>From 2065bdfa84d2b08010f98dedc569b095cf7a728d Mon Sep 17 00:00:00 2001 From: nixo Date: Tue, 24 Nov 2020 16:23:06 +0100 Subject: [PATCH 08/20] gnu: Add dart-2.0.0-dev.8.0. * gnu/packages/dart.scm (dart-2.0.0-dev.8.0): New variable. * gnu/packages/patches (dart-2.0.0-dev.8-disable-analytics.patch): New file. * gnu/local.mk: Add it. --- gnu/local.mk | 1 + gnu/packages/dart.scm | 419 +- .../dart-2.0.0-dev.8-disable-analytics.patch | 192411 +++++++++++++++ 3 files changed, 192810 insertions(+), 21 deletions(-) create mode 100644 gnu/packages/patches/dart-2.0.0-dev.8-disable-analytics.patch diff --git a/gnu/local.mk b/gnu/local.mk index 359015415c..ee4ade0139 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -905,6 +905,7 @@ dist_patch_DATA = \ %D%/packages/patches/cursynth-wave-rand.patch \ %D%/packages/patches/cvs-CVE-2017-12836.patch \ %D%/packages/patches/cyrus-sasl-ac-try-run-fix.patch \ + %D%/packages/patches/dart-2.0.0-dev.8-disable-analytics.patch \ %D%/packages/patches/date-output-pkg-config-files.patch \ %D%/packages/patches/datefudge-gettimeofday.patch \ %D%/packages/patches/dbacl-include-locale.h.patch \ diff --git a/gnu/packages/dart.scm b/gnu/packages/dart.scm index 53c108f1f0..4918f56d2c 100644 --- a/gnu/packages/dart.scm +++ b/gnu/packages/dart.scm @@ -18,20 +18,30 @@ (define-module (gnu packages dart) #:use-module ((guix licenses) #:prefix license:) - #:use-module (guix build utils) + #:use-module (guix build-system gnu) #:use-module (guix git-download) #:use-module (guix packages) - #:use-module (guix utils)) + #:use-module (guix utils) + #:use-module (gnu packages) + #:use-module (gnu packages build-tools) + #:use-module (gnu packages gcc) + #:use-module (gnu packages golang) + #:use-module (gnu packages libunwind) + #:use-module (gnu packages ninja) + #:use-module (gnu packages nss) + #:use-module (gnu packages perl) + #:use-module (gnu packages python) + #:use-module (gnu packages python-xyz)) (define (dart-pkg name tag hash) (origin (method git-fetch) (uri (git-reference - (url (string-append - "https://github.com/dart-lang/" - (string-replace-substring name "-" "_") - ".git")) - (commit tag))) + (url (string-append + "https://github.com/dart-lang/" + (string-replace-substring name "-" "_") + ".git")) + (commit tag))) (file-name (git-file-name name (if (> (string-length tag) 9) @@ -41,50 +51,417 @@ (define dart-zlib (let ((version "c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f") - (hash "0fr3h9krramy0jclbacjnwbn0lzvjm6b809llhaz56mbd90i4yl4")) + (hash "0fr3h9krramy0jclbacjnwbn0lzvjm6b809llhaz56mbd90i4yl4")) (origin (method git-fetch) (uri (git-reference - (url "https://chromium.googlesource.com/chromium/src/third_party/zlib.git") - (commit version))) + (url "https://chromium.googlesource.com/chromium/src/third_party/zlib.git") + (commit version))) (sha256 (base32 hash))))) (define dart-boringssl (let ((version "d519bf6be0b447fb80fbc539d4bff4479b5482a2") - (hash "137q647ha8x770wv3jj2kgjv3lj9qjcv191m51vkp3a7zqhhaknv")) + (hash "137q647ha8x770wv3jj2kgjv3lj9qjcv191m51vkp3a7zqhhaknv")) (origin (method git-fetch) (uri (git-reference - (url "https://boringssl.googlesource.com/boringssl") - (commit version))) + (url "https://boringssl.googlesource.com/boringssl") + (commit version))) (sha256 (base32 hash))))) (define boringssl-gen (let ((version "d2b56d1b7657e52eb5a1f075968c773aa3e53614") - (hash "1pn2hn0i9fwd27i695q4av3bymm11pmydlbv4hcafslhggq0md19")) + (hash "1pn2hn0i9fwd27i695q4av3bymm11pmydlbv4hcafslhggq0md19")) (origin (method git-fetch) (uri (git-reference - (url "https://github.com/dart-lang/boringssl_gen") - (commit version))) + (url "https://github.com/dart-lang/boringssl_gen") + (commit version))) (sha256 (base32 hash))))) ;; TODO: should I take the src from the real gperftools and override the version? (define dart-gperftools (let ((version "02eeed29df112728564a5dde6417fa4622b57a06") - (hash "1j5yx7v1g8ljzv5hs2452q736gdf1xm5x9w5d1csm5bjlryxaykm")) + (hash "1j5yx7v1g8ljzv5hs2452q736gdf1xm5x9w5d1csm5bjlryxaykm")) (origin (method git-fetch) (uri (git-reference - (url "https://github.com/gperftools/gperftools.git") - (commit version))) + (url "https://github.com/gperftools/gperftools.git") + (commit version))) (sha256 (base32 hash))))) (define (root-certificates version hash) (origin (method git-fetch) (uri (git-reference - (url "https://github.com/dart-lang/root_certificates.git") - (commit version))) + (url "https://github.com/dart-lang/root_certificates.git") + (commit version))) (sha256 (base32 hash)))) +(define-public dart-2.0.0-dev.8.0 + (package + (name "dart") + (version "2.0.0-dev.8.0") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/dart-lang/sdk.git") + (commit version))) + (file-name (string-append name "-" version)) + (sha256 + (base32 + "17870yvi4flcraw3ihs694g4r0fmmmj2qmz9n4r311pizxzagjkk")) + (modules '((guix build utils))) + ;; Delete a folder containing a pre-build windows .dll + (snippet + '(delete-file-recursively "build/win")) + (patches + (search-patches "dart-2.0.0-dev.8-disable-analytics.patch")))) + (arguments + `(#:configure-flags + ;; FIXME: Do not hardcode the target? Don't know if when fixed this + ;; package will work on other targets + (list "host_cpu=\"x64\"" + "target_cpu=\"x64\"" + "dart_target_arch=\"x64\"" + "target_os=\"linux\"" + "dart_runtime_mode=\"develop\"" + "dart_debug=false" + "is_debug=false" + "is_release=true" + "is_product=false" + "is_clang=false" + "use_goma=false" + "goma_dir=\"None\"" + "dart_use_tcmalloc=true" + "dart_use_fallback_root_certificates=true" + "dart_zlib_path = \"//runtime/bin/zlib\"" + "dart_platform_sdk=false" + "is_asan=false" + "is_msan=false" + "is_tsan=false" + "dart_snapshot_kind=\"app-jit\"") + #:phases + (modify-phases %standard-phases + ;; no check target. Tests are available, but I should check how to + ;; run them + (delete 'check) + (add-before 'configure 'add-git-revision + (lambda _ + (with-output-to-file "tools/GIT_REVISION" + (lambda () (display "0"))))) + (add-before 'configure 'add-third-party-src + ;; Copy some deps to third_party, as required by the build system + ;; TODO: LINK THEM INSTEAD OF COPYING + (lambda* (#:key inputs #:allow-other-keys) + (use-modules (ice-9 regex) (ice-9 match)) + ;; place pkg inputs in the right third_party folder + ;; (either pkg or pkgtested) based on their input name + (define (dart-copy-deps-to-third-party-dir pkgdep) + (copy-recursively + (assoc-ref inputs pkgdep) + (let* ((out "third_party/") + (text + (if (string-match "pkgtested" pkgdep) + (string-append out "pkg_tested/" + (regexp-substitute + #f + (string-match "dart-pkgtested-" pkgdep) + 'post)) + (string-append out "pkg/" + (regexp-substitute + #f + (string-match "dart-pkg-" pkgdep) + 'post))))) + (if (string-match "-" text) + (regexp-substitute/global + #f "-" text 'pre "_" 'post) + text)))) + (map (lambda (input) + (let ((pkg (car input))) + ;; Copy only dependencies starting with "dart-" + (when (string-match "dart-" pkg) + (dart-copy-deps-to-third-party-dir pkg)))) + inputs) + ;; Do the same for other required packages + (copy-recursively (assoc-ref inputs "boringssl") + "third_party/boringssl/src") + (copy-recursively (assoc-ref inputs "gperftools") + "third_party/tcmalloc/gperftools") + (copy-recursively (assoc-ref inputs "root-certificates") + "third_party/root_certificates") + (copy-recursively (assoc-ref inputs "zlib") + "third_party/zlib") + (copy-recursively (assoc-ref inputs "observatory-pub-packages") + "third_party/observatory_pub_packages"))) + (add-after 'add-third-party-src 'generate-third-party-build-files + (lambda* (#:key inputs #:allow-other-keys) + (with-directory-excursion "third_party/boringssl" + ;; go requires home to be set + (setenv "HOME" "/tmp/") + (invoke (string-append (assoc-ref inputs "python") "/bin/python2") + "src/util/generate_build_files.py" "gn") + (map (lambda (file) + (copy-file + (string-append (assoc-ref inputs "boringssl-gen") "/" file) + file)) + '("BUILD.gn" "BUILD.generated.gni"))))) + (add-before 'configure 'enable-dtags + ;; adds the RUNPATH + (lambda* (#:key inputs propagated-inputs #:allow-other-keys) + (substitute* "build/config/gcc/BUILD.gn" + (("disable-new-dtags") "enable-new-dtags")))) + (replace 'configure + (lambda* (#:key configure-flags #:allow-other-keys) + (let ((args (string-join configure-flags " "))) + (mkdir "out") + ;; Generate ninja build files. + (invoke "gn" "gen" "out/Release" + (string-append "--args=" args)) + ;; Print the full list of supported arguments as well as + ;; their current status for convenience. + (format #t "Dumping configure flags...\n") + (invoke "gn" "args" "out/Release" "--list")))) + (replace 'build + (lambda* (#:key configure-flags #:allow-other-keys) + (invoke "ninja" "all" "-C" "out/Release"))) + ;; no install phase + (replace 'install + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + ;; This should depend on the architecture as before + (copy-recursively "out/Release/dart-sdk/" out))))))) + (inputs + `(("zlib" ,dart-zlib) + ("libunwind" ,libunwind) + ("nspr" ,nspr) + ("nss" ,nss) + ("boringssl" ,dart-boringssl) + ("boringssl-gen" ,boringssl-gen) + ("gperftools" ,dart-gperftools) + ("root-certificates" + ,(root-certificates + "16ef64be64c7dfdff2b9f4b910726e635ccc519e" + "1kxadamhz03dlvm3j5xxqjgn0jasgskyjx11ysm3a431ma5j9182")) + ("observatory-pub-packages" + ,(dart-pkg "observatory-pub-packages" "4c282bb240b68f407c8c7779a65c68eeb0139dc6" + "0p09r24q37i4hyz3n2j75lx9a252zr81jcynap61nfh415xlcv3z")) + ("dart-pkg-args" + ,(dart-pkg "args" "0.13.7" + "0y3f1kaplxmanw5gqm84l9wqx2nl1vrk11m8kdqqwc7n73fc4kdl")) + ("dart-pkg-async" + ,(dart-pkg "async" "2.0.0" + "1r0fqdh633426p2h9ynb126s58l30jj3mj0bzvjigbklam7vfjgc")) + ("dart-pkg-barback" + ,(dart-pkg "barback" "0.15.2+13" + "0n532b2as62nkzq7w9jaxk6gkl78il1kq3q0s1xgcdazmbzx5fb1")) + ("dart-pkg-bazel-worker" + ,(dart-pkg "bazel-worker" "v0.1.4" + "1cc4jvx9qba76ws2l7ijr8kvl8yydfak965gwrgb88f2r1qp2q46")) + ("dart-pkg-charcode" + ,(dart-pkg "charcode" "v1.1.1" + "0907828insqsr0ffyz4n2xns4qc77brnm7zv0a6965b53b84pk8b")) + ("dart-pkg-cli-util" + ,(dart-pkg "cli-util" "0.1.2+1" + "09nqdkyipnb0734ci554gxrl9cic528mlhfad9wibcg6kx7y6gra")) + ("dart-pkg-collection" + ,(dart-pkg "collection" "1.14.3" + "1rdgvrj67vj27k2052h5k31xc6rays4p4j27a122c1ikxnb4i3bh")) + ("dart-pkg-convert" + ,(dart-pkg "convert" "2.0.1" + "1v0b6vgzp6i37jja2d2aim6dmig8xfjhi8b553a1909n5pzqxp2g")) + ("dart-pkg-crypto" + ,(dart-pkg "crypto" "2.0.2+1" + "12v5rw189vrk2n2ryxkf8qcbdx8hf3bf33i552439lzhz0czkvcq")) + ("dart-pkg-csslib" + ,(dart-pkg "csslib" "0.14.1" + "0zlmbg6vwwc4cha8l2xv73klwzdqg6b43qmhlca0f62lr7k6014w")) + ("dart-pkg-dart2js-info" + ,(dart-pkg "dart2js_info" "0.5.5+1" + "05rdp96n9rxkjyw7lmn3a9hlbsaxpdn8wp8qnsfjmqv3i8vcypvj")) + ("dart-pkg-dartdoc" + ,(dart-pkg "dartdoc" "v0.13.0+3" + "1v85510bvjhllr00hgabvn737bh791x1m14qsv7zbxhqnsy2jafj")) + ("dart-pkg-fixnum" + ,(dart-pkg "fixnum" "0.10.5" + "01j7sj4mnkaxam1bpmhvlxl817dcck92xzpk66m7qbccm58c0giw")) + ("dart-pkg-func" + ,(dart-pkg "func" "25eec48146a58967d75330075ab376b3838b18a8" + "0xcfnca5sa5hc62g14xx11qqv9xjamsaqqn1cmldb917qnxb7lkk")) + ("dart-pkg-glob" + ,(dart-pkg "glob" "1.1.5" + "1lbd7lkxvw0q5zvz2hxvc035mxakmzcq08lwwr25v56s9ybavh93")) + ("dart-pkg-html" + ,(dart-pkg "html" "0.13.2" + "0w0gn8camhqhclmlf5g1mp03nssl2gyghqkmcz0zrvkicc1d5r1s")) + ("dart-pkg-http" + ,(dart-pkg "http" "0.11.3+14" + "1a1k8m2gp8a02q9bw40bqj7ad9yx44ap0w4xr7s26lridi7isylc")) + ("dart-pkg-http-multi-server" + ,(dart-pkg "http_multi_server" "2.0.4" + "09x4alr181p6s3zxqflgmhglglxr4aaaz6ys7pp0r715dq50qz4n")) + ("dart-pkg-http-parser" + ,(dart-pkg "http-parser" "3.1.1" + "18p8cqanxbxsxk3wwvisgb1bxdy83vkh3l11h0cys7gxrz6z2g12")) + ("dart-pkg-http-throttle" + ,(dart-pkg "http-throttle" "1.0.1" + "1q0pv1px5rd7zjd799pnq5zcr825ya1yqnxyvdr91rlga621hdbj")) + ("dart-pkg-intl" + ,(dart-pkg "intl" "0.15.2" + "0vd0a3pqmfs03kf12mmg0rrpian0f35ja0x332mr7cx8h9d7pmqx")) + ("dart-pkg-isolate" + ,(dart-pkg "isolate" "1.1.0" + "12m97zhm8qwpraf6nyvj1nawssygrwz0zka7843ayj3vxx6j34xr")) + ("dart-pkg-json-rpc-2" + ,(dart-pkg "json_rpc_2" "2.0.4" + "1q2x6gy7l7agr930k4r6vncfzjcnp43chq9fwxfa0p0nyccnixz3")) + ("dart-pkg-linter" + ,(dart-pkg "linter" "0.1.39" + "0wfd6bzfny5bis3r2ygj89kyd2gl618x7hk06qp4h9nvbpsvvz0n")) + ("dart-pkg-logging" + ,(dart-pkg "logging" "0.11.3+1" + "180w376jz2wmfijcfg07ygfpc6i68i4zibw2421xvwcjhi0q07kv")) + ("dart-pkg-markdown" + ,(dart-pkg "markdown" "0.11.4" + "009qw47k3lrl2fkdn378l41dga493alspywrk3z93yy1pqaf1j5n")) + ("dart-pkg-matcher" + ,(dart-pkg "matcher" "0.12.1+4" + "1q0hbcc5ys5zpml7blsyj0d1f42w67vr6x19vxg34sra3bv0h2xx")) + ("dart-pkg-mime" + ,(dart-pkg "mime" "0.9.4" + "1bh4xla0qlaz9cm1qgxqq57l76b2zh5qqk9pax7sc57s79zi1nmz")) + ("dart-pkg-mockito" + ,(dart-pkg "mockito" "2.0.2" + "1q1zlv3fwfjbmwm141wj19vglx15s8xkqzdsqz9hhv6gg7h45gsl")) + ("dart-pkg-mustache4dart" + ,(origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/valotas/mustache4dart.git") + (commit "v2.1.0"))) + (sha256 (base32 "0wsmg2xvpp2h9rqcg65icymh2s9hifq6v700mni65ky33dah9ji1")))) + ("dart-pkg-oauth2" + ,(dart-pkg "oauth2" "1.1.0" + "1519799j61sdka6p1n6ba768v5a8q4q9w6y957dzqigwaf19p9v5")) + ("dart-pkg-path" + ,(dart-pkg "path" "1.4.2" + "0ld39rpzla8wd4c2kx1kycdk66cwypklxki58nb18959j2749fbi")) + ("dart-pkg-plugin" + ,(dart-pkg "plugin" "0.2.0" + "10sgglzpwr9hkdhr6r4d1kvazv49zdhc9cr2asxdk5531347kk9m")) + ("dart-pkg-pool" + ,(dart-pkg "pool" "1.3.3" + "1cljnzsrbjgkif8rj1vxrzp5rz2xak265pasachdcg4yh2hl0y7d")) + ("dart-pkg-protobuf" + ,(dart-pkg "protobuf" "0.5.4" + "1wjb8da0da0gda0f83dl2dvl5w4a6gvq5xcg1yrgg3xjs7gzy8dd")) + ("dart-pkg-pub" + ,(dart-pkg "pub" "cde958f157d3662bf968bcbed05580d5c0355e89" + "1g1cw4c0811l3pvc80fvb7s04shzxvxrcb25195s7kjjfiivgqi4")) + ("dart-pkg-pub-semver" + ,(dart-pkg "pub-semver" "1.3.2" + "15s6zn2qyyfc5lf8ip5h8j3sq5miz4vrzxbgbwi5vv91d53miia8")) + ("dart-pkg-quiver" + ,(origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/google/quiver-dart.git") + (commit "0.25.0"))) + (sha256 (base32 "02wqrk266s0ias9lfy7l5dh9ni2r697n3z42h4sgzxy7qg4rip24")))) + ("dart-pkg-resource" + ,(dart-pkg "resource" "af5a5bf65511943398146cf146e466e5f0b95cb9" + "1jq4bmg65jrpyqxcvbp87d5qqpgmv5ylfz3w1djzimq5jhr9k4vn")) + ("dart-pkg-scheduled-test" + ,(dart-pkg "scheduled-test" "0.12.11+1" + "1xk66f68m443yig5672p0dpack2c0kpkyk2d7f8iaq22q5zq7h1w")) + ("dart-pkg-shelf" + ,(dart-pkg "shelf" "0.6.8" + "0vl4m47yhjvc1nynyzc42bks4mzv877vsy7fbcv9w2fjh05sxhb9")) + ("dart-pkg-shelf-packages-handler" + ,(dart-pkg "shelf-packages-handler" "1.0.3" + "0iccfa713jyg7bb7fx144i5rl0afyfxvb3pi56igw2gdwklq4yck")) + ("dart-pkg-shelf-static" + ,(dart-pkg "shelf-static" "0.2.4" + "1gfyjqvv13d3zpnaahv5fi601ag7mr8crm94xawlvgvpqgpl0hsh")) + ("dart-pkg-shelf-web-socket" + ,(dart-pkg "shelf-web-socket" "0.2.1" + "18krh9bnbshwjjl47k15x9g3r7s5k0yichvn3gdsddjqjgp6vfp8")) + ("dart-pkg-source-map-stack-trace" + ,(dart-pkg "source-map-stack-trace" "1.1.4" + "1cpyq1vdfc623k8cdx673v2kkv112hzsrsyaxd8dd82v23caglva")) + ("dart-pkg-source-maps" + ,(dart-pkg "source-maps" "0.10.4" + "11dmncxgv8q40am73dxlxgzkfaanvgc9p3lds77m96mb1k27zbkf")) + ("dart-pkg-source-span" + ,(dart-pkg "source-span" "1.4.0" + "0gpa15p5rcilgl0paqa7f9fkiks7kyalzl2r0sd37m4cry9cf0vz")) + ("dart-pkg-stack-trace" + ,(dart-pkg "stack-trace" "1.8.2" + "0n21n2dv371bfcw6q83xwb8x26d1rd49cvx5qzm8mi0006h9frzs")) + ("dart-pkg-stream-channel" + ,(dart-pkg "stream-channel" "1.6.2" + "02ixi6vsja2cc22jcflp89v5wsbj45fl23p0sgaayqaj6l1jcxm1")) + ("dart-pkg-string-scanner" + ,(dart-pkg "string-scanner" "1.0.2" + "13hfnc704c9qipcvjinbv1hbq57hs5l2f68kyw282dlrcbbwwksy")) + ("dart-pkg-term-glyph" + ,(dart-pkg "term-glyph" "1.0.0" + "1nxqg345k2zh0yn498mxxdi7v1q3651z5invv0llfvs17ly2h2pz")) + ("dart-pkg-test" + ,(dart-pkg "test" "0.12.24+6" + "1xkmvwx30zm5ci1gn53hf6zrxymlq9cn9waa00k3ihxbd64mxg1k")) + ("dart-pkg-test-reflective-loader" + ,(dart-pkg "test-reflective-loader" "0.1.0" + "1qmbayg6js96lcy9s6grly1y6rh9x5mbyqygnr58zsdypzvhr4hr")) + ("dart-pkg-tuple" + ,(dart-pkg "tuple" "v1.0.1" + "0khkwq1blc90lgdcy4i8ng4nzppmhg31nziw4sc36axwbwdnpc86")) + ("dart-pkg-typed-data" + ,(dart-pkg "typed-data" "1.1.3" + "1zr9la34lib0rdfdf0539hdai2j71kf3s4ynsal7hw4pqvkdwi72")) + ("dart-pkg-unittest" + ,(dart-pkg "test" "0.11.7" + "1xbx2i2glmqlc3cz8x91anhf8d4hsr3bq9j53qliawz8j6q9anf8")) + ("dart-pkg-usage" + ,(dart-pkg "usage" "3.3.0" + "0r8d0q4ij42c7axclwns61cyrxpmk1qpggqfiqfm5vbmh8gpfm3b")) + ("dart-pkg-utf" + ,(dart-pkg "utf" "0.9.0+3" + "07jppjvg8bc8plzq910b8ld32l6x35i8qwy0mdqimydjjaslj78f")) + ("dart-pkg-watcher" + ,(dart-pkg "watcher" "0.9.7+4" + "09jpk98qb5j5250sr9r9ic17gj741yjy1p2j50zzl47a9wydfjly")) + ("dart-pkg-web-socket-channel" + ,(dart-pkg "web-socket-channel" "1.0.6" + "1phb2n3n6npzwl08nnp1aggcjmvwx516b816q4hsx8w190yr4f86")) + ("dart-pkg-yaml" + ,(dart-pkg "yaml" "2.1.12" + "0m2xr36vd2v3yirv1jb5v3dncsczn8n34s9fmqcm2ld979b4vanm")) + ("dart-pkgtested-dart-style" + ,(dart-pkg "dart-style" "1.0.7" + "0qym7z5n4w4jy75fnvcyza3hw0nrm8kli5mv65drr16f8pkr0lcg")) + ("dart-pkgtested-package-config" + ,(dart-pkg "package-config" "1.0.3" + "03w67nb1dhi2yqb63z1301p88hjws1d8azmw8m5ap4zapqdbhzgn")) + ("dart-pkgtested-package-resolver" + ,(dart-pkg "package-resolver" "1.0.2+1" + "0qs7zmxjwqqjkq6mqnz8b3rj142hyz1x0v1innh8n3bwmljgp3w9")))) + (native-inputs + `(("python" ,python-2) + ("python2-gyp" ,python2-gyp) + ("perl" ,perl) + ("go" ,go) + ("gn" ,gn-for-dart-bootstrap) + ("ninja" ,ninja) + ("gcc" ,gcc-6))) + (build-system gnu-build-system) + (home-page "https://dart.dev") + (synopsis "The Dart SDK, including the VM, dart2js and core libraries") + (description "Dart is a programming language which is: +@enumerate +@item Optimized for UI +@item Supports hot reload +@item Supported both on desktop and on mobile +@end") + (license license:bsd-3))) diff --git a/gnu/packages/patches/dart-2.0.0-dev.8-disable-analytics.patch b/gnu/packages/patches/dart-2.0.0-dev.8-disable-analytics.patch new file mode 100644 index 0000000000..763e5503ea --- /dev/null +++ b/gnu/packages/patches/dart-2.0.0-dev.8-disable-analytics.patch @@ -0,0 +1,192411 @@ +From f9843f7af84da47141a2721972c7859cdddfa36f Mon Sep 17 00:00:00 2001 +From: nixo +Date: Tue, 24 Nov 2020 16:59:00 +0100 +Subject: [PATCH] disable analytics + +--- + BUILD.gn | 7 - + pkg/analysis_server/AUTHORS | 6 - + pkg/analysis_server/CHANGELOG.md | 5 - + pkg/analysis_server/CONTRIBUTING.md | 40 - + pkg/analysis_server/LICENSE | 26 - + pkg/analysis_server/README.md | 22 - + pkg/analysis_server/analysis_options.yaml | 8 - + pkg/analysis_server/benchmark/benchmarks.dart | 239 - + .../benchmark/integration/README.md | 69 - + .../benchmark/integration/driver.dart | 315 - + .../integration/input_converter.dart | 399 - + .../instrumentation_input_converter.dart | 146 - + .../benchmark/integration/local_runner.dart | 91 - + .../integration/log_file_input_converter.dart | 82 - + .../benchmark/integration/main.dart | 246 - + .../benchmark/integration/operation.dart | 236 - + .../benchmark/perf/analysis_timing_tests.dart | 161 - + .../benchmark/perf/benchmark_angular.dart | 115 - + .../benchmark/perf/benchmark_flutter.dart | 216 - + .../benchmark/perf/benchmark_scenario.dart | 310 - + .../benchmark/perf/benchmarks_impl.dart | 187 - + .../perf/completion_timing_tests.dart | 85 - + .../benchmark/perf/memory_tests.dart | 133 - + .../benchmark/perf/performance_tests.dart | 76 - + pkg/analysis_server/benchmark/readme.md | 35 - + pkg/analysis_server/bin/server.dart | 13 - + pkg/analysis_server/doc/api.html | 4725 ----- + .../occurrences/occurrences_core.dart | 17 - + .../lib/plugin/edit/assist/assist_core.dart | 90 - + .../lib/plugin/edit/assist/assist_dart.dart | 107 - + .../lib/plugin/edit/fix/fix_core.dart | 88 - + .../lib/plugin/edit/fix/fix_dart.dart | 73 - + .../lib/plugin/protocol/protocol_dart.dart | 216 - + .../lib/protocol/protocol.dart | 673 - + .../lib/protocol/protocol_constants.dart | 258 - + .../lib/protocol/protocol_generated.dart | 15802 ---------------- + .../lib/src/analysis_logger.dart | 55 - + .../lib/src/analysis_server.dart | 1557 -- + .../lib/src/channel/byte_stream_channel.dart | 175 - + .../lib/src/channel/channel.dart | 150 - + pkg/analysis_server/lib/src/collections.dart | 71 - + .../src/computer/computer_closingLabels.dart | 105 - + .../lib/src/computer/computer_highlights.dart | 737 - + .../src/computer/computer_highlights2.dart | 834 - + .../lib/src/computer/computer_hover.dart | 140 - + .../lib/src/computer/computer_outline.dart | 488 - + .../lib/src/computer/computer_overrides.dart | 237 - + .../computer/import_elements_computer.dart | 433 - + .../computer/imported_elements_computer.dart | 129 - + .../lib/src/computer/new_notifications.dart | 45 - + pkg/analysis_server/lib/src/constants.dart | 100 - + .../lib/src/context_manager.dart | 1817 -- + .../lib/src/domain_abstract.dart | 78 - + .../lib/src/domain_analysis.dart | 432 - + .../lib/src/domain_analytics.dart | 60 - + .../lib/src/domain_completion.dart | 298 - + .../lib/src/domain_diagnostic.dart | 75 - + .../lib/src/domain_execution.dart | 147 - + pkg/analysis_server/lib/src/domain_kythe.dart | 114 - + .../lib/src/domain_server.dart | 74 - + .../domains/analysis/implemented_dart.dart | 79 - + .../src/domains/analysis/navigation_dart.dart | 360 - + .../lib/src/domains/analysis/occurrences.dart | 33 - + .../domains/analysis/occurrences_dart.dart | 63 - + .../lib/src/edit/edit_domain.dart | 1062 -- + .../lib/src/operation/operation_analysis.dart | 164 - + .../lib/src/plugin/notification_manager.dart | 365 - + .../lib/src/plugin/plugin_locator.dart | 105 - + .../lib/src/plugin/plugin_manager.dart | 1102 -- + .../lib/src/plugin/plugin_watcher.dart | 134 - + .../lib/src/plugin/request_converter.dart | 46 - + .../lib/src/plugin/result_collector.dart | 124 - + .../lib/src/plugin/result_converter.dart | 46 - + .../lib/src/plugin/result_merger.dart | 846 - + .../lib/src/protocol/protocol_internal.dart | 336 - + .../lib/src/protocol_server.dart | 283 - + .../completion/completion_core.dart | 86 - + .../completion/dart/completion_dart.dart | 97 - + .../lib/src/search/element_references.dart | 93 - + .../lib/src/search/search_domain.dart | 211 - + .../lib/src/search/type_hierarchy.dart | 202 - + .../lib/src/server/diagnostic_server.dart | 16 - + .../lib/src/server/driver.dart | 640 - + .../lib/src/server/http_server.dart | 169 - + .../lib/src/server/stdio_server.dart | 40 - + .../services/completion/completion_core.dart | 75 - + .../completion/completion_performance.dart | 117 - + .../completion/dart/arglist_contributor.dart | 340 - + .../dart/combinator_contributor.dart | 41 - + .../completion/dart/common_usage_sorter.dart | 127 - + .../dart/common_usage_sorter.g.dart | 427 - + .../completion/dart/completion_manager.dart | 278 - + .../completion/dart/contribution_sorter.dart | 24 - + .../dart/field_formal_contributor.dart | 78 - + .../dart/imported_reference_contributor.dart | 86 - + .../dart/inherited_reference_contributor.dart | 134 - + .../completion/dart/keyword_contributor.dart | 706 - + .../completion/dart/label_contributor.dart | 156 - + .../dart/library_member_contributor.dart | 73 - + .../dart/library_prefix_contributor.dart | 48 - + .../dart/local_constructor_contributor.dart | 161 - + .../dart/local_library_contributor.dart | 197 - + .../dart/local_reference_contributor.dart | 517 - + .../dart/named_constructor_contributor.dart | 61 - + .../completion/dart/override_contributor.dart | 150 - + .../dart/static_member_contributor.dart | 131 - + .../completion/dart/suggestion_builder.dart | 302 - + .../dart/type_member_contributor.dart | 411 - + .../completion/dart/uri_contributor.dart | 242 - + .../services/completion/dart/utilities.dart | 237 - + .../dart/variable_name_contributor.dart | 99 - + .../postfix/postfix_completion.dart | 567 - + .../completion/statement/design_notes.md | 144 - + .../statement/statement_completion.dart | 1237 -- + .../lib/src/services/correction/assist.dart | 126 - + .../services/correction/assist_internal.dart | 2617 --- + .../lib/src/services/correction/fix.dart | 260 - + .../src/services/correction/fix_internal.dart | 3284 ---- + .../src/services/correction/levenshtein.dart | 133 - + .../services/correction/name_suggestion.dart | 238 - + .../src/services/correction/namespace.dart | 183 - + .../correction/organize_directives.dart | 250 - + .../correction/selection_analyzer.dart | 142 - + .../src/services/correction/sort_members.dart | 504 - + .../services/correction/source_buffer.dart | 99 - + .../correction/statement_analyzer.dart | 230 - + .../lib/src/services/correction/status.dart | 179 - + .../lib/src/services/correction/strings.dart | 263 - + .../lib/src/services/correction/util.dart | 1530 -- + .../src/services/kythe/kythe_visitors.dart | 1407 -- + .../lib/src/services/kythe/schema.dart | 82 - + .../refactoring/convert_getter_to_method.dart | 127 - + .../refactoring/convert_method_to_getter.dart | 143 - + .../services/refactoring/extract_local.dart | 699 - + .../services/refactoring/extract_method.dart | 1350 -- + .../services/refactoring/inline_local.dart | 213 - + .../services/refactoring/inline_method.dart | 880 - + .../refactoring/naming_conventions.dart | 263 - + .../src/services/refactoring/refactoring.dart | 444 - + .../refactoring/refactoring_internal.dart | 116 - + .../lib/src/services/refactoring/rename.dart | 148 - + .../refactoring/rename_class_member.dart | 345 - + .../refactoring/rename_constructor.dart | 131 - + .../services/refactoring/rename_import.dart | 137 - + .../services/refactoring/rename_label.dart | 45 - + .../services/refactoring/rename_library.dart | 48 - + .../services/refactoring/rename_local.dart | 171 - + .../refactoring/rename_unit_member.dart | 263 - + .../src/services/search/element_visitors.dart | 63 - + .../lib/src/services/search/hierarchy.dart | 162 - + .../src/services/search/search_engine.dart | 171 - + .../search/search_engine_internal.dart | 238 - + .../lib/src/socket_server.dart | 90 - + .../lib/src/status/ast_writer.dart | 243 - + .../lib/src/status/diagnostics.dart | 1229 -- + .../lib/src/status/element_writer.dart | 179 - + pkg/analysis_server/lib/src/status/pages.dart | 189 - + .../lib/src/status/tree_writer.dart | 123 - + .../lib/src/utilities/documentation.dart | 67 - + .../lib/src/utilities/flutter.dart | 267 - + .../lib/src/utilities/null_string_sink.dart | 13 - + .../lib/src/utilities/profiling.dart | 89 - + .../lib/src/watch_manager.dart | 285 - + pkg/analysis_server/lib/starter.dart | 49 - + pkg/analysis_server/pubspec.yaml | 27 - + .../test/abstract_context.dart | 172 - + .../test/abstract_single_unit.dart | 144 - + .../test/analysis/get_errors_test.dart | 150 - + .../test/analysis/get_hover_test.dart | 562 - + .../test/analysis/get_navigation_test.dart | 250 - + .../notification_analysis_options_test.dart | 334 - + .../notification_analyzedFiles_test.dart | 133 - + .../notification_closingLabels_test.dart | 101 - + .../analysis/notification_errors_test.dart | 146 - + .../notification_highlights_test.dart | 960 - + .../notification_highlights_test2.dart | 1111 -- + .../notification_implemented_test.dart | 431 - + .../notification_navigation_test.dart | 1031 - + .../notification_occurrences_test.dart | 257 - + .../analysis/notification_outline_test.dart | 135 - + .../analysis/notification_overrides_test.dart | 577 - + .../test/analysis/reanalyze_test.dart | 75 - + .../analysis/set_priority_files_test.dart | 131 - + .../test/analysis/test_all.dart | 51 - + .../test/analysis/update_content_test.dart | 266 - + .../test/analysis_abstract.dart | 367 - + .../test/analysis_server_test.dart | 210 - + pkg/analysis_server/test/benchmarks_test.dart | 76 - + .../channel/byte_stream_channel_test.dart | 272 - + .../test/channel/test_all.dart | 16 - + pkg/analysis_server/test/completion_test.dart | 2517 --- + .../test/completion_test_support.dart | 203 - + .../test/context_manager_test.dart | 2695 --- + .../test/domain_analysis_test.dart | 790 - + .../test/domain_completion_test.dart | 780 - + .../test/domain_completion_util.dart | 123 - + .../test/domain_diagnostic_test.dart | 58 - + .../test/domain_execution_test.dart | 243 - + .../test/domain_server_test.dart | 81 - + .../test/edit/assists_test.dart | 134 - + pkg/analysis_server/test/edit/fixes_test.dart | 164 - + .../test/edit/format_test.dart | 125 - + .../test/edit/organize_directives_test.dart | 167 - + .../test/edit/postfix_completion_test.dart | 93 - + .../test/edit/refactoring_test.dart | 2016 -- + .../test/edit/sort_members_test.dart | 256 - + .../test/edit/statement_completion_test.dart | 122 - + pkg/analysis_server/test/edit/test_all.dart | 27 - + .../analysis/analysis_options_test.dart | 81 - + .../test/integration/analysis/error_test.dart | 100 - + .../analysis/get_errors_nonStandard_sdk.dart | 99 - + .../integration/analysis/get_errors_test.dart | 36 - + .../integration/analysis/get_hover_test.dart | 189 - + .../analysis/get_imported_elements_test.dart | 135 - + .../get_library_dependencies_test.dart | 47 - + .../analysis/get_navigation_test.dart | 67 - + .../analysis/get_reachable_sources_test.dart | 49 - + .../integration/analysis/highlights_test.dart | 146 - + .../analysis/highlights_test2.dart | 166 - + .../test/integration/analysis/lint_test.dart | 83 - + .../integration/analysis/navigation_test.dart | 136 - + .../analysis/occurrences_test.dart | 68 - + .../integration/analysis/outline_test.dart | 84 - + .../integration/analysis/overrides_test.dart | 122 - + .../analysis/package_root_test.dart | 79 - + .../analysis/reanalyze_concurrent_test.dart | 49 - + .../integration/analysis/reanalyze_test.dart | 40 - + .../analysis/set_analysis_roots_test.dart | 32 - + .../set_general_subscriptions_test.dart | 40 - + .../analysis/set_priority_files_test.dart | 30 - + .../analysis/set_subscriptions_test.dart | 32 - + .../test/integration/analysis/test_all.dart | 66 - + .../analysis/update_content_list_test.dart | 52 - + .../analysis/update_content_test.dart | 107 - + .../analysis/update_options_test.dart | 47 - + .../integration/analytics/enable_test.dart | 33 - + .../analytics/is_enabled_test.dart | 26 - + .../analytics/send_event_test.dart | 31 - + .../analytics/send_timing_test.dart | 31 - + .../test/integration/analytics/test_all.dart | 19 - + .../completion/get_suggestions_test.dart | 118 - + .../test/integration/completion/test_all.dart | 16 - + .../test/integration/coverage.md | 83 - + .../test/integration/coverage_test.dart | 129 - + .../diagnostic/get_diagnostics_test.dart | 30 - + .../diagnostic/get_server_port_test.dart | 37 - + .../test/integration/diagnostic/test_all.dart | 15 - + .../test/integration/edit/format_test.dart | 80 - + .../integration/edit/get_assists_test.dart | 50 - + .../edit/get_available_refactorings_test.dart | 37 - + .../test/integration/edit/get_fixes_test.dart | 60 - + .../edit/get_postfix_completion_test.dart | 52 - + .../edit/get_refactoring_test.dart | 66 - + .../edit/get_statement_completion_test.dart | 47 - + .../edit/import_elements_test.dart | 139 - + ...is_postfix_completion_applicable_test.dart | 41 - + ...ist_postfix_completion_templates_test.dart | 41 - + .../edit/organize_directives_test.dart | 76 - + .../integration/edit/sort_members_test.dart | 64 - + .../test/integration/edit/test_all.dart | 38 - + .../execution/create_context_test.dart | 24 - + .../execution/delete_context_test.dart | 43 - + .../integration/execution/map_uri_test.dart | 40 - + .../execution/set_subscriptions_test.dart | 23 - + .../test/integration/execution/test_all.dart | 19 - + .../kythe/get_kythe_entries_test.dart | 39 - + .../test/integration/kythe/test_all.dart | 13 - + .../search/find_element_references_test.dart | 72 - + .../search/find_member_declarations_test.dart | 51 - + .../search/find_member_references_test.dart | 52 - + .../find_top_level_declarations_test.dart | 56 - + .../search/get_type_hierarchy_test.dart | 275 - + .../test/integration/search/test_all.dart | 25 - + .../integration/server/get_version_test.dart | 20 - + ...et_subscriptions_invalid_service_test.dart | 30 - + .../server/set_subscriptions_test.dart | 64 - + .../integration/server/shutdown_test.dart | 31 - + .../test/integration/server/status_test.dart | 50 - + .../test/integration/server/test_all.dart | 25 - + .../support/integration_test_methods.dart | 2240 --- + .../support/integration_tests.dart | 1003 - + .../support/protocol_matchers.dart | 2644 --- + .../test/integration/test_all.dart | 35 - + pkg/analysis_server/test/mock_sdk.dart | 438 - + pkg/analysis_server/test/mocks.dart | 320 - + .../test/plugin/protocol_dart_test.dart | 461 - + pkg/analysis_server/test/plugin/test_all.dart | 16 - + .../test/protocol_server_test.dart | 196 - + pkg/analysis_server/test/protocol_test.dart | 270 - + .../test/search/abstract_search_domain.dart | 113 - + .../test/search/element_references_test.dart | 674 - + .../test/search/member_declarations_test.dart | 157 - + .../test/search/member_references_test.dart | 114 - + .../test/search/search_result_test.dart | 55 - + pkg/analysis_server/test/search/test_all.dart | 26 - + .../search/top_level_declarations_test.dart | 82 - + .../test/search/type_hierarchy_test.dart | 1055 -- + .../dart/arglist_contributor_test.dart | 1019 - + .../dart/combinator_contributor_test.dart | 153 - + .../dart/common_usage_sorter_test.dart | 148 - + .../dart/completion_contributor_util.dart | 589 - + .../dart/completion_manager_test.dart | 91 - + .../dart/field_formal_contributor_test.dart | 197 - + .../imported_reference_contributor_test.dart | 4294 ----- + .../inherited_reference_contributor_test.dart | 607 - + .../dart/keyword_contributor_test.dart | 1826 -- + .../dart/label_contributor_test.dart | 320 - + .../dart/library_member_contributor_test.dart | 251 - + .../dart/library_prefix_contributor_test.dart | 329 - + .../local_constructor_contributor_test.dart | 3975 ---- + .../dart/local_library_contributor_test.dart | 282 - + .../local_reference_contributor_test.dart | 4585 ----- + .../named_constructor_contributor_test.dart | 171 - + .../dart/override_contributor_test.dart | 112 - + .../dart/static_member_contributor_test.dart | 285 - + .../services/completion/dart/test_all.dart | 52 - + .../dart/type_member_contributor_test.dart | 4027 ---- + .../completion/dart/uri_contributor_test.dart | 682 - + .../dart/variable_name_contributor_test.dart | 244 - + .../postfix/postfix_completion_test.dart | 709 - + .../services/completion/postfix/test_all.dart | 13 - + .../statement/statement_completion_test.dart | 1912 -- + .../completion/statement/test_all.dart | 13 - + .../test/services/completion/test_all.dart | 17 - + .../test/services/correction/assist_test.dart | 4443 ----- + .../test/services/correction/change_test.dart | 296 - + .../test/services/correction/fix_test.dart | 6753 ------- + .../services/correction/levenshtein_test.dart | 66 - + .../correction/name_suggestion_test.dart | 369 - + .../correction/organize_directives_test.dart | 321 - + .../correction/sort_members_test.dart | 810 - + .../test/services/correction/status_test.dart | 235 - + .../services/correction/strings_test.dart | 175 - + .../test/services/correction/test_all.dart | 32 - + .../test/services/correction/util_test.dart | 252 - + .../test/services/linter/linter_test.dart | 79 - + .../test/services/linter/test_all.dart | 13 - + .../refactoring/abstract_refactoring.dart | 175 - + .../services/refactoring/abstract_rename.dart | 75 - + .../convert_getter_to_method_test.dart | 163 - + .../convert_method_to_getter_test.dart | 215 - + .../refactoring/extract_local_test.dart | 1346 -- + .../refactoring/extract_method_test.dart | 2886 --- + .../refactoring/inline_local_test.dart | 639 - + .../refactoring/inline_method_test.dart | 1761 -- + .../refactoring/naming_conventions_test.dart | 754 - + .../refactoring/rename_class_member_test.dart | 894 - + .../refactoring/rename_constructor_test.dart | 249 - + .../refactoring/rename_import_test.dart | 230 - + .../refactoring/rename_label_test.dart | 83 - + .../refactoring/rename_library_test.dart | 91 - + .../refactoring/rename_local_test.dart | 545 - + .../refactoring/rename_unit_member_test.dart | 607 - + .../test/services/refactoring/test_all.dart | 40 - + .../test/services/search/hierarchy_test.dart | 362 - + .../services/search/search_engine_test.dart | 422 - + .../test/services/search/test_all.dart | 18 - + .../test/services/test_all.dart | 21 - + .../test/socket_server_test.dart | 142 - + .../computer/closingLabels_computer_test.dart | 346 - + .../import_elements_computer_test.dart | 343 - + .../imported_elements_computer_test.dart | 400 - + .../src/computer/outline_computer_test.dart | 1022 - + .../test/src/computer/test_all.dart | 20 - + .../test/src/domain_abstract_test.dart | 105 - + .../src/plugin/notification_manager_test.dart | 511 - + .../test/src/plugin/plugin_locator_test.dart | 96 - + .../test/src/plugin/plugin_manager_test.dart | 918 - + .../test/src/plugin/plugin_watcher_test.dart | 187 - + .../src/plugin/protocol_test_utilities.dart | 192 - + .../src/plugin/request_converter_test.dart | 82 - + .../src/plugin/result_collector_test.dart | 110 - + .../src/plugin/result_converter_test.dart | 128 - + .../test/src/plugin/result_merger_test.dart | 738 - + .../test/src/plugin/test_all.dart | 27 - + pkg/analysis_server/test/src/test_all.dart | 24 - + .../test/src/utilities/flutter_test.dart | 156 - + .../test/src/utilities/flutter_util.dart | 205 - + .../test/src/utilities/profiling_test.dart | 30 - + .../test/src/utilities/test_all.dart | 15 - + .../test/src/watch_manager_test.dart | 350 - + .../test/stress/replay/operation.dart | 80 - + .../test/stress/replay/replay.dart | 707 - + .../test/stress/utilities/git.dart | 551 - + .../test/stress/utilities/logger.dart | 49 - + .../test/stress/utilities/server.dart | 1081 -- + pkg/analysis_server/test/test_all.dart | 61 - + .../timing/completion/completion_simple.dart | 111 - + .../test/timing/timing_framework.dart | 312 - + .../tool/instrumentation/log/log.dart | 1195 -- + .../tool/instrumentation/log_viewer.dart | 129 - + .../tool/instrumentation/page/log_page.dart | 331 - + .../instrumentation/page/page_writer.dart | 317 - + .../tool/instrumentation/page/stats_page.dart | 265 - + .../tool/instrumentation/page/task_page.dart | 168 - + .../tool/instrumentation/server.dart | 238 - + pkg/analysis_server/tool/spec/api.dart | 528 - + .../tool/spec/check_all_test.dart | 23 - + .../tool/spec/codegen_analysis_server.dart | 137 - + .../tool/spec/codegen_dart.dart | 49 - + .../tool/spec/codegen_dart_protocol.dart | 1326 -- + .../tool/spec/codegen_inttest_methods.dart | 275 - + .../tool/spec/codegen_java.dart | 301 - + .../tool/spec/codegen_java_types.dart | 744 - + .../tool/spec/codegen_matchers.dart | 191 - + .../tool/spec/codegen_protocol_constants.dart | 170 - + pkg/analysis_server/tool/spec/from_html.dart | 609 - + .../tool/spec/generate_all.dart | 40 - + pkg/analysis_server/tool/spec/generate_files | 61 - + .../spec/generated/java/AnalysisServer.java | 757 - + .../java/types/AddContentOverlay.java | 132 - + .../generated/java/types/AnalysisError.java | 251 - + .../java/types/AnalysisErrorFixes.java | 138 - + .../java/types/AnalysisErrorSeverity.java | 32 - + .../java/types/AnalysisErrorType.java | 42 - + .../generated/java/types/AnalysisOptions.java | 287 - + .../generated/java/types/AnalysisService.java | 49 - + .../generated/java/types/AnalysisStatus.java | 136 - + .../java/types/ChangeContentOverlay.java | 142 - + .../generated/java/types/ClosingLabel.java | 156 - + .../java/types/CompletionSuggestion.java | 574 - + .../java/types/CompletionSuggestionKind.java | 64 - + .../generated/java/types/ContextData.java | 195 - + .../spec/generated/java/types/Element.java | 297 - + .../generated/java/types/ElementKind.java | 76 - + .../generated/java/types/ExecutableFile.java | 134 - + .../generated/java/types/ExecutableKind.java | 34 - + .../java/types/ExecutionService.java | 28 - + .../types/ExtractLocalVariableFeedback.java | 221 - + .../types/ExtractLocalVariableOptions.java | 152 - + .../java/types/ExtractMethodFeedback.java | 272 - + .../java/types/ExtractMethodOptions.java | 261 - + .../spec/generated/java/types/FileKind.java | 30 - + .../generated/java/types/FoldingKind.java | 36 - + .../generated/java/types/FoldingRegion.java | 153 - + .../java/types/GeneralAnalysisService.java | 29 - + .../generated/java/types/HighlightRegion.java | 157 - + .../java/types/HighlightRegionType.java | 319 - + .../java/types/HoverInformation.java | 372 - + .../java/types/ImplementedClass.java | 134 - + .../java/types/ImplementedMember.java | 134 - + .../java/types/ImportedElements.java | 158 - + .../types/InlineLocalVariableFeedback.java | 132 - + .../java/types/InlineMethodFeedback.java | 155 - + .../java/types/InlineMethodOptions.java | 152 - + .../spec/generated/java/types/KytheEntry.java | 202 - + .../spec/generated/java/types/KytheVName.java | 200 - + .../generated/java/types/LinkedEditGroup.java | 165 - + .../java/types/LinkedEditSuggestion.java | 135 - + .../java/types/LinkedEditSuggestionKind.java | 34 - + .../spec/generated/java/types/Location.java | 191 - + .../generated/java/types/MoveFileOptions.java | 120 - + .../java/types/NavigationRegion.java | 179 - + .../java/types/NavigationTarget.java | 220 - + .../generated/java/types/Occurrences.java | 166 - + .../spec/generated/java/types/Outline.java | 207 - + .../java/types/OverriddenMember.java | 134 - + .../generated/java/types/OverrideMember.java | 186 - + .../spec/generated/java/types/Position.java | 134 - + .../java/types/PostfixTemplateDescriptor.java | 153 - + .../spec/generated/java/types/PubStatus.java | 115 - + .../java/types/RefactoringFeedback.java | 85 - + .../generated/java/types/RefactoringKind.java | 44 - + .../types/RefactoringMethodParameter.java | 242 - + .../types/RefactoringMethodParameterKind.java | 32 - + .../java/types/RefactoringOptions.java | 85 - + .../java/types/RefactoringProblem.java | 159 - + .../types/RefactoringProblemSeverity.java | 55 - + .../java/types/RemoveContentOverlay.java | 113 - + .../generated/java/types/RenameFeedback.java | 172 - + .../generated/java/types/RenameOptions.java | 120 - + .../generated/java/types/RequestError.java | 155 - + .../java/types/RequestErrorCode.java | 182 - + .../generated/java/types/SearchResult.java | 182 - + .../java/types/SearchResultKind.java | 61 - + .../generated/java/types/ServerService.java | 28 - + .../generated/java/types/SourceChange.java | 182 - + .../spec/generated/java/types/SourceEdit.java | 186 - + .../generated/java/types/SourceFileEdit.java | 163 - + .../java/types/TypeHierarchyItem.java | 271 - + .../tool/spec/implied_types.dart | 89 - + pkg/analysis_server/tool/spec/spec_input.html | 3975 ---- + pkg/analysis_server/tool/spec/to_html.dart | 831 - + pkg/analysis_server_client/CHANGELOG.md | 5 - + pkg/analysis_server_client/LICENSE | 26 - + pkg/analysis_server_client/README.md | 13 - + .../lib/analysis_server_client.dart | 101 - + pkg/analysis_server_client/pubspec.yaml | 13 - + .../test/analysis_server_client_test.dart | 97 - + pkg/analyzer/README.md | 2 - + pkg/analyzer/lib/src/codegen/tools.dart | 2 - + pkg/analyzer_cli/lib/src/driver.dart | 58 +- + pkg/analyzer_cli/lib/src/options.dart | 55 +- + pkg/analyzer_cli/pubspec.yaml | 1 - + pkg/analyzer_cli/test/options_test.dart | 23 - + .../support/integration_test_methods.dart | 815 - + .../support/integration_tests.dart | 15 - + pkg/front_end/testing.json | 1 - + pkg/microlytics/example/simple.dart | 26 - + pkg/microlytics/lib/channels.dart | 53 - + pkg/microlytics/lib/html_channels.dart | 14 - + pkg/microlytics/lib/io_channels.dart | 20 - + pkg/microlytics/lib/microlytics.dart | 57 - + pkg/microlytics/pubspec.yaml | 8 - + .../test/dart_microlytics_test.dart | 114 - + pkg/microlytics/test/test_channel.dart | 19 - + pkg/pkg.status | 15 - + pkg/telemetry/LICENSE | 26 - + pkg/telemetry/README.md | 51 - + pkg/telemetry/analysis_options.yaml | 10 - + pkg/telemetry/lib/crash_reporting.dart | 94 - + pkg/telemetry/lib/telemetry.dart | 126 - + pkg/telemetry/pubspec.yaml | 16 - + pkg/telemetry/test/crash_reporting_test.dart | 41 - + pkg/telemetry/test/telemetry_test.dart | 31 - + runtime/observatory/lib/app.dart | 3 +- + .../observatory/lib/src/app/analytics.dart | 31 - + runtime/observatory/observatory_sources.gni | 1 - + sdk/BUILD.gn | 11 - + tests/lib/analyzer/analyze_library.status | 1 - + tools/bots/dartdoc_footer.html | 13 - + tools/bots/test_matrix.json | 30 - + tools/bots/try_benchmarks.sh | 1 - + utils/analysis_server/.gitignore | 3 - + utils/analysis_server/BUILD.gn | 10 - + 525 files changed, 8 insertions(+), 187921 deletions(-) + delete mode 100644 pkg/analysis_server/AUTHORS + delete mode 100644 pkg/analysis_server/CHANGELOG.md + delete mode 100644 pkg/analysis_server/CONTRIBUTING.md + delete mode 100644 pkg/analysis_server/LICENSE + delete mode 100644 pkg/analysis_server/README.md + delete mode 100644 pkg/analysis_server/analysis_options.yaml + delete mode 100644 pkg/analysis_server/benchmark/benchmarks.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/README.md + delete mode 100644 pkg/analysis_server/benchmark/integration/driver.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/input_converter.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/local_runner.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/log_file_input_converter.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/main.dart + delete mode 100644 pkg/analysis_server/benchmark/integration/operation.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/benchmark_angular.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/benchmark_flutter.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/benchmark_scenario.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/benchmarks_impl.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/completion_timing_tests.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/memory_tests.dart + delete mode 100644 pkg/analysis_server/benchmark/perf/performance_tests.dart + delete mode 100644 pkg/analysis_server/benchmark/readme.md + delete mode 100644 pkg/analysis_server/bin/server.dart + delete mode 100644 pkg/analysis_server/doc/api.html + delete mode 100644 pkg/analysis_server/lib/plugin/analysis/occurrences/occurrences_core.dart + delete mode 100644 pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart + delete mode 100644 pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart + delete mode 100644 pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart + delete mode 100644 pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart + delete mode 100644 pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart + delete mode 100644 pkg/analysis_server/lib/protocol/protocol.dart + delete mode 100644 pkg/analysis_server/lib/protocol/protocol_constants.dart + delete mode 100644 pkg/analysis_server/lib/protocol/protocol_generated.dart + delete mode 100644 pkg/analysis_server/lib/src/analysis_logger.dart + delete mode 100644 pkg/analysis_server/lib/src/analysis_server.dart + delete mode 100644 pkg/analysis_server/lib/src/channel/byte_stream_channel.dart + delete mode 100644 pkg/analysis_server/lib/src/channel/channel.dart + delete mode 100644 pkg/analysis_server/lib/src/collections.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/computer_closingLabels.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/computer_highlights.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/computer_highlights2.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/computer_hover.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/computer_outline.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/computer_overrides.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/import_elements_computer.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/imported_elements_computer.dart + delete mode 100644 pkg/analysis_server/lib/src/computer/new_notifications.dart + delete mode 100644 pkg/analysis_server/lib/src/constants.dart + delete mode 100644 pkg/analysis_server/lib/src/context_manager.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_abstract.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_analysis.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_analytics.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_completion.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_diagnostic.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_execution.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_kythe.dart + delete mode 100644 pkg/analysis_server/lib/src/domain_server.dart + delete mode 100644 pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart + delete mode 100644 pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart + delete mode 100644 pkg/analysis_server/lib/src/domains/analysis/occurrences.dart + delete mode 100644 pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart + delete mode 100644 pkg/analysis_server/lib/src/edit/edit_domain.dart + delete mode 100644 pkg/analysis_server/lib/src/operation/operation_analysis.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/notification_manager.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/plugin_locator.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/plugin_manager.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/plugin_watcher.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/request_converter.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/result_collector.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/result_converter.dart + delete mode 100644 pkg/analysis_server/lib/src/plugin/result_merger.dart + delete mode 100644 pkg/analysis_server/lib/src/protocol/protocol_internal.dart + delete mode 100644 pkg/analysis_server/lib/src/protocol_server.dart + delete mode 100644 pkg/analysis_server/lib/src/provisional/completion/completion_core.dart + delete mode 100644 pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart + delete mode 100644 pkg/analysis_server/lib/src/search/element_references.dart + delete mode 100644 pkg/analysis_server/lib/src/search/search_domain.dart + delete mode 100644 pkg/analysis_server/lib/src/search/type_hierarchy.dart + delete mode 100644 pkg/analysis_server/lib/src/server/diagnostic_server.dart + delete mode 100644 pkg/analysis_server/lib/src/server/driver.dart + delete mode 100644 pkg/analysis_server/lib/src/server/http_server.dart + delete mode 100644 pkg/analysis_server/lib/src/server/stdio_server.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/completion_core.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/completion_performance.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/utilities.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart + delete mode 100644 pkg/analysis_server/lib/src/services/completion/statement/design_notes.md + delete mode 100644 pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/assist.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/assist_internal.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/fix.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/fix_internal.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/levenshtein.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/name_suggestion.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/namespace.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/organize_directives.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/sort_members.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/source_buffer.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/status.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/strings.dart + delete mode 100644 pkg/analysis_server/lib/src/services/correction/util.dart + delete mode 100644 pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart + delete mode 100644 pkg/analysis_server/lib/src/services/kythe/schema.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/extract_local.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/extract_method.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/inline_local.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/inline_method.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/refactoring.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_import.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_label.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_library.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_local.dart + delete mode 100644 pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart + delete mode 100644 pkg/analysis_server/lib/src/services/search/element_visitors.dart + delete mode 100644 pkg/analysis_server/lib/src/services/search/hierarchy.dart + delete mode 100644 pkg/analysis_server/lib/src/services/search/search_engine.dart + delete mode 100644 pkg/analysis_server/lib/src/services/search/search_engine_internal.dart + delete mode 100644 pkg/analysis_server/lib/src/socket_server.dart + delete mode 100644 pkg/analysis_server/lib/src/status/ast_writer.dart + delete mode 100644 pkg/analysis_server/lib/src/status/diagnostics.dart + delete mode 100644 pkg/analysis_server/lib/src/status/element_writer.dart + delete mode 100644 pkg/analysis_server/lib/src/status/pages.dart + delete mode 100644 pkg/analysis_server/lib/src/status/tree_writer.dart + delete mode 100644 pkg/analysis_server/lib/src/utilities/documentation.dart + delete mode 100644 pkg/analysis_server/lib/src/utilities/flutter.dart + delete mode 100644 pkg/analysis_server/lib/src/utilities/null_string_sink.dart + delete mode 100644 pkg/analysis_server/lib/src/utilities/profiling.dart + delete mode 100644 pkg/analysis_server/lib/src/watch_manager.dart + delete mode 100644 pkg/analysis_server/lib/starter.dart + delete mode 100644 pkg/analysis_server/pubspec.yaml + delete mode 100644 pkg/analysis_server/test/abstract_context.dart + delete mode 100644 pkg/analysis_server/test/abstract_single_unit.dart + delete mode 100644 pkg/analysis_server/test/analysis/get_errors_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/get_hover_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/get_navigation_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_analysis_options_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_closingLabels_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_errors_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_highlights_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_highlights_test2.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_implemented_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_navigation_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_occurrences_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_outline_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/notification_overrides_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/reanalyze_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/set_priority_files_test.dart + delete mode 100644 pkg/analysis_server/test/analysis/test_all.dart + delete mode 100644 pkg/analysis_server/test/analysis/update_content_test.dart + delete mode 100644 pkg/analysis_server/test/analysis_abstract.dart + delete mode 100644 pkg/analysis_server/test/analysis_server_test.dart + delete mode 100644 pkg/analysis_server/test/benchmarks_test.dart + delete mode 100644 pkg/analysis_server/test/channel/byte_stream_channel_test.dart + delete mode 100644 pkg/analysis_server/test/channel/test_all.dart + delete mode 100644 pkg/analysis_server/test/completion_test.dart + delete mode 100644 pkg/analysis_server/test/completion_test_support.dart + delete mode 100644 pkg/analysis_server/test/context_manager_test.dart + delete mode 100644 pkg/analysis_server/test/domain_analysis_test.dart + delete mode 100644 pkg/analysis_server/test/domain_completion_test.dart + delete mode 100644 pkg/analysis_server/test/domain_completion_util.dart + delete mode 100644 pkg/analysis_server/test/domain_diagnostic_test.dart + delete mode 100644 pkg/analysis_server/test/domain_execution_test.dart + delete mode 100644 pkg/analysis_server/test/domain_server_test.dart + delete mode 100644 pkg/analysis_server/test/edit/assists_test.dart + delete mode 100644 pkg/analysis_server/test/edit/fixes_test.dart + delete mode 100644 pkg/analysis_server/test/edit/format_test.dart + delete mode 100644 pkg/analysis_server/test/edit/organize_directives_test.dart + delete mode 100644 pkg/analysis_server/test/edit/postfix_completion_test.dart + delete mode 100644 pkg/analysis_server/test/edit/refactoring_test.dart + delete mode 100644 pkg/analysis_server/test/edit/sort_members_test.dart + delete mode 100644 pkg/analysis_server/test/edit/statement_completion_test.dart + delete mode 100644 pkg/analysis_server/test/edit/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/analysis_options_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/error_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_errors_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_hover_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_navigation_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/highlights_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/highlights_test2.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/lint_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/navigation_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/occurrences_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/outline_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/overrides_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/package_root_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/reanalyze_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/set_analysis_roots_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/set_general_subscriptions_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/set_subscriptions_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/update_content_list_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/update_content_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analysis/update_options_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analytics/enable_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analytics/is_enabled_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analytics/send_event_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analytics/send_timing_test.dart + delete mode 100644 pkg/analysis_server/test/integration/analytics/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/completion/get_suggestions_test.dart + delete mode 100644 pkg/analysis_server/test/integration/completion/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/coverage.md + delete mode 100644 pkg/analysis_server/test/integration/coverage_test.dart + delete mode 100644 pkg/analysis_server/test/integration/diagnostic/get_diagnostics_test.dart + delete mode 100644 pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart + delete mode 100644 pkg/analysis_server/test/integration/diagnostic/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/format_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/get_assists_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/get_available_refactorings_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/get_fixes_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/get_refactoring_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/get_statement_completion_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/import_elements_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/is_postfix_completion_applicable_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/list_postfix_completion_templates_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/organize_directives_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/sort_members_test.dart + delete mode 100644 pkg/analysis_server/test/integration/edit/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/execution/create_context_test.dart + delete mode 100644 pkg/analysis_server/test/integration/execution/delete_context_test.dart + delete mode 100644 pkg/analysis_server/test/integration/execution/map_uri_test.dart + delete mode 100644 pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart + delete mode 100644 pkg/analysis_server/test/integration/execution/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/kythe/get_kythe_entries_test.dart + delete mode 100644 pkg/analysis_server/test/integration/kythe/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/search/find_element_references_test.dart + delete mode 100644 pkg/analysis_server/test/integration/search/find_member_declarations_test.dart + delete mode 100644 pkg/analysis_server/test/integration/search/find_member_references_test.dart + delete mode 100644 pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart + delete mode 100644 pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart + delete mode 100644 pkg/analysis_server/test/integration/search/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/server/get_version_test.dart + delete mode 100644 pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart + delete mode 100644 pkg/analysis_server/test/integration/server/set_subscriptions_test.dart + delete mode 100644 pkg/analysis_server/test/integration/server/shutdown_test.dart + delete mode 100644 pkg/analysis_server/test/integration/server/status_test.dart + delete mode 100644 pkg/analysis_server/test/integration/server/test_all.dart + delete mode 100644 pkg/analysis_server/test/integration/support/integration_test_methods.dart + delete mode 100644 pkg/analysis_server/test/integration/support/integration_tests.dart + delete mode 100644 pkg/analysis_server/test/integration/support/protocol_matchers.dart + delete mode 100644 pkg/analysis_server/test/integration/test_all.dart + delete mode 100644 pkg/analysis_server/test/mock_sdk.dart + delete mode 100644 pkg/analysis_server/test/mocks.dart + delete mode 100644 pkg/analysis_server/test/plugin/protocol_dart_test.dart + delete mode 100644 pkg/analysis_server/test/plugin/test_all.dart + delete mode 100644 pkg/analysis_server/test/protocol_server_test.dart + delete mode 100644 pkg/analysis_server/test/protocol_test.dart + delete mode 100644 pkg/analysis_server/test/search/abstract_search_domain.dart + delete mode 100644 pkg/analysis_server/test/search/element_references_test.dart + delete mode 100644 pkg/analysis_server/test/search/member_declarations_test.dart + delete mode 100644 pkg/analysis_server/test/search/member_references_test.dart + delete mode 100644 pkg/analysis_server/test/search/search_result_test.dart + delete mode 100644 pkg/analysis_server/test/search/test_all.dart + delete mode 100644 pkg/analysis_server/test/search/top_level_declarations_test.dart + delete mode 100644 pkg/analysis_server/test/search/type_hierarchy_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/postfix/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart + delete mode 100644 pkg/analysis_server/test/services/completion/statement/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/completion/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/correction/assist_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/change_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/fix_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/levenshtein_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/name_suggestion_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/organize_directives_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/sort_members_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/status_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/strings_test.dart + delete mode 100644 pkg/analysis_server/test/services/correction/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/correction/util_test.dart + delete mode 100644 pkg/analysis_server/test/services/linter/linter_test.dart + delete mode 100644 pkg/analysis_server/test/services/linter/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/abstract_rename.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/extract_local_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/extract_method_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/inline_local_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/inline_method_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_import_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_label_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_library_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_local_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart + delete mode 100644 pkg/analysis_server/test/services/refactoring/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/search/hierarchy_test.dart + delete mode 100644 pkg/analysis_server/test/services/search/search_engine_test.dart + delete mode 100644 pkg/analysis_server/test/services/search/test_all.dart + delete mode 100644 pkg/analysis_server/test/services/test_all.dart + delete mode 100644 pkg/analysis_server/test/socket_server_test.dart + delete mode 100644 pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart + delete mode 100644 pkg/analysis_server/test/src/computer/import_elements_computer_test.dart + delete mode 100644 pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart + delete mode 100644 pkg/analysis_server/test/src/computer/outline_computer_test.dart + delete mode 100644 pkg/analysis_server/test/src/computer/test_all.dart + delete mode 100644 pkg/analysis_server/test/src/domain_abstract_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/notification_manager_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/plugin_locator_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/plugin_manager_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/request_converter_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/result_collector_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/result_converter_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/result_merger_test.dart + delete mode 100644 pkg/analysis_server/test/src/plugin/test_all.dart + delete mode 100644 pkg/analysis_server/test/src/test_all.dart + delete mode 100644 pkg/analysis_server/test/src/utilities/flutter_test.dart + delete mode 100644 pkg/analysis_server/test/src/utilities/flutter_util.dart + delete mode 100644 pkg/analysis_server/test/src/utilities/profiling_test.dart + delete mode 100644 pkg/analysis_server/test/src/utilities/test_all.dart + delete mode 100644 pkg/analysis_server/test/src/watch_manager_test.dart + delete mode 100644 pkg/analysis_server/test/stress/replay/operation.dart + delete mode 100644 pkg/analysis_server/test/stress/replay/replay.dart + delete mode 100644 pkg/analysis_server/test/stress/utilities/git.dart + delete mode 100644 pkg/analysis_server/test/stress/utilities/logger.dart + delete mode 100644 pkg/analysis_server/test/stress/utilities/server.dart + delete mode 100644 pkg/analysis_server/test/test_all.dart + delete mode 100644 pkg/analysis_server/test/timing/completion/completion_simple.dart + delete mode 100644 pkg/analysis_server/test/timing/timing_framework.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/log/log.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/log_viewer.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/page/log_page.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/page/page_writer.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/page/stats_page.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/page/task_page.dart + delete mode 100644 pkg/analysis_server/tool/instrumentation/server.dart + delete mode 100644 pkg/analysis_server/tool/spec/api.dart + delete mode 100644 pkg/analysis_server/tool/spec/check_all_test.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_analysis_server.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_dart.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_dart_protocol.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_inttest_methods.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_java.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_java_types.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_matchers.dart + delete mode 100644 pkg/analysis_server/tool/spec/codegen_protocol_constants.dart + delete mode 100644 pkg/analysis_server/tool/spec/from_html.dart + delete mode 100644 pkg/analysis_server/tool/spec/generate_all.dart + delete mode 100755 pkg/analysis_server/tool/spec/generate_files + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ContextData.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/Element.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/FileKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/Location.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/Outline.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/Position.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RequestError.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/ServerService.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java + delete mode 100644 pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java + delete mode 100644 pkg/analysis_server/tool/spec/implied_types.dart + delete mode 100644 pkg/analysis_server/tool/spec/spec_input.html + delete mode 100644 pkg/analysis_server/tool/spec/to_html.dart + delete mode 100644 pkg/analysis_server_client/CHANGELOG.md + delete mode 100644 pkg/analysis_server_client/LICENSE + delete mode 100644 pkg/analysis_server_client/README.md + delete mode 100644 pkg/analysis_server_client/lib/analysis_server_client.dart + delete mode 100644 pkg/analysis_server_client/pubspec.yaml + delete mode 100644 pkg/analysis_server_client/test/analysis_server_client_test.dart + delete mode 100644 pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart + delete mode 100644 pkg/microlytics/example/simple.dart + delete mode 100644 pkg/microlytics/lib/channels.dart + delete mode 100644 pkg/microlytics/lib/html_channels.dart + delete mode 100644 pkg/microlytics/lib/io_channels.dart + delete mode 100644 pkg/microlytics/lib/microlytics.dart + delete mode 100644 pkg/microlytics/pubspec.yaml + delete mode 100644 pkg/microlytics/test/dart_microlytics_test.dart + delete mode 100644 pkg/microlytics/test/test_channel.dart + delete mode 100644 pkg/telemetry/LICENSE + delete mode 100644 pkg/telemetry/README.md + delete mode 100644 pkg/telemetry/analysis_options.yaml + delete mode 100644 pkg/telemetry/lib/crash_reporting.dart + delete mode 100644 pkg/telemetry/lib/telemetry.dart + delete mode 100644 pkg/telemetry/pubspec.yaml + delete mode 100644 pkg/telemetry/test/crash_reporting_test.dart + delete mode 100644 pkg/telemetry/test/telemetry_test.dart + delete mode 100644 runtime/observatory/lib/src/app/analytics.dart + delete mode 100644 utils/analysis_server/.gitignore + delete mode 100644 utils/analysis_server/BUILD.gn + +diff --git a/BUILD.gn b/BUILD.gn +index 80e3bdd3757..0f7746d8c92 100644 +--- a/BUILD.gn ++++ b/BUILD.gn +@@ -21,7 +21,6 @@ group("most") { + testonly = true + } + deps = [ +- ":analysis_server", + ":create_sdk", + ":dart2js", + ":dartanalyzer", +@@ -107,12 +106,6 @@ group("dartfmt") { + ] + } + +-group("analysis_server") { +- deps = [ +- "utils/analysis_server", +- ] +-} +- + # This is the target that is built on the dart2js build bots. + # It must depend on anything that is required by the dart2js + # test suites. +diff --git a/pkg/analysis_server/AUTHORS b/pkg/analysis_server/AUTHORS +deleted file mode 100644 +index e8063a8cd6e..00000000000 +--- a/pkg/analysis_server/AUTHORS ++++ /dev/null +@@ -1,6 +0,0 @@ +-# Below is a list of people and organizations that have contributed +-# to the project. Names should be added to the list like so: +-# +-# Name/Organization +- +-Google Inc. +diff --git a/pkg/analysis_server/CHANGELOG.md b/pkg/analysis_server/CHANGELOG.md +deleted file mode 100644 +index 2a2d63cf8e6..00000000000 +--- a/pkg/analysis_server/CHANGELOG.md ++++ /dev/null +@@ -1,5 +0,0 @@ +-# Changelog +- +-## 0.0.1 +- +-- Initial version +diff --git a/pkg/analysis_server/CONTRIBUTING.md b/pkg/analysis_server/CONTRIBUTING.md +deleted file mode 100644 +index 242f214b5e7..00000000000 +--- a/pkg/analysis_server/CONTRIBUTING.md ++++ /dev/null +@@ -1,40 +0,0 @@ +-## Contributing +- +-Contributions welcome! Please follow the guide in [Contributing][contributing]. +- +-## Building +- +-If you want to build Dart yourself, here is a guide to +-[getting the source, preparing your machine to build the SDK, and +-building][building]. +- +-There are more documents on our [wiki](https://github.com/dart-lang/sdk/wiki). +-Once set up to build the SDK, run: +- +-``` +-./tools/build.py -mrelease create_sdk +-``` +- +-## Running tests +- +-To run analyzer tests: +- +-``` +-./tools/test.py -mrelease pkg/analyzer/test/ +-``` +- +-To run all analysis server tests: +- +-``` +-./tools/test.py -mrelease pkg/analysis_server/test/ +-``` +- +-To run just the analysis server integration tests: +- +-``` +-./tools/test.py -mrelease pkg/analysis_server/test/integration/ +-``` +- +- +-[building]: https://github.com/dart-lang/sdk/wiki/Building +-[contributing]: https://github.com/dart-lang/sdk/wiki/Contributing +diff --git a/pkg/analysis_server/LICENSE b/pkg/analysis_server/LICENSE +deleted file mode 100644 +index 5c60afea399..00000000000 +--- a/pkg/analysis_server/LICENSE ++++ /dev/null +@@ -1,26 +0,0 @@ +-Copyright 2014, the Dart project authors. All rights reserved. +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions are +-met: +- +- * Redistributions of source code must retain the above copyright +- notice, this list of conditions and the following disclaimer. +- * Redistributions in binary form must reproduce the above +- copyright notice, this list of conditions and the following +- disclaimer in the documentation and/or other materials provided +- with the distribution. +- * Neither the name of Google Inc. nor the names of its +- contributors may be used to endorse or promote products derived +- from this software without specific prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +diff --git a/pkg/analysis_server/README.md b/pkg/analysis_server/README.md +deleted file mode 100644 +index d596f5c47af..00000000000 +--- a/pkg/analysis_server/README.md ++++ /dev/null +@@ -1,22 +0,0 @@ +-# analysis_server +- +-A long-running process that provides analysis results to other tools. +- +-The analysis server is designed to provide on-going analysis of one or more code +-bases as those code bases are changing. +- +-## Using the server +- +-The analysis server is not intended to be used stand-alone, and therefore does +-not have a human-friendly user interface. +- +-Clients (typically tools, such as an editor) are expected to run the analysis +-server in a separate process and communicate with it using a JSON protocol. The +-protocol is specified in the file [`analysis_server/doc/api.html`][api]. +- +-## Features and bugs +- +-Please file feature requests and bugs at the [issue tracker][tracker]. +- +-[tracker]: https://github.com/dart-lang/sdk/issues +-[api]: https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/master/pkg/analysis_server/doc/api.html +diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml +deleted file mode 100644 +index 9bacf2b50aa..00000000000 +--- a/pkg/analysis_server/analysis_options.yaml ++++ /dev/null +@@ -1,8 +0,0 @@ +-analyzer: +- strong-mode: true +-linter: +- rules: +- - empty_constructor_bodies +- - empty_statements +- - unnecessary_brace_in_string_interps +- - valid_regexps +diff --git a/pkg/analysis_server/benchmark/benchmarks.dart b/pkg/analysis_server/benchmark/benchmarks.dart +deleted file mode 100644 +index 63eb6720e32..00000000000 +--- a/pkg/analysis_server/benchmark/benchmarks.dart ++++ /dev/null +@@ -1,239 +0,0 @@ +-// 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:convert'; +-import 'dart:io'; +-import 'dart:math' as math; +- +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:args/command_runner.dart'; +-import 'package:intl/intl.dart'; +-import 'package:path/path.dart' as path; +- +-import 'perf/benchmarks_impl.dart'; +- +-Future main(List args) async { +- final List benchmarks = [ +- new ColdAnalysisBenchmark(), +- new AnalysisBenchmark() +- ]; +- +- CommandRunner runner = new CommandRunner( +- 'benchmark', 'A benchmark runner for the analysis server.'); +- runner.addCommand(new ListCommand(benchmarks)); +- runner.addCommand(new RunCommand(benchmarks)); +- runner.run(args); +-} +- +-class ListCommand extends Command { +- final List benchmarks; +- +- ListCommand(this.benchmarks) { +- argParser.addFlag('machine', +- negatable: false, help: 'Emit the list of benchmarks as json.'); +- } +- +- @override +- String get name => 'list'; +- +- @override +- String get description => 'List available benchmarks.'; +- +- @override +- String get invocation => '${runner.executableName} $name'; +- +- void run() { +- if (argResults['machine']) { +- final Map map = { +- 'benchmarks': benchmarks.map((b) => b.toJson()).toList() +- }; +- print(new JsonEncoder.withIndent(' ').convert(map)); +- } else { +- for (Benchmark benchmark in benchmarks) { +- print('${benchmark.id}: ${benchmark.description}'); +- } +- } +- } +-} +- +-class RunCommand extends Command { +- final List benchmarks; +- +- RunCommand(this.benchmarks) { +- argParser.addFlag('quick', +- negatable: false, +- help: 'Run a quick version of the benchmark. This is not useful for ' +- 'gathering accurate times,\nbut can be used to validate that the ' +- 'benchmark works.'); +- argParser.addFlag('preview-dart-2', +- negatable: false, +- help: 'Benchmark against the Dart 2.0 front end implementation.'); +- argParser.addOption('repeat', +- defaultsTo: '10', help: 'The number of times to repeat the benchmark.'); +- } +- +- @override +- String get name => 'run'; +- +- @override +- String get description => 'Run a given benchmark.'; +- +- @override +- String get invocation => '${runner.executableName} $name '; +- +- Future run() async { +- if (argResults.rest.isEmpty) { +- printUsage(); +- exit(1); +- } +- +- final String benchmarkId = argResults.rest.first; +- final int repeatCount = int.parse(argResults['repeat']); +- final bool quick = argResults['quick']; +- final bool previewDart2 = argResults['preview-dart-2']; +- +- final Benchmark benchmark = +- benchmarks.firstWhere((b) => b.id == benchmarkId, orElse: () { +- print("Benchmark '$benchmarkId' not found."); +- exit(1); +- }); +- +- int actualIterations = repeatCount; +- if (benchmark.maxIterations > 0) { +- actualIterations = math.min(benchmark.maxIterations, repeatCount); +- } +- +- try { +- BenchMarkResult result; +- Stopwatch time = new Stopwatch()..start(); +- print('Running $benchmarkId $actualIterations times...'); +- +- for (int iteration = 0; iteration < actualIterations; iteration++) { +- BenchMarkResult newResult = await benchmark.run( +- quick: quick, +- previewDart2: previewDart2, +- ); +- print(' $newResult'); +- result = result == null ? newResult : result.combine(newResult); +- } +- +- time.stop(); +- print('Finished in ${time.elapsed.inSeconds} seconds.\n'); +- Map m = {'benchmark': benchmarkId, 'result': result.toJson()}; +- print(JSON.encode(m)); +- } catch (error, st) { +- print('$benchmarkId threw exception: $error'); +- print(st); +- exit(1); +- } +- } +-} +- +-abstract class Benchmark { +- final String id; +- final String description; +- final bool enabled; +- +- /// One of 'memory', 'cpu', or 'group'. +- final String kind; +- +- Benchmark(this.id, this.description, {this.enabled: true, this.kind: 'cpu'}); +- +- Future run({bool quick: false, bool previewDart2: false}); +- +- int get maxIterations => 0; +- +- Map toJson() => +- {'id': id, 'description': description, 'enabled': enabled, 'kind': kind}; +- +- String toString() => '$id: $description'; +-} +- +-class BenchMarkResult { +- static final NumberFormat nf = new NumberFormat.decimalPattern(); +- +- /// One of 'bytes', 'micros', or 'compound'. +- final String kindName; +- +- final int value; +- +- BenchMarkResult(this.kindName, this.value); +- +- BenchMarkResult combine(BenchMarkResult other) { +- return new BenchMarkResult(kindName, math.min(value, other.value)); +- } +- +- Map toJson() => {kindName: value}; +- +- String toString() => '$kindName: ${nf.format(value)}'; +-} +- +-class CompoundBenchMarkResult extends BenchMarkResult { +- final String name; +- +- CompoundBenchMarkResult(this.name) : super('compound', 0); +- +- Map results = {}; +- +- void add(String name, BenchMarkResult result) { +- results[name] = result; +- } +- +- BenchMarkResult combine(BenchMarkResult other) { +- BenchMarkResult _combine(BenchMarkResult a, BenchMarkResult b) { +- if (a == null) return b; +- if (b == null) return a; +- return a.combine(b); +- } +- +- CompoundBenchMarkResult o = other as CompoundBenchMarkResult; +- +- CompoundBenchMarkResult combined = new CompoundBenchMarkResult(name); +- List keys = +- (new Set()..addAll(results.keys)..addAll(o.results.keys)).toList(); +- +- for (String key in keys) { +- combined.add(key, _combine(results[key], o.results[key])); +- } +- +- return combined; +- } +- +- Map toJson() { +- Map m = {}; +- for (String key in results.keys) { +- m['$name-$key'] = results[key].toJson(); +- } +- return m; +- } +- +- String toString() => '${toJson()}'; +-} +- +-List getProjectRoots({bool quick: false}) { +- String script = Platform.script.toFilePath(windows: Platform.isWindows); +- String pkgPath = path.normalize(path.join(path.dirname(script), '..', '..')); +- return [path.join(pkgPath, quick ? 'meta' : 'analysis_server')]; +-} +- +-String get analysisServerSrcPath { +- String script = Platform.script.toFilePath(windows: Platform.isWindows); +- String pkgPath = path.normalize(path.join(path.dirname(script), '..', '..')); +- return path.join(pkgPath, 'analysis_server'); +-} +- +-void deleteServerCache() { +- // ~/.dartServer/.analysis-driver/ +- ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; +- Folder stateLocation = resourceProvider.getStateLocation('.analysis-driver'); +- try { +- if (stateLocation.exists) { +- stateLocation.delete(); +- } +- } catch (e) { +- // ignore any exception +- } +-} +diff --git a/pkg/analysis_server/benchmark/integration/README.md b/pkg/analysis_server/benchmark/integration/README.md +deleted file mode 100644 +index 9955c11ce06..00000000000 +--- a/pkg/analysis_server/benchmark/integration/README.md ++++ /dev/null +@@ -1,69 +0,0 @@ +-# Running Benchmarks +- +-There are two entry points for running benchmarks: +-* **main.dart** - a general Dart application for running performance benchmarks +-* **local_runner.dart** - an example Dart application +-which sets up the local environment +-and then calls main.dart to run performance benchmarks +- +-## local_runner.dart +- +-This Dart application is one example for running performance benchmarks. +-When run, this application 1) extracts a branch from a git repository +-into a temporary directory, and 2) creates a symlink to the out or xcodebuild +-directory for proper package-root package resolution. +-Once setup is complete, this applications calls main.dart +- +-The required command line arguments are +-* **gitDir** = a path to the git repository containing the initial target source +-* **branch** = the branch containing the initial target source +-* **inputFile** = the instrumentation or log file +- +-Additional arguments are passed directly to main.dart. +-For example, if the log was recorded on one machine and is played back on another, +-then you might need to specify -m, +-to map the source paths for playback. +-When specifying additional arguments, any occurrences of @tmpSrcDir@ +-will be replaced with the absolute path of the temporary directory +-into which the source was extracted. +- +-## main.dart +- +-This Dart application reads an instrumentation or local log file produced by +-analysis server, "replays" that interaction with the analysis server, +-compares the notifications and responses with what was recorded in the log, +-and produces a report. It assumes that the environment for playback has +-already been setup. +-The required command line arguments are +-* **-i, --input ** +-The input file specifying how this client should interact with the server. +-If the input file name is "stdin", then the instructions are read from stdin. +-* **-m, --map ,** +-This option defines a mapping from the original source directory +-when the instrumentation or log file was generated +-to the target source directory used during performance testing. +-Multiple mappings can be specified. +-WARNING: The contents of the target directory will be modified +-* **-t, --tmpSrcDir ** +-The temporary directory containing source used during performance measurement. +-WARNING: The contents of the target directory will be modified +-* **-d, --diagnosticPort** localhost port on which server +- will provide diagnostic web pages +-* **-v, --verbose** Verbose logging +-* **--vv** Extra verbose logging +-* **-h, --help** Print this help information +- +-For each request recorded in the input file, +-the application sends a corresponding request to the analysis server +-and waits up to 60 seconds for a response to that request. +-If a response in not received in that time, then the application exits. +-Any responses that are received are compared with the recorded response. +- +-For each analysis-complete notification recorded in the input file, +-the application waits for the corresponding analysis-complete notification +-from the running analysis server. +-While it is waiting for an analysis-complete notification, +-the application monitors the stream of notifications. +-If there is a period of more than 60 seconds during which no communication +-is received from the server, the application assumes that the server is hung +-and exits. +diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart +deleted file mode 100644 +index da928396139..00000000000 +--- a/pkg/analysis_server/benchmark/integration/driver.dart ++++ /dev/null +@@ -1,315 +0,0 @@ +-// Copyright (c) 2015, 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:math' show max, sqrt; +- +-import 'package:logging/logging.dart'; +- +-import '../../test/integration/support/integration_test_methods.dart'; +-import '../../test/integration/support/integration_tests.dart'; +-import 'operation.dart'; +- +-final SPACE = ' '.codeUnitAt(0); +- +-void _printColumn(StringBuffer sb, String text, int keyLen, +- {bool rightJustified: false}) { +- if (!rightJustified) { +- sb.write(text); +- sb.write(','); +- } +- for (int i = text.length; i < keyLen; ++i) { +- sb.writeCharCode(SPACE); +- } +- if (rightJustified) { +- sb.write(text); +- sb.write(','); +- } +- sb.writeCharCode(SPACE); +-} +- +-/** +- * [Driver] launches and manages an instance of analysis server, +- * reads a stream of operations, sends requests to analysis server +- * based upon those operations, and evaluates the results. +- */ +-class Driver extends IntegrationTestMixin { +- /** +- * The amount of time to give the server to respond to a shutdown request +- * before forcibly terminating it. +- */ +- static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5); +- +- final Logger logger = new Logger('Driver'); +- +- /** +- * The diagnostic port for Analysis Server or `null` if none. +- */ +- final int diagnosticPort; +- +- /** +- * A flag indicating whether the server is running. +- */ +- bool running = false; +- +- @override +- Server server; +- +- /** +- * The results collected while running analysis server. +- */ +- final Results results = new Results(); +- +- /** +- * The [Completer] for [runComplete]. +- */ +- Completer _runCompleter = new Completer(); +- +- Driver({this.diagnosticPort}); +- +- /** +- * Return a [Future] that completes with the [Results] of running +- * the analysis server once all operations have been performed. +- */ +- Future get runComplete => _runCompleter.future; +- +- /** +- * Perform the given operation. +- * Return a [Future] that completes when the next operation can be performed, +- * or `null` if the next operation can be performed immediately +- */ +- Future perform(Operation op) { +- return op.perform(this); +- } +- +- /** +- * Send a command to the server. An 'id' will be automatically assigned. +- * The returned [Future] will be completed when the server acknowledges the +- * command with a response. If the server acknowledges the command with a +- * normal (non-error) response, the future will be completed with the 'result' +- * field from the response. If the server acknowledges the command with an +- * error response, the future will be completed with an error. +- */ +- Future> send( +- String method, Map params) { +- return server.send(method, params); +- } +- +- /** +- * Launch the analysis server. +- * Return a [Future] that completes when analysis server has started. +- */ +- Future startServer() async { +- logger.log(Level.FINE, 'starting server'); +- initializeInttestMixin(); +- server = new Server(); +- Completer serverConnected = new Completer(); +- onServerConnected.listen((_) { +- logger.log(Level.FINE, 'connected to server'); +- serverConnected.complete(); +- }); +- running = true; +- return server +- .start(diagnosticPort: diagnosticPort /*profileServer: true*/) +- .then((params) { +- server.listenToOutput(dispatchNotification); +- server.exitCode.then((_) { +- logger.log(Level.FINE, 'server stopped'); +- running = false; +- _resultsReady(); +- }); +- return serverConnected.future; +- }); +- } +- +- /** +- * Shutdown the analysis server if it is running. +- */ +- Future stopServer([Duration timeout = SHUTDOWN_TIMEOUT]) async { +- if (running) { +- logger.log(Level.FINE, 'requesting server shutdown'); +- // Give the server a short time to comply with the shutdown request; if it +- // doesn't exit, then forcibly terminate it. +- sendServerShutdown(); +- await server.exitCode.timeout(timeout, onTimeout: () { +- return server.kill('server failed to exit'); +- }); +- } +- _resultsReady(); +- } +- +- /** +- * If not already complete, signal the completer with the collected results. +- */ +- void _resultsReady() { +- if (!_runCompleter.isCompleted) { +- _runCompleter.complete(results); +- } +- } +-} +- +-/** +- * [Measurement] tracks elapsed time for a given operation. +- */ +-class Measurement { +- final String tag; +- final bool notification; +- final List elapsedTimes = new List(); +- int errorCount = 0; +- int unexpectedResultCount = 0; +- +- Measurement(this.tag, this.notification); +- +- int get count => elapsedTimes.length; +- +- void printSummary(int keyLen) { +- int count = 0; +- Duration maxTime = elapsedTimes[0]; +- Duration minTime = elapsedTimes[0]; +- int totalTimeMicros = 0; +- for (Duration elapsed in elapsedTimes) { +- ++count; +- int timeMicros = elapsed.inMicroseconds; +- maxTime = maxTime.compareTo(elapsed) > 0 ? maxTime : elapsed; +- minTime = minTime.compareTo(elapsed) < 0 ? minTime : elapsed; +- totalTimeMicros += timeMicros; +- } +- int meanTime = (totalTimeMicros / count).round(); +- List sorted = elapsedTimes.toList()..sort(); +- Duration time90th = sorted[(sorted.length * 0.90).round() - 1]; +- Duration time99th = sorted[(sorted.length * 0.99).round() - 1]; +- int differenceFromMeanSquared = 0; +- for (Duration elapsed in elapsedTimes) { +- int timeMicros = elapsed.inMicroseconds; +- int differenceFromMean = timeMicros - meanTime; +- differenceFromMeanSquared += differenceFromMean * differenceFromMean; +- } +- double variance = differenceFromMeanSquared / count; +- int standardDeviation = sqrt(variance).round(); +- +- StringBuffer sb = new StringBuffer(); +- _printColumn(sb, tag, keyLen); +- _printColumn(sb, count.toString(), 6, rightJustified: true); +- _printColumn(sb, errorCount.toString(), 6, rightJustified: true); +- _printColumn(sb, unexpectedResultCount.toString(), 6, rightJustified: true); +- _printDuration(sb, new Duration(microseconds: meanTime)); +- _printDuration(sb, time90th); +- _printDuration(sb, time99th); +- _printDuration(sb, new Duration(microseconds: standardDeviation)); +- _printDuration(sb, minTime); +- _printDuration(sb, maxTime); +- _printDuration(sb, new Duration(microseconds: totalTimeMicros)); +- print(sb.toString()); +- } +- +- void record(bool success, Duration elapsed) { +- if (!success) { +- ++errorCount; +- } +- elapsedTimes.add(elapsed); +- } +- +- void recordUnexpectedResults() { +- ++unexpectedResultCount; +- } +- +- void _printDuration(StringBuffer sb, Duration duration) { +- _printColumn(sb, duration.inMilliseconds.toString(), 15, +- rightJustified: true); +- } +-} +- +-/** +- * [Results] contains information gathered by [Driver] +- * while running the analysis server +- */ +-class Results { +- Map measurements = new Map(); +- +- /** +- * Display results on stdout. +- */ +- void printResults() { +- print(''); +- print('=================================================================='); +- print(''); +- List keys = measurements.keys.toList()..sort(); +- int keyLen = keys.fold(0, (int len, String key) => max(len, key.length)); +- _printGroupHeader('Request/Response', keyLen); +- int totalCount = 0; +- int totalErrorCount = 0; +- int totalUnexpectedResultCount = 0; +- for (String tag in keys) { +- Measurement m = measurements[tag]; +- if (!m.notification) { +- m.printSummary(keyLen); +- totalCount += m.count; +- totalErrorCount += m.errorCount; +- totalUnexpectedResultCount += m.unexpectedResultCount; +- } +- } +- _printTotals( +- keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount); +- print(''); +- _printGroupHeader('Notifications', keyLen); +- for (String tag in keys) { +- Measurement m = measurements[tag]; +- if (m.notification) { +- m.printSummary(keyLen); +- } +- } +- +- /// TODO(danrubel) *** print warnings if driver caches are not empty **** +- print(''' +- +-(1) uxr = UneXpected Results or responses received from the server +- that do not match the recorded response for that request. +-(2) all times in milliseconds'''); +- } +- +- /** +- * Record the elapsed time for the given operation. +- */ +- void record(String tag, Duration elapsed, +- {bool notification: false, bool success: true}) { +- Measurement measurement = measurements[tag]; +- if (measurement == null) { +- measurement = new Measurement(tag, notification); +- measurements[tag] = measurement; +- } +- measurement.record(success, elapsed); +- } +- +- void recordUnexpectedResults(String tag) { +- measurements[tag].recordUnexpectedResults(); +- } +- +- void _printGroupHeader(String groupName, int keyLen) { +- StringBuffer sb = new StringBuffer(); +- _printColumn(sb, groupName, keyLen); +- _printColumn(sb, 'count', 6, rightJustified: true); +- _printColumn(sb, 'error', 6, rightJustified: true); +- _printColumn(sb, 'uxr(1)', 6, rightJustified: true); +- sb.write(' '); +- _printColumn(sb, 'mean(2)', 15); +- _printColumn(sb, '90th', 15); +- _printColumn(sb, '99th', 15); +- _printColumn(sb, 'std-dev', 15); +- _printColumn(sb, 'minimum', 15); +- _printColumn(sb, 'maximum', 15); +- _printColumn(sb, 'total', 15); +- print(sb.toString()); +- } +- +- void _printTotals(int keyLen, int totalCount, int totalErrorCount, +- int totalUnexpectedResultCount) { +- StringBuffer sb = new StringBuffer(); +- _printColumn(sb, 'Totals', keyLen); +- _printColumn(sb, totalCount.toString(), 6, rightJustified: true); +- _printColumn(sb, totalErrorCount.toString(), 6, rightJustified: true); +- _printColumn(sb, totalUnexpectedResultCount.toString(), 6, +- rightJustified: true); +- print(sb.toString()); +- } +-} +diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart +deleted file mode 100644 +index 70999d504aa..00000000000 +--- a/pkg/analysis_server/benchmark/integration/input_converter.dart ++++ /dev/null +@@ -1,399 +0,0 @@ +-// Copyright (c) 2015, 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:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:logging/logging.dart'; +-import 'package:path/path.dart' as path; +- +-import 'instrumentation_input_converter.dart'; +-import 'log_file_input_converter.dart'; +-import 'operation.dart'; +- +-/** +- * Common input converter superclass for sharing implementation. +- */ +-abstract class CommonInputConverter extends Converter { +- static final ERROR_PREFIX = 'Server responded with an error: '; +- final Logger logger = new Logger('InstrumentationInputConverter'); +- final Set eventsSeen = new Set(); +- +- /** +- * A mapping from request/response id to request json +- * for those requests for which a response has not been processed. +- */ +- final Map requestMap = {}; +- +- /** +- * A mapping from request/response id to a completer +- * for those requests for which a response has not been processed. +- * The completer is called with the actual json response +- * when it becomes available. +- */ +- final Map responseCompleters = {}; +- +- /** +- * A mapping from request/response id to the actual response result +- * for those responses that have not been processed. +- */ +- final Map responseMap = {}; +- +- /** +- * A mapping of current overlay content +- * parallel to what is in the analysis server +- * so that we can update the file system. +- */ +- final Map overlays = {}; +- +- /** +- * The prefix used to determine if a request parameter is a file path. +- */ +- final String rootPrefix = path.rootPrefix(path.current); +- +- /** +- * A mapping of source path prefixes +- * from location where instrumentation or log file was generated +- * to the target location of the source using during performance measurement. +- */ +- final PathMap srcPathMap; +- +- /** +- * The root directory for all source being modified +- * during performance measurement. +- */ +- final String tmpSrcDirPath; +- +- CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap); +- +- Map asMap(dynamic value) => value as Map; +- +- /** +- * Return an operation for the notification or `null` if none. +- */ +- Operation convertNotification(Map json) { +- String event = json['event']; +- if (event == SERVER_NOTIFICATION_STATUS) { +- // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}} +- Map params = asMap(json['params']); +- if (params != null) { +- Map analysis = asMap(params['analysis']); +- if (analysis != null && analysis['isAnalyzing'] == false) { +- return new WaitForAnalysisCompleteOperation(); +- } +- } +- } +- if (event == SERVER_NOTIFICATION_CONNECTED) { +- // {"event":"server.connected","params":{"version":"1.7.0"}} +- return new StartServerOperation(); +- } +- if (eventsSeen.add(event)) { +- logger.log(Level.INFO, 'Ignored notification: $event\n $json'); +- } +- return null; +- } +- +- /** +- * Return an operation for the request or `null` if none. +- */ +- Operation convertRequest(Map origJson) { +- Map json = asMap(translateSrcPaths(origJson)); +- requestMap[json['id']] = json; +- String method = json['method']; +- // Sanity check operations that modify source +- // to ensure that the operation is on source in temp space +- if (method == ANALYSIS_REQUEST_UPDATE_CONTENT) { +- // Track overlays in parallel with the analysis server +- // so that when an overlay is removed, the file can be updated on disk +- Request request = new Request.fromJson(json); +- var params = new AnalysisUpdateContentParams.fromRequest(request); +- params.files.forEach((String filePath, change) { +- if (change is AddContentOverlay) { +- String content = change.content; +- if (content == null) { +- throw 'expected new overlay content\n$json'; +- } +- overlays[filePath] = content; +- } else if (change is ChangeContentOverlay) { +- String content = overlays[filePath]; +- if (content == null) { +- throw 'expected cached overlay content\n$json'; +- } +- overlays[filePath] = SourceEdit.applySequence(content, change.edits); +- } else if (change is RemoveContentOverlay) { +- String content = overlays.remove(filePath); +- if (content == null) { +- throw 'expected cached overlay content\n$json'; +- } +- if (!path.isWithin(tmpSrcDirPath, filePath)) { +- throw 'found path referencing source outside temp space\n$filePath\n$json'; +- } +- new File(filePath).writeAsStringSync(content); +- } else { +- throw 'unknown overlay change $change\n$json'; +- } +- }); +- return new RequestOperation(this, json); +- } +- // Track performance for completion notifications +- if (method == COMPLETION_REQUEST_GET_SUGGESTIONS) { +- return new CompletionRequestOperation(this, json); +- } +- // TODO(danrubel) replace this with code +- // that just forwards the translated request +- if (method == ANALYSIS_REQUEST_GET_HOVER || +- method == ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS || +- method == ANALYSIS_REQUEST_SET_PRIORITY_FILES || +- method == ANALYSIS_REQUEST_SET_SUBSCRIPTIONS || +- method == ANALYSIS_REQUEST_UPDATE_OPTIONS || +- method == EDIT_REQUEST_GET_ASSISTS || +- method == EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS || +- method == EDIT_REQUEST_GET_FIXES || +- method == EDIT_REQUEST_GET_REFACTORING || +- method == EDIT_REQUEST_SORT_MEMBERS || +- method == EXECUTION_REQUEST_CREATE_CONTEXT || +- method == EXECUTION_REQUEST_DELETE_CONTEXT || +- method == EXECUTION_REQUEST_MAP_URI || +- method == EXECUTION_REQUEST_SET_SUBSCRIPTIONS || +- method == SEARCH_REQUEST_FIND_ELEMENT_REFERENCES || +- method == SEARCH_REQUEST_FIND_MEMBER_DECLARATIONS || +- method == SERVER_REQUEST_GET_VERSION || +- method == SERVER_REQUEST_SET_SUBSCRIPTIONS) { +- return new RequestOperation(this, json); +- } +- throw 'unknown request: $method\n $json'; +- } +- +- /** +- * Return an operation for the recorded/expected response. +- */ +- Operation convertResponse(Map json) { +- return new ResponseOperation(this, asMap(requestMap.remove(json['id'])), +- asMap(translateSrcPaths(json))); +- } +- +- void logOverlayContent() { +- logger.log(Level.WARNING, '${overlays.length} overlays'); +- List allPaths = overlays.keys.toList()..sort(); +- for (String filePath in allPaths) { +- logger.log(Level.WARNING, 'overlay $filePath\n${overlays[filePath]}'); +- } +- } +- +- /** +- * Process an error response from the server by either +- * completing the associated completer in the [responseCompleters] +- * or stashing it in [responseMap] if no completer exists. +- */ +- void processErrorResponse(String id, exception) { +- var result = exception; +- if (exception is UnimplementedError) { +- if (exception.message.startsWith(ERROR_PREFIX)) { +- result = JSON.decode(exception.message.substring(ERROR_PREFIX.length)); +- } +- } +- processResponseResult(id, result); +- } +- +- /** +- * Process the expected response by completing the given completer +- * with the result if it has already been received, +- * or caching the completer to be completed when the server +- * returns the associated result. +- * Return a future that completes when the response is received +- * or `null` if the response has already been received +- * and the completer completed. +- */ +- Future processExpectedResponse(String id, Completer completer) { +- if (responseMap.containsKey(id)) { +- logger.log(Level.INFO, 'processing cached response $id'); +- completer.complete(responseMap.remove(id)); +- return null; +- } else { +- logger.log(Level.INFO, 'waiting for response $id'); +- responseCompleters[id] = completer; +- return completer.future; +- } +- } +- +- /** +- * Process a success response result from the server by either +- * completing the associated completer in the [responseCompleters] +- * or stashing it in [responseMap] if no completer exists. +- * The response result may be `null`. +- */ +- void processResponseResult(String id, result) { +- Completer completer = responseCompleters[id]; +- if (completer != null) { +- logger.log(Level.INFO, 'processing response $id'); +- completer.complete(result); +- } else { +- logger.log(Level.INFO, 'caching response $id'); +- responseMap[id] = result; +- } +- } +- +- /** +- * Recursively translate source paths in the specified JSON to reference +- * the temporary source used during performance measurement rather than +- * the original source when the instrumentation or log file was generated. +- */ +- translateSrcPaths(json) { +- if (json is String) { +- return srcPathMap.translate(json); +- } +- if (json is List) { +- List result = []; +- for (int i = 0; i < json.length; ++i) { +- result.add(translateSrcPaths(json[i])); +- } +- return result; +- } +- if (json is Map) { +- Map result = new Map(); +- json.forEach((origKey, value) { +- result[translateSrcPaths(origKey)] = translateSrcPaths(value); +- }); +- return result; +- } +- return json; +- } +-} +- +-/** +- * [InputConverter] converts an input stream +- * into a series of operations to be sent to the analysis server. +- * The input stream can be either an instrumentation or log file. +- */ +-class InputConverter extends Converter { +- final Logger logger = new Logger('InputConverter'); +- +- /** +- * A mapping of source path prefixes +- * from location where instrumentation or log file was generated +- * to the target location of the source using during performance measurement. +- */ +- final PathMap srcPathMap; +- +- /** +- * The root directory for all source being modified +- * during performance measurement. +- */ +- final String tmpSrcDirPath; +- +- /** +- * The number of lines read before the underlying converter was determined +- * or the end of file was reached. +- */ +- int headerLineCount = 0; +- +- /** +- * The underlying converter used to translate lines into operations +- * or `null` if it has not yet been determined. +- */ +- Converter converter; +- +- /** +- * [active] is `true` if converting lines to operations +- * or `false` if an exception has occurred. +- */ +- bool active = true; +- +- InputConverter(this.tmpSrcDirPath, this.srcPathMap); +- +- @override +- Operation convert(String line) { +- if (!active) { +- return null; +- } +- if (converter != null) { +- try { +- return converter.convert(line); +- } catch (e) { +- active = false; +- rethrow; +- } +- } +- if (headerLineCount == 20) { +- throw 'Failed to determine input file format'; +- } +- if (InstrumentationInputConverter.isFormat(line)) { +- converter = new InstrumentationInputConverter(tmpSrcDirPath, srcPathMap); +- } else if (LogFileInputConverter.isFormat(line)) { +- converter = new LogFileInputConverter(tmpSrcDirPath, srcPathMap); +- } +- if (converter != null) { +- return converter.convert(line); +- } +- logger.log(Level.INFO, 'skipped input line: $line'); +- return null; +- } +- +- @override +- _InputSink startChunkedConversion(outSink) { +- return new _InputSink(this, outSink); +- } +-} +- +-/** +- * A container of [PathMapEntry]s used to translate a source path in the log +- * before it is sent to the analysis server. +- */ +-class PathMap { +- final List entries = []; +- +- void add(String oldSrcPrefix, String newSrcPrefix) { +- entries.add(new PathMapEntry(oldSrcPrefix, newSrcPrefix)); +- } +- +- String translate(String original) { +- String result = original; +- for (PathMapEntry entry in entries) { +- result = entry.translate(result); +- } +- return result; +- } +-} +- +-/** +- * An entry in [PathMap] used to translate a source path in the log +- * before it is sent to the analysis server. +- */ +-class PathMapEntry { +- final String oldSrcPrefix; +- final String newSrcPrefix; +- +- PathMapEntry(this.oldSrcPrefix, this.newSrcPrefix); +- +- String translate(String original) { +- return original.startsWith(oldSrcPrefix) +- ? '$newSrcPrefix${original.substring(oldSrcPrefix.length)}' +- : original; +- } +-} +- +-class _InputSink extends ChunkedConversionSink { +- final Converter converter; +- final outSink; +- +- _InputSink(this.converter, this.outSink); +- +- @override +- void add(String line) { +- Operation op = converter.convert(line); +- if (op != null) { +- outSink.add(op); +- } +- } +- +- @override +- void close() { +- outSink.close(); +- } +-} +diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart +deleted file mode 100644 +index 7a875942643..00000000000 +--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart ++++ /dev/null +@@ -1,146 +0,0 @@ +-// Copyright (c) 2015, 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:convert'; +- +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:logging/logging.dart'; +- +-import 'input_converter.dart'; +-import 'operation.dart'; +- +-final int COLON = ':'.codeUnitAt(0); +- +-/** +- * [InstrumentationInputConverter] converts an instrumentation stream +- * into a series of operations to be sent to the analysis server. +- */ +-class InstrumentationInputConverter extends CommonInputConverter { +- final Set codesSeen = new Set(); +- +- /** +- * [readBuffer] holds the contents of the file being read from disk +- * as recorded in the instrumentation log +- * or `null` if not converting a "Read" entry. +- */ +- StringBuffer readBuffer = null; +- +- InstrumentationInputConverter(String tmpSrcDirPath, PathMap srcPathMap) +- : super(tmpSrcDirPath, srcPathMap); +- +- @override +- Operation convert(String line) { +- List fields; +- try { +- fields = _parseFields(line); +- if (fields.length < 2) { +- if (readBuffer != null) { +- readBuffer.writeln(fields.length == 1 ? fields[0] : ''); +- return null; +- } +- throw 'Failed to process line:\n$line'; +- } +- if (readBuffer != null) { +- readBuffer = null; +- } +- } catch (e, s) { +- throw new AnalysisException( +- 'Failed to parse line\n$line', new CaughtException(e, s)); +- } +- // int timeStamp = int.parse(fields[0], onError: (_) => -1); +- String opCode = fields[1]; +- if (opCode == InstrumentationService.TAG_NOTIFICATION) { +- return convertNotification(decodeJson(line, fields[2])); +- } else if (opCode == 'Read') { +- // 1434096943209:Read:/some/file/path:1434095535000: +- //String filePath = fields[2]; +- readBuffer = new StringBuffer(fields.length > 4 ? fields[4] : ''); +- return null; +- } else if (opCode == InstrumentationService.TAG_REQUEST) { +- return convertRequest(decodeJson(line, fields[2])); +- } else if (opCode == InstrumentationService.TAG_RESPONSE) { +- // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}} +- return convertResponse(decodeJson(line, fields[2])); +- } else if (opCode == InstrumentationService.TAG_ANALYSIS_TASK) { +- // 1434096943208:Task:/Users/ +- return null; +- } else if (opCode == InstrumentationService.TAG_LOG_ENTRY) { +- // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}} +- return null; +- } else if (opCode == InstrumentationService.TAG_PERFORMANCE) { +- //1434096960092:Perf:analysis_full:16884:context_id=0 +- return null; +- } else if (opCode == InstrumentationService.TAG_SUBPROCESS_START) { +- // 1434096938634:SPStart:0:/Users/da +- return null; +- } else if (opCode == InstrumentationService.TAG_SUBPROCESS_RESULT) { +- // 1434096939068:SPResult:0:0:"{\"packages\"::{\"rpi_lidar\"::\"/Users +- return null; +- } else if (opCode == InstrumentationService.TAG_VERSION) { +- // 1434096937358:Ver:1421765742287333878467:org.dartlang.dartplugin +- return null; +- } else if (opCode == InstrumentationService.TAG_WATCH_EVENT) { +- // 1434097460414:Watch:/some/file/path +- return null; +- } +- if (codesSeen.add(opCode)) { +- logger.log( +- Level.WARNING, 'Ignored instrumentation op code: $opCode\n $line'); +- } +- return null; +- } +- +- Map decodeJson(String line, String text) { +- try { +- return asMap(JSON.decode(text)); +- } catch (e, s) { +- throw new AnalysisException( +- 'Failed to decode JSON: $text\n$line', new CaughtException(e, s)); +- } +- } +- +- /** +- * Determine if the given line is from an instrumentation file. +- * For example: +- * `1433175833005:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.6.2:1.11.0-edge.131698` +- */ +- static bool isFormat(String line) { +- List fields = _parseFields(line); +- if (fields.length < 2) return false; +- int timeStamp = int.parse(fields[0], onError: (_) => -1); +- String opCode = fields[1]; +- return timeStamp > 0 && opCode == 'Ver'; +- } +- +- /** +- * Extract fields from the given [line]. +- */ +- static List _parseFields(String line) { +- List fields = new List(); +- int index = 0; +- StringBuffer sb = new StringBuffer(); +- while (index < line.length) { +- int code = line.codeUnitAt(index); +- if (code == COLON) { +- // Embedded colons are doubled +- int next = index + 1; +- if (next < line.length && line.codeUnitAt(next) == COLON) { +- sb.write(':'); +- ++index; +- } else { +- fields.add(sb.toString()); +- sb.clear(); +- } +- } else { +- sb.writeCharCode(code); +- } +- ++index; +- } +- if (sb.isNotEmpty) { +- fields.add(sb.toString()); +- } +- return fields; +- } +-} +diff --git a/pkg/analysis_server/benchmark/integration/local_runner.dart b/pkg/analysis_server/benchmark/integration/local_runner.dart +deleted file mode 100644 +index 28ef5bb9136..00000000000 +--- a/pkg/analysis_server/benchmark/integration/local_runner.dart ++++ /dev/null +@@ -1,91 +0,0 @@ +-// Copyright (c) 2015, 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:io'; +- +-import 'package:path/path.dart'; +- +-import 'main.dart' as performance; +- +-// Local driver for performance measurement +- +-main(List args) { +- /* +- * Parse arguments +- */ +- if (args.length < 3) printHelp('Expected 3 arguments'); +- var gitDir = new Directory(args[0]); +- if (!gitDir.existsSync()) printHelp('${gitDir.path} does not exist'); +- if (!new Directory(join(gitDir.path, '.git')).existsSync()) +- printHelp('${gitDir.path} does not appear to be a local git repository'); +- var branch = args[1]; +- var inputFile = new File(args[2]); +- if (!inputFile.existsSync()) printHelp('${inputFile.path} does not exist'); +- /* +- * Create a new temp directory +- */ +- var tmpDir = new Directory( +- join(Directory.systemTemp.path, 'analysis_server_perf_target')); +- if (!tmpDir.path.contains('tmp')) throw 'invalid tmp directory\n $tmpDir'; +- print('Extracting target analysis environment into\n ${tmpDir.path}'); +- if (tmpDir.existsSync()) tmpDir.deleteSync(recursive: true); +- tmpDir.createSync(recursive: true); +- /* +- * Setup the initial target source in the temp directory +- */ +- var tarFilePath = join(tmpDir.path, 'targetSrc.tar'); +- var result = Process.runSync('git', ['archive', branch, '-o', tarFilePath], +- workingDirectory: gitDir.path); +- if (result.exitCode != 0) throw 'failed to obtain target source: $result'; +- var tmpSrcDirPath = join(tmpDir.path, 'targetSrc'); +- new Directory(tmpSrcDirPath).createSync(); +- result = Process.runSync('tar', ['-xf', tarFilePath], +- workingDirectory: tmpSrcDirPath); +- if (result.exitCode != 0) throw 'failed to extract target source: $result'; +- /* +- * Symlink the out or xcodebuild directory +- */ +- var outDirName = 'out'; +- if (!new Directory(join(gitDir.path, outDirName)).existsSync()) { +- outDirName = 'xcodebuild'; +- } +- if (!new Directory(join(gitDir.path, outDirName)).existsSync()) { +- throw 'failed to find out or xcodebuild directory'; +- } +- result = Process.runSync('ln', +- ['-s', join(gitDir.path, outDirName), join(tmpSrcDirPath, outDirName)]); +- if (result.exitCode != 0) throw 'failed to link out or xcodebuild: $result'; +- /* +- * Collect arguments +- */ +- var perfArgs = [ +- '-i${inputFile.path}', +- '-t$tmpSrcDirPath', +- ]; +- for (int index = 3; index < args.length; ++index) { +- perfArgs.add(args[index].replaceAll('@tmpSrcDir@', tmpSrcDirPath)); +- } +- perfArgs.add('-m${gitDir.path},$tmpSrcDirPath'); +- /* +- * Launch the performance analysis tool +- */ +- performance.main(perfArgs); +-} +- +-/// Print help and exit +-void printHelp([String errMsg]) { +- if (errMsg != null) { +- print(''); +- print('Error: $errMsg'); +- print(''); +- } +- print('''Required arguments: +-gitDir = a path to the git repository containing the initial target source +-branch = the branch containing the initial target source +-inputFile = the instrumentation or log file +- +-Optional arguments:'''); +- print(performance.argParser.usage); +- exit(1); +-} +diff --git a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart +deleted file mode 100644 +index 79d3d6e955c..00000000000 +--- a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart ++++ /dev/null +@@ -1,82 +0,0 @@ +-// Copyright (c) 2015, 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:convert'; +- +-import 'package:analyzer/exception/exception.dart'; +-import 'package:logging/logging.dart'; +- +-import 'input_converter.dart'; +-import 'operation.dart'; +- +-const CONNECTED_MSG_FRAGMENT = ' <= {"event":"server.connected"'; +-const RECEIVED_FRAGMENT = ' <= {'; +-const SENT_FRAGMENT = ' => {'; +-final int NINE = '9'.codeUnitAt(0); +-final int ZERO = '0'.codeUnitAt(0); +- +-/** +- * [LogFileInputConverter] converts a log file stream +- * into a series of operations to be sent to the analysis server. +- */ +-class LogFileInputConverter extends CommonInputConverter { +- LogFileInputConverter(String tmpSrcDirPath, PathMap srcPathMap) +- : super(tmpSrcDirPath, srcPathMap); +- +- @override +- Operation convert(String line) { +- try { +- String timeStampString = _parseTimeStamp(line); +- String data = line.substring(timeStampString.length); +- if (data.startsWith(RECEIVED_FRAGMENT)) { +- Map json = asMap(JSON.decode(data.substring(4))); +- if (json.containsKey('event')) { +- return convertNotification(json); +- } else { +- return convertResponse(json); +- } +- } else if (data.startsWith(SENT_FRAGMENT)) { +- Map json = asMap(JSON.decode(data.substring(4))); +- if (json.containsKey('method')) { +- return convertRequest(json); +- } +- return null; +- } +- logger.log(Level.INFO, 'unknown input line: $line'); +- return null; +- } catch (e, s) { +- throw new AnalysisException( +- 'Failed to parse line\n $line', new CaughtException(e, s)); +- } +- } +- +- /** +- * Determine if the given line is from an instrumentation file. +- * For example: +- * `1428347977499 <= {"event":"server.connected","params":{"version":"1.6.0"}}` +- */ +- static bool isFormat(String line) { +- String timeStampString = _parseTimeStamp(line); +- int start = timeStampString.length; +- int end = start + CONNECTED_MSG_FRAGMENT.length; +- return (10 < start && end < line.length) && +- line.substring(start, end) == CONNECTED_MSG_FRAGMENT; +- } +- +- /** +- * Parse the given line and return the millisecond timestamp or `null` +- * if it cannot be determined. +- */ +- static String _parseTimeStamp(String line) { +- int index = 0; +- while (index < line.length) { +- int code = line.codeUnitAt(index); +- if (code < ZERO || NINE < code) { +- return line.substring(0, index); +- } +- ++index; +- } +- return line; +- } +-} +diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart +deleted file mode 100644 +index 0760b171fab..00000000000 +--- a/pkg/analysis_server/benchmark/integration/main.dart ++++ /dev/null +@@ -1,246 +0,0 @@ +-// Copyright (c) 2015, 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:convert'; +-import 'dart:io'; +- +-import 'package:args/args.dart'; +-import 'package:logging/logging.dart'; +-import 'package:path/path.dart' as path; +- +-import 'driver.dart'; +-import 'input_converter.dart'; +-import 'operation.dart'; +- +-/** +- * Launch and interact with the analysis server. +- */ +-main(List rawArgs) { +- Logger logger = new Logger('Performance Measurement Client'); +- logger.onRecord.listen((LogRecord rec) { +- print(rec.message); +- }); +- PerfArgs args = parseArgs(rawArgs); +- +- Driver driver = new Driver(diagnosticPort: args.diagnosticPort); +- Stream stream = openInput(args); +- StreamSubscription subscription; +- subscription = stream.listen((Operation op) { +- Future future = driver.perform(op); +- if (future != null) { +- logger.log(Level.FINE, 'pausing operations for ${op.runtimeType}'); +- subscription.pause(future.then((_) { +- logger.log(Level.FINE, 'resuming operations'); +- })); +- } +- }, onDone: () { +- subscription.cancel(); +- driver.stopServer(SHUTDOWN_TIMEOUT); +- }, onError: (e, s) { +- subscription.cancel(); +- logger.log(Level.SEVERE, '$e\n$s'); +- driver.stopServer(SHUTDOWN_TIMEOUT); +- }); +- driver.runComplete.then((Results results) { +- results.printResults(); +- }).whenComplete(() { +- return subscription.cancel(); +- }); +-} +- +-const DIAGNOSTIC_PORT_OPTION = 'diagnosticPort'; +-const HELP_CMDLINE_OPTION = 'help'; +-const INPUT_CMDLINE_OPTION = 'input'; +-const MAP_OPTION = 'map'; +- +-/** +- * The amount of time to give the server to respond to a shutdown request +- * before forcibly terminating it. +- */ +-const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 25); +- +-const TMP_SRC_DIR_OPTION = 'tmpSrcDir'; +-const VERBOSE_CMDLINE_OPTION = 'verbose'; +-const VERY_VERBOSE_CMDLINE_OPTION = 'vv'; +- +-ArgParser _argParser; +- +-ArgParser get argParser { +- _argParser = new ArgParser(); +- +- _argParser.addOption(INPUT_CMDLINE_OPTION, +- abbr: 'i', +- help: '\n' +- 'The input file specifying how this client should interact with the server.\n' +- 'If the input file name is "stdin", then the instructions are read from standard input.'); +- _argParser.addOption(MAP_OPTION, +- abbr: 'm', +- allowMultiple: true, +- splitCommas: false, +- help: ',\n' +- 'This option defines a mapping from the original source directory \n' +- 'when the instrumentation or log file was generated\n' +- 'to the target source directory used during performance testing.\n' +- 'Multiple mappings can be specified.\n' +- 'WARNING: The contents of the target directory will be modified'); +- _argParser.addOption(TMP_SRC_DIR_OPTION, +- abbr: 't', +- help: '\n' +- 'The temporary directory containing source used during performance measurement.\n' +- 'WARNING: The contents of the target directory will be modified'); +- _argParser.addOption(DIAGNOSTIC_PORT_OPTION, +- abbr: 'd', +- help: 'localhost port on which server will provide diagnostic web pages'); +- _argParser.addFlag(VERBOSE_CMDLINE_OPTION, +- abbr: 'v', help: 'Verbose logging', negatable: false); +- _argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION, +- help: 'Extra verbose logging', negatable: false); +- _argParser.addFlag(HELP_CMDLINE_OPTION, +- abbr: 'h', help: 'Print this help information', negatable: false); +- return _argParser; +-} +- +-/** +- * Open and return the input stream specifying how this client +- * should interact with the analysis server. +- */ +-Stream openInput(PerfArgs args) { +- var logger = new Logger('openInput'); +- Stream> inputRaw; +- if (args.inputPath == 'stdin') { +- inputRaw = stdin; +- } else { +- inputRaw = new File(args.inputPath).openRead(); +- } +- for (PathMapEntry entry in args.srcPathMap.entries) { +- logger.log( +- Level.INFO, +- 'mapping source path\n' +- ' from ${entry.oldSrcPrefix}\n to ${entry.newSrcPrefix}'); +- } +- logger.log(Level.INFO, 'tmpSrcDir: ${args.tmpSrcDirPath}'); +- return inputRaw +- .transform(SYSTEM_ENCODING.decoder) +- .transform(new LineSplitter()) +- .transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap)); +-} +- +-/** +- * Parse the command line arguments. +- */ +-PerfArgs parseArgs(List rawArgs) { +- ArgResults args; +- PerfArgs perfArgs = new PerfArgs(); +- try { +- args = argParser.parse(rawArgs); +- } on Exception catch (e) { +- print(e); +- printHelp(); +- exit(1); +- } +- +- bool showHelp = args[HELP_CMDLINE_OPTION] || args.rest.isNotEmpty; +- +- bool isMissing(key) => args[key] == null || args[key].isEmpty; +- +- perfArgs.inputPath = args[INPUT_CMDLINE_OPTION]; +- if (isMissing(INPUT_CMDLINE_OPTION)) { +- print('missing $INPUT_CMDLINE_OPTION argument'); +- showHelp = true; +- } +- +- for (String pair in args[MAP_OPTION]) { +- if (pair is String) { +- int index = pair.indexOf(','); +- if (index != -1 && pair.indexOf(',', index + 1) == -1) { +- String oldSrcPrefix = _withTrailingSeparator(pair.substring(0, index)); +- String newSrcPrefix = _withTrailingSeparator(pair.substring(index + 1)); +- if (new Directory(newSrcPrefix).existsSync()) { +- perfArgs.srcPathMap.add(oldSrcPrefix, newSrcPrefix); +- continue; +- } +- } +- } +- print('must specifiy $MAP_OPTION ,'); +- showHelp = true; +- } +- +- perfArgs.tmpSrcDirPath = _withTrailingSeparator(args[TMP_SRC_DIR_OPTION]); +- if (isMissing(TMP_SRC_DIR_OPTION)) { +- print('missing $TMP_SRC_DIR_OPTION argument'); +- showHelp = true; +- } +- +- String portText = args[DIAGNOSTIC_PORT_OPTION]; +- if (portText != null) { +- perfArgs.diagnosticPort = int.parse(portText, onError: (s) { +- print('invalid $DIAGNOSTIC_PORT_OPTION: $s'); +- showHelp = true; +- }); +- } +- +- if (args[VERY_VERBOSE_CMDLINE_OPTION] || rawArgs.contains('-vv')) { +- Logger.root.level = Level.FINE; +- } else if (args[VERBOSE_CMDLINE_OPTION]) { +- Logger.root.level = Level.INFO; +- } else { +- Logger.root.level = Level.WARNING; +- } +- +- if (showHelp) { +- printHelp(); +- exit(1); +- } +- +- return perfArgs; +-} +- +-void printHelp() { +- print(''); +- print('Launch and interact with the AnalysisServer'); +- print(''); +- print(argParser.usage); +-} +- +-/** +- * Ensure that the given path has a trailing separator +- */ +-String _withTrailingSeparator(String dirPath) { +- if (dirPath != null && dirPath.length > 4) { +- if (!dirPath.endsWith(path.separator)) { +- return '$dirPath${path.separator}'; +- } +- } +- return dirPath; +-} +- +-/** +- * The performance measurement arguments specified on the command line. +- */ +-class PerfArgs { +- /** +- * The file path of the instrumentation or log file +- * used to drive performance measurement, +- * or 'stdin' if this information should be read from standard input. +- */ +- String inputPath; +- +- /** +- * A mapping from the original source directory +- * when the instrumentation or log file was generated +- * to the target source directory used during performance testing. +- */ +- final PathMap srcPathMap = new PathMap(); +- +- /** +- * The temporary directory containing source used during performance measurement. +- */ +- String tmpSrcDirPath; +- +- /** +- * The diagnostic port for Analysis Server or `null` if none. +- */ +- int diagnosticPort; +-} +diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart +deleted file mode 100644 +index 75cf2a7edc9..00000000000 +--- a/pkg/analysis_server/benchmark/integration/operation.dart ++++ /dev/null +@@ -1,236 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:logging/logging.dart'; +- +-import 'driver.dart'; +-import 'input_converter.dart'; +- +-/** +- * A [CompletionRequestOperation] tracks response time along with +- * the first and last completion notifications. +- */ +-class CompletionRequestOperation extends RequestOperation { +- Driver driver; +- StreamSubscription subscription; +- String notificationId; +- Stopwatch stopwatch; +- bool firstNotification = true; +- +- CompletionRequestOperation( +- CommonInputConverter converter, Map json) +- : super(converter, json); +- +- @override +- Future perform(Driver driver) { +- this.driver = driver; +- subscription = driver.onCompletionResults.listen(processNotification); +- return super.perform(driver); +- } +- +- void processNotification(CompletionResultsParams event) { +- if (event.id == notificationId) { +- Duration elapsed = stopwatch.elapsed; +- if (firstNotification) { +- firstNotification = false; +- driver.results.record('completion notification first', elapsed, +- notification: true); +- } +- if (event.isLast) { +- subscription.cancel(); +- driver.results.record('completion notification last', elapsed, +- notification: true); +- } +- } +- } +- +- @override +- void processResult( +- String id, Map result, Stopwatch stopwatch) { +- notificationId = result['id']; +- this.stopwatch = stopwatch; +- super.processResult(id, result, stopwatch); +- } +-} +- +-/** +- * An [Operation] represents an action such as sending a request to the server. +- */ +-abstract class Operation { +- Future perform(Driver driver); +-} +- +-/** +- * A [RequestOperation] sends a [JSON] request to the server. +- */ +-class RequestOperation extends Operation { +- final CommonInputConverter converter; +- final Map json; +- +- RequestOperation(this.converter, this.json); +- +- @override +- Future perform(Driver driver) { +- Stopwatch stopwatch = new Stopwatch(); +- String originalId = json['id']; +- String method = json['method']; +- json['clientRequestTime'] = new DateTime.now().millisecondsSinceEpoch; +- driver.logger.log(Level.FINE, 'Sending request: $method\n $json'); +- stopwatch.start(); +- +- void recordResult(bool success, result) { +- Duration elapsed = stopwatch.elapsed; +- driver.results.record(method, elapsed, success: success); +- driver.logger +- .log(Level.FINE, 'Response received: $method : $elapsed\n $result'); +- } +- +- driver +- .send(method, converter.asMap(json['params'])) +- .then((Map result) { +- recordResult(true, result); +- processResult(originalId, result, stopwatch); +- }).catchError((exception) { +- recordResult(false, exception); +- converter.processErrorResponse(originalId, exception); +- }); +- return null; +- } +- +- void processResult( +- String id, Map result, Stopwatch stopwatch) { +- converter.processResponseResult(id, result); +- } +-} +- +-/** +- * A [ResponseOperation] waits for a [JSON] response from the server. +- */ +-class ResponseOperation extends Operation { +- static final Duration responseTimeout = new Duration(seconds: 60); +- final CommonInputConverter converter; +- final Map requestJson; +- final Map responseJson; +- final Completer completer = new Completer(); +- Driver driver; +- +- ResponseOperation(this.converter, this.requestJson, this.responseJson) { +- completer.future.then(_processResult).timeout(responseTimeout); +- } +- +- @override +- Future perform(Driver driver) { +- this.driver = driver; +- return converter.processExpectedResponse(responseJson['id'], completer); +- } +- +- bool _equal(expectedResult, actualResult) { +- if (expectedResult is Map && actualResult is Map) { +- if (expectedResult.length == actualResult.length) { +- return expectedResult.keys.every((key) { +- return key == +- 'fileStamp' || // fileStamp values will not be the same across runs +- _equal(expectedResult[key], actualResult[key]); +- }); +- } +- } else if (expectedResult is List && actualResult is List) { +- if (expectedResult.length == actualResult.length) { +- for (int i = 0; i < expectedResult.length; ++i) { +- if (!_equal(expectedResult[i], actualResult[i])) { +- return false; +- } +- } +- return true; +- } +- } +- return expectedResult == actualResult; +- } +- +- /** +- * Compare the expected and actual server response result. +- */ +- void _processResult(actualResult) { +- var expectedResult = responseJson['result']; +- if (!_equal(expectedResult, actualResult)) { +- var expectedError = responseJson['error']; +- String format(value) { +- String text = '\n$value'; +- if (text.endsWith('\n')) { +- text = text.substring(0, text.length - 1); +- } +- return text.replaceAll('\n', '\n '); +- } +- +- String message = 'Request:${format(requestJson)}\n' +- 'expected result:${format(expectedResult)}\n' +- 'expected error:${format(expectedError)}\n' +- 'but received:${format(actualResult)}'; +- driver.results.recordUnexpectedResults(requestJson['method']); +- converter.logOverlayContent(); +- if (expectedError == null) { +- converter.logger.log(Level.SEVERE, message); +- } else { +- throw message; +- } +- } +- } +-} +- +-class StartServerOperation extends Operation { +- @override +- Future perform(Driver driver) { +- return driver.startServer(); +- } +-} +- +-class WaitForAnalysisCompleteOperation extends Operation { +- @override +- Future perform(Driver driver) { +- DateTime start = new DateTime.now(); +- driver.logger.log(Level.FINE, 'waiting for analysis to complete'); +- StreamSubscription subscription; +- Timer timer; +- Completer completer = new Completer(); +- bool isAnalyzing = false; +- subscription = driver.onServerStatus.listen((ServerStatusParams params) { +- if (params.analysis != null) { +- if (params.analysis.isAnalyzing) { +- isAnalyzing = true; +- } else { +- subscription.cancel(); +- timer.cancel(); +- DateTime end = new DateTime.now(); +- Duration delta = end.difference(start); +- driver.logger.log(Level.FINE, 'analysis complete after $delta'); +- completer.complete(); +- driver.results.record('analysis complete', delta, notification: true); +- } +- } +- }); +- timer = new Timer.periodic(new Duration(milliseconds: 20), (_) { +- if (!isAnalyzing) { +- // TODO (danrubel) revisit this once source change requests are implemented +- subscription.cancel(); +- timer.cancel(); +- driver.logger.log(Level.INFO, 'analysis never started'); +- completer.complete(); +- return; +- } +- // Timeout if no communication received within the last 60 seconds. +- double currentTime = driver.server.currentElapseTime; +- double lastTime = driver.server.lastCommunicationTime; +- if (currentTime - lastTime > 60) { +- subscription.cancel(); +- timer.cancel(); +- String message = 'gave up waiting for analysis to complete'; +- driver.logger.log(Level.WARNING, message); +- completer.completeError(message); +- } +- }); +- return completer.future; +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart +deleted file mode 100644 +index 79330458007..00000000000 +--- a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart ++++ /dev/null +@@ -1,161 +0,0 @@ +-// Copyright (c) 2015, 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:io'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:args/args.dart'; +-import 'package:test/test.dart'; +- +-import 'performance_tests.dart'; +- +-/** +- * Pass in the directory of the source to be analyzed as option `--source`, +- * optionally specify a priority file with `--priority` and the specific +- * test to run with `--metric`. If no test is specified, the default is +- * `analysis`. +- */ +-main(List arguments) { +- ArgParser parser = _createArgParser(); +- var args = parser.parse(arguments); +- if (args[SOURCE_OPTION] == null) { +- print('path to source directory must be specified'); +- exit(1); +- } +- source = args[SOURCE_OPTION]; +- priorityFile = args[PRIORITY_FILE_OPTION]; +- List names = args[METRIC_NAME_OPTION] as List; +- for (var name in names) { +- metricNames.add(name as String); +- } +- +- var test; +- +- if (metricNames.isEmpty) { +- test = new AnalysisTimingTest(); +- } else { +- test = new SubscriptionTimingTest(); +- } +- +- Future.wait([test.test_timing()]); +-} +- +-const DEFAULT_METRIC = 'analysis'; +-const METRIC_NAME_OPTION = 'metric'; +-const PRIORITY_FILE_OPTION = 'priority'; +-const SOURCE_OPTION = 'source'; +- +-final metricNames = []; +-String priorityFile; +-String source; +- +-ArgParser _createArgParser() => new ArgParser() +- ..addOption(METRIC_NAME_OPTION, +- help: 'metric name (defaults to `analysis`)', allowMultiple: true) +- ..addOption(SOURCE_OPTION, help: 'full path to source directory for analysis') +- ..addOption(PRIORITY_FILE_OPTION, +- help: '(optional) full path to a priority file'); +- +-/** +- * AnalysisTimingTest measures the time taken by the analysis server to fully analyze +- * the given directory. Measurement is started after setting the analysis root, and +- * analysis is considered complete on receiving the `"isAnalyzing": false` message +- * from the analysis server. +- */ +-class AnalysisTimingTest extends AbstractTimingTest { +- Future test_timing() async { +- // Set root after subscribing to avoid empty notifications. +- await init(source); +- +- setAnalysisRoot(); +- stopwatch.start(); +- await analysisFinished; +- print('analysis completed in ${stopwatch.elapsed}'); +- +- await shutdown(); +- } +-} +- +-class Metric { +- List timings = []; +- Stream eventStream; +- AnalysisService service; +- String name; +- Metric(this.name, this.service, this.eventStream); +- String toString() => '$name: $service, ${eventStream.runtimeType}, $timings'; +-} +- +-/** +- * SubscriptionTimingTest measures the time taken by the analysis server to return +- * information for navigation, semantic highlighting, outline, get occurrences, +- * overrides, folding and implemented. These timings are wrt to the specified priority file +- * - the file that is currently opened and has focus in the editor. Measure the time from +- * when the client subscribes for the notifications till there is a response from the server. +- * Does not wait for analysis to be complete before subscribing for notifications. +- */ +-class SubscriptionTimingTest extends AbstractTimingTest { +- List _metrics; +- +- List get metrics => _metrics ??= metricNames.map(getMetric).toList(); +- +- Metric getMetric(String name) { +- switch (name) { +- case 'folding': +- return new Metric(name, AnalysisService.FOLDING, onAnalysisFolding); +- case 'highlighting': +- return new Metric( +- name, AnalysisService.HIGHLIGHTS, onAnalysisHighlights); +- case 'implemented': +- return new Metric( +- name, AnalysisService.IMPLEMENTED, onAnalysisImplemented); +- case 'navigation': +- return new Metric( +- name, AnalysisService.NAVIGATION, onAnalysisNavigation); +- case 'outline': +- return new Metric(name, AnalysisService.OUTLINE, onAnalysisOutline); +- case 'occurences': +- return new Metric( +- name, AnalysisService.OCCURRENCES, onAnalysisOccurrences); +- case 'overrides': +- return new Metric(name, AnalysisService.OVERRIDES, onAnalysisOverrides); +- } +- print('no metric found for $name'); +- exit(1); +- return null; // Won't get here. +- } +- +- Future test_timing() async { +-// debugStdio(); +- +- expect(metrics, isNotEmpty); +- expect(priorityFile, isNotNull, +- reason: 'A priority file must be specified for ' +- '${metrics.first.name} testing.'); +- +- await init(source); +- stopwatch.start(); +- +- metrics.forEach((Metric m) => m.eventStream.listen((_) { +- m.timings.add( +- new Duration(milliseconds: stopwatch.elapsed.inMilliseconds)); +- })); +- +- var subscriptions = >{}; +- metrics.forEach((Metric m) => subscriptions[m.service] = [priorityFile]); +- +- sendAnalysisSetSubscriptions(subscriptions); +- +- // Set root after subscribing to avoid empty notifications. +- setAnalysisRoot(); +- +- sendAnalysisSetPriorityFiles([priorityFile]); +- +- await analysisFinished; +- print('analysis completed in ${stopwatch.elapsed}'); +- metrics.forEach((Metric m) => print('${m.name} timings: ${m.timings}')); +- +- await shutdown(); +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/benchmark_angular.dart b/pkg/analysis_server/benchmark/perf/benchmark_angular.dart +deleted file mode 100644 +index c93138d86ba..00000000000 +--- a/pkg/analysis_server/benchmark/perf/benchmark_angular.dart ++++ /dev/null +@@ -1,115 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +- +-import 'benchmark_scenario.dart'; +-import 'memory_tests.dart'; +- +-main(List args) async { +- int length = args.length; +- if (length < 1) { +- print( +- 'Usage: dart benchmark_local.dart path_to_np8080 (an example ngdart project)' +- ' [benchmark_id]'); +- return; +- } +- paths = new PathHolder(projectPath: args[0]); +- String id = args.length >= 2 ? args[1] : null; +- if (id == null) { +- for (String id in benchmarks.keys) { +- BenchmarkFunction benchmark = benchmarks[id]; +- await benchmark(id); +- } +- } else { +- BenchmarkFunction benchmark = benchmarks[id]; +- if (benchmark != null) { +- benchmark(id); +- } +- } +-} +- +-const Map benchmarks = +- const { +- 'ng-initialAnalysis': run_ng_initialAnalysis, +- 'ng-change-dart': run_ng_change_dart, +- 'ng-change-html': run_ng_change_html, +- 'ng-memory-initialAnalysis': run_ng_memory_initialAnalysis, +-}; +- +-PathHolder paths; +- +-Future run_ng_change_dart(String id) async { +- String description = r''' +-1. Open 'packages/np8080'. +-2. Add an @Output to the class +-3. Measure the time to finish analysis. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- List times = await new BenchmarkScenario().waitAnalyze_change_analyze( +- roots: [paths.packageNp8080], +- file: paths.editorDart, +- fileChange: new FileChange( +- afterStr: 'showPreview = false;', +- insertStr: '@Output() EventEmitter myEventEmitter;'), +- numOfRepeats: 10); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_ng_change_html(String id) async { +- String description = r''' +-1. Open 'packages/np8080'. +-2. Change the contents of a mustache +-3. Measure the time to finish analysis. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- List times = await new BenchmarkScenario().waitAnalyze_change_analyze( +- roots: [paths.packageNp8080], +- file: paths.editorHtml, +- fileChange: new FileChange( +- afterStr: 'note.lastModified', afterStrBack: 4, insertStr: 'NewName'), +- numOfRepeats: 4); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_ng_initialAnalysis(String id) async { +- String description = r''' +-1. Start server, set 'package/np8080' analysis roots. +-2. Measure the time to finish initial analysis. +-3. Shutdown the server. +-4. Go to (1). +-'''; +- List times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown( +- roots: [paths.packageNp8080], numOfRepeats: 5); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_ng_memory_initialAnalysis(String id) async { +- String description = r''' +-1. Start server, set 'package/np8080' as the analysis root. +-2. Measure the memory usage after finishing initial analysis. +-3. Shutdown the server. +-4. Go to (1). +-'''; +- List sizes = await AnalysisServerMemoryUsageTest +- .start_waitInitialAnalysis_shutdown( +- roots: [paths.packageNp8080], numOfRepeats: 3); +- printMemoryResults(id, description, sizes); +-} +- +-typedef BenchmarkFunction(String id); +- +-class PathHolder { +- String editorHtml; +- String editorDart; +- String packageNp8080; +- +- PathHolder({String projectPath}) { +- editorHtml = '$projectPath/lib/editor/editor_component.html'; +- editorDart = '$projectPath/lib/editor/editor_component.dart'; +- packageNp8080 = projectPath; +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart b/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart +deleted file mode 100644 +index 2e47a2b3bf8..00000000000 +--- a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart ++++ /dev/null +@@ -1,216 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-import 'benchmark_scenario.dart'; +-import 'memory_tests.dart'; +- +-main(List args) async { +- int length = args.length; +- if (length < 1) { +- print('Usage: dart benchmark_local.dart path_to_flutter_checkout' +- ' [benchmark_id]'); +- return; +- } +- paths = new PathHolder(flutterPath: args[0]); +- String id = args.length >= 2 ? args[1] : null; +- if (id == null) { +- for (String id in benchmarks.keys) { +- BenchmarkFunction benchmark = benchmarks[id]; +- await benchmark(id); +- } +- } else { +- BenchmarkFunction benchmark = benchmarks[id]; +- if (benchmark != null) { +- benchmark(id); +- } +- } +-} +- +-const Map benchmarks = +- const { +- 'flutter-initialAnalysis-1': run_flutter_initialAnalysis_1, +- 'flutter-initialAnalysis-2': run_flutter_initialAnalysis_2, +- 'flutter-change-1': run_flutter_change_1, +- 'flutter-change-2': run_flutter_change_2, +- 'flutter-completion-1': run_flutter_completion_1, +- 'flutter-completion-2': run_flutter_completion_2, +- 'flutter-refactoring-1': run_flutter_refactoring_1, +- 'flutter-memory-initialAnalysis-1': run_flutter_memory_initialAnalysis_1, +- 'flutter-memory-initialAnalysis-2': run_flutter_memory_initialAnalysis_2, +-}; +- +-PathHolder paths; +- +-Future run_flutter_change_1(String id) async { +- String description = r''' +-1. Open 'packages/flutter'. +-2. Change a method body in lib/src/painting/colors.dart +-3. Measure the time to finish analysis. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- List times = await new BenchmarkScenario().waitAnalyze_change_analyze( +- roots: [paths.packageFlutter], +- file: '${paths.packageFlutter}/lib/src/painting/colors.dart', +- fileChange: new FileChange( +- afterStr: 'final double h = hue % 360;', insertStr: 'print(12345);'), +- numOfRepeats: 10); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_flutter_change_2(String id) async { +- String description = r''' +-1. Open 'packages/flutter'. +-2. Change the name of a public method in lib/src/painting/colors.dart +-3. Measure the time to finish analysis. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- List times = await new BenchmarkScenario().waitAnalyze_change_analyze( +- roots: [paths.packageFlutter], +- file: '${paths.packageFlutter}/lib/src/painting/colors.dart', +- fileChange: new FileChange( +- afterStr: 'withValue(dou', afterStrBack: 4, insertStr: 'NewName'), +- numOfRepeats: 5); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_flutter_completion_1(String id) async { +- String description = r''' +-1. Open 'packages/flutter'. +-2. Change a method body in packages/flutter/lib/src/material/button.dart +-3. Request code completion in this method and measure time to get results. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- String completionMarker = 'print(12345);'; +- List times = await new BenchmarkScenario() +- .waitAnalyze_change_getCompletion( +- roots: [paths.packageFlutter], +- file: '${paths.packageFlutter}/lib/src/material/button.dart', +- fileChange: new FileChange( +- afterStr: 'Widget build(BuildContext context) {', +- insertStr: completionMarker), +- completeAfterStr: completionMarker, +- numOfRepeats: 10); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_flutter_completion_2(String id) async { +- String description = r''' +-1. Open 'packages/flutter'. +-2. Change the name of a public method in lib/src/rendering/layer.dart +-3. Request code completion in this method and measure time to get results. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- List times = await new BenchmarkScenario() +- .waitAnalyze_change_getCompletion( +- roots: [paths.packageFlutter], +- file: '${paths.packageFlutter}/lib/src/rendering/layer.dart', +- fileChange: new FileChange( +- replaceWhat: 'void removeAllChildren() {', +- replaceWith: 'void removeAllChildren2() {print(12345);parent.'), +- completeAfterStr: 'print(12345);parent.', +- numOfRepeats: 5); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_flutter_initialAnalysis_1(String id) async { +- String description = r''' +-1. Start server, set 'hello_world' analysis root. +-2. Measure the time to finish initial analysis. +-3. Shutdown the server. +-4. Go to (1). +-'''; +- List times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown( +- roots: [paths.exampleHelloWorld], numOfRepeats: 5); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_flutter_initialAnalysis_2(String id) async { +- String description = r''' +-1. Start server, set 'hello_world' and 'flutter_gallery' analysis roots. +-2. Measure the time to finish initial analysis. +-3. Shutdown the server. +-4. Go to (1). +-'''; +- List times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown( +- roots: [paths.exampleHelloWorld, paths.exampleGallery], numOfRepeats: 5); +- printBenchmarkResults(id, description, times); +-} +- +-Future run_flutter_memory_initialAnalysis_1(String id) async { +- String description = r''' +-1. Start server, set 'packages/flutter' as the analysis root. +-2. Measure the memory usage after finishing initial analysis. +-3. Shutdown the server. +-4. Go to (1). +-'''; +- List sizes = await AnalysisServerMemoryUsageTest +- .start_waitInitialAnalysis_shutdown( +- roots: [paths.packageFlutter], numOfRepeats: 3); +- printMemoryResults(id, description, sizes); +-} +- +-Future run_flutter_memory_initialAnalysis_2(String id) async { +- String description = r''' +-1. Start server, set 'packages/flutter' and 'packages/flutter_markdown' analysis roots. +-2. Measure the memory usage after finishing initial analysis. +-3. Shutdown the server. +-4. Go to (1). +-'''; +- List sizes = await AnalysisServerMemoryUsageTest +- .start_waitInitialAnalysis_shutdown( +- roots: [paths.packageFlutter, paths.packageMarkdown], +- numOfRepeats: 3); +- printMemoryResults(id, description, sizes); +-} +- +-Future run_flutter_refactoring_1(String id) async { +- String description = r''' +-1. Open 'packages/flutter'. +-2. Change the name of a public method in lib/src/rendering/layer.dart +-3. Request rename refactoring for `getSourcesWithFullName` and measure time to get results. +-4. Rollback changes to the file and wait for analysis. +-5. Go to (2). +-'''; +- List times = await new BenchmarkScenario() +- .waitAnalyze_change_getRefactoring( +- roots: [paths.packageFlutter], +- file: '${paths.packageFlutter}/lib/src/rendering/layer.dart', +- fileChange: new FileChange( +- replaceWhat: 'void removeAllChildren() {', +- replaceWith: 'void removeAllChildren2() {'), +- refactoringAtStr: 'addToScene(ui.SceneBuilder builder', +- refactoringKind: RefactoringKind.RENAME, +- refactoringOptions: new RenameOptions('addToScene2'), +- numOfRepeats: 5); +- printBenchmarkResults(id, description, times); +-} +- +-typedef BenchmarkFunction(String id); +- +-class PathHolder { +- String exampleHelloWorld; +- String exampleGallery; +- String exampleStocks; +- String packageFlutter; +- String packageMarkdown; +- String packageSprites; +- +- PathHolder({String flutterPath}) { +- exampleHelloWorld = '$flutterPath/examples/hello_world'; +- exampleGallery = '$flutterPath/examples/flutter_gallery'; +- exampleStocks = '$flutterPath/examples/stocks'; +- packageFlutter = '$flutterPath/packages/flutter'; +- packageMarkdown = '$flutterPath/packages/flutter_markdown'; +- packageSprites = '$flutterPath/packages/flutter_sprites'; +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart +deleted file mode 100644 +index 930bc0e7cd3..00000000000 +--- a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart ++++ /dev/null +@@ -1,310 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +-import 'dart:io'; +-import 'dart:math'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +- +-import '../../test/integration/support/integration_tests.dart'; +-import 'performance_tests.dart'; +- +-void printBenchmarkResults(String id, String description, List times) { +- int minTime = times.fold(1 << 20, min); +- String now = new DateTime.now().toUtc().toIso8601String(); +- print('$now ========== $id'); +- print('times: $times'); +- print('min_time: $minTime'); +- print(description.trim()); +- print('--------------------'); +- print(''); +- print(''); +-} +- +-class BenchmarkScenario extends AbstractTimingTest { +- /** +- * Init. +- * - Start Analysis Server. +- * - Set the analysis [roots]. +- * - Wait for analysis to complete. +- * - Make [file] the priority file. +- * +- * Measurement. +- * - Change the [file] according to the [fileChange]. +- * - Record the time to finish analysis. +- * +- * Repeat. +- * - Undo changes to the [file]. +- * - Repeat measurement [numOfRepeats] times. +- */ +- Future> waitAnalyze_change_analyze( +- {List roots, +- String file, +- FileChange fileChange, +- int numOfRepeats}) async { +- outOfTestExpect(roots, isNotNull, reason: 'roots'); +- outOfTestExpect(file, isNotNull, reason: 'file'); +- outOfTestExpect(fileChange, isNotNull, reason: 'fileChange'); +- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats'); +- // Initialize Analysis Server. +- await super.setUp(); +- await subscribeToStatusNotifications(); +- // Set roots and analyze. +- await sendAnalysisSetAnalysisRoots(roots, []); +- await analysisFinished; +- // Make the file priority. +- await sendAnalysisSetPriorityFiles([file]); +- // Repeat. +- List times = []; +- for (int i = 0; i < numOfRepeats; i++) { +- // Update and wait for analysis. +- Stopwatch stopwatch = new Stopwatch()..start(); +- await _applyFileChange(file, fileChange); +- await analysisFinished; +- times.add(stopwatch.elapsed.inMilliseconds); +- // Remove the overlay and analyze. +- await sendAnalysisUpdateContent({file: new RemoveContentOverlay()}); +- await analysisFinished; +- } +- // Done. +- await shutdown(); +- return times; +- } +- +- /** +- * Init. +- * 1. Start Analysis Server. +- * 2. Set the analysis [roots]. +- * 3. Wait for analysis to complete. +- * 4. Make [file] the priority file. +- * +- * Measurement. +- * 5. Change the [file] according to the [fileChange]. +- * 6. Request [completeAfterStr] in the updated file content. +- * 7. Record the time to get completion results. +- * 8. Undo changes to the [file] and analyze. +- * 9. Go to (5). +- */ +- Future> waitAnalyze_change_getCompletion( +- {List roots, +- String file, +- FileChange fileChange, +- String completeAfterStr, +- int numOfRepeats}) async { +- outOfTestExpect(roots, isNotNull, reason: 'roots'); +- outOfTestExpect(file, isNotNull, reason: 'file'); +- outOfTestExpect(fileChange, isNotNull, reason: 'fileChange'); +- outOfTestExpect(completeAfterStr, isNotNull, reason: 'completeAfterStr'); +- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats'); +- // Initialize Analysis Server. +- await super.setUp(); +- await subscribeToStatusNotifications(); +- // Set roots and analyze. +- await sendAnalysisSetAnalysisRoots(roots, []); +- await analysisFinished; +- // Make the file priority. +- await sendAnalysisSetPriorityFiles([file]); +- // Repeat. +- List times = []; +- for (int i = 0; i < numOfRepeats; i++) { +- String updatedContent = await _applyFileChange(file, fileChange); +- // Measure completion time. +- int completionOffset = +- _indexOfEnd(file, updatedContent, completeAfterStr); +- Duration completionDuration = +- await _measureCompletionTime(file, completionOffset); +- times.add(completionDuration.inMilliseconds); +- // Remove the overlay and analyze. +- await sendAnalysisUpdateContent({file: new RemoveContentOverlay()}); +- await analysisFinished; +- } +- // Done. +- await shutdown(); +- return times; +- } +- +- /** +- * Init. +- * 1. Start Analysis Server. +- * 2. Set the analysis [roots]. +- * 3. Wait for analysis to complete. +- * 4. Make [file] the priority file. +- * +- * Measurement. +- * 5. Change the [file] according to the [fileChange]. +- * 6. Request [refactoringAtStr] in the updated file content. +- * 7. Record the time to get refactoring. +- * 8. Undo changes to the [file] and analyze. +- * 9. Go to (5). +- */ +- Future> waitAnalyze_change_getRefactoring( +- {List roots, +- String file, +- FileChange fileChange, +- String refactoringAtStr, +- RefactoringKind refactoringKind, +- RefactoringOptions refactoringOptions, +- int numOfRepeats}) async { +- outOfTestExpect(roots, isNotNull, reason: 'roots'); +- outOfTestExpect(file, isNotNull, reason: 'file'); +- outOfTestExpect(fileChange, isNotNull, reason: 'fileChange'); +- outOfTestExpect(refactoringAtStr, isNotNull, reason: 'refactoringAtStr'); +- outOfTestExpect(refactoringKind, isNotNull, reason: 'refactoringKind'); +- outOfTestExpect(refactoringOptions, isNotNull, +- reason: 'refactoringOptions'); +- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats'); +- // Initialize Analysis Server. +- await super.setUp(); +- await subscribeToStatusNotifications(); +- // Set roots and analyze. +- await sendAnalysisSetAnalysisRoots(roots, []); +- await analysisFinished; +- // Make the file priority. +- await sendAnalysisSetPriorityFiles([file]); +- // Repeat. +- List times = []; +- for (int i = 0; i < numOfRepeats; i++) { +- String updatedContent = await _applyFileChange(file, fileChange); +- // Measure time to get refactoring. +- int refactoringOffset = _indexOf(file, updatedContent, refactoringAtStr); +- Duration refactoringDuration = await _measureRefactoringTime( +- file, refactoringOffset, refactoringKind, refactoringOptions); +- times.add(refactoringDuration.inMilliseconds); +- // Remove the overlay and analyze. +- await sendAnalysisUpdateContent({file: new RemoveContentOverlay()}); +- await analysisFinished; +- } +- // Done. +- await shutdown(); +- return times; +- } +- +- /** +- * Compute updated content of the [file] as described by [desc], add overlay +- * for the [file], and return the updated content. +- */ +- Future _applyFileChange(String file, FileChange desc) async { +- String originalContent = _getFileContent(file); +- String updatedContent; +- if (desc.afterStr != null) { +- int offset = _indexOfEnd(file, originalContent, desc.afterStr); +- offset -= desc.afterStrBack; +- updatedContent = originalContent.substring(0, offset) + +- desc.insertStr + +- originalContent.substring(offset); +- } else if (desc.replaceWhat != null) { +- int offset = _indexOf(file, originalContent, desc.replaceWhat); +- updatedContent = originalContent.substring(0, offset) + +- desc.replaceWith + +- originalContent.substring(offset + desc.replaceWhat.length); +- } +- await sendAnalysisUpdateContent( +- {file: new AddContentOverlay(updatedContent)}); +- return updatedContent; +- } +- +- Future _measureCompletionTime(String file, int offset) async { +- Stopwatch stopwatch = new Stopwatch(); +- stopwatch.start(); +- Completer completer = new Completer(); +- var completionSubscription = onCompletionResults.listen((_) { +- completer.complete(stopwatch.elapsed); +- }); +- try { +- await sendCompletionGetSuggestions(file, offset); +- return await completer.future; +- } finally { +- completionSubscription.cancel(); +- } +- } +- +- Future _measureRefactoringTime( +- String file, +- int offset, +- RefactoringKind refactoringKind, +- RefactoringOptions refactoringOptions) async { +- Stopwatch stopwatch = new Stopwatch(); +- stopwatch.start(); +- await sendEditGetRefactoring(refactoringKind, file, offset, 0, false, +- options: refactoringOptions); +- return stopwatch.elapsed; +- } +- +- /** +- * 1. Start Analysis Server. +- * 2. Set the analysis [roots]. +- * 3. Wait for analysis to complete. +- * 4. Record the time to finish analysis. +- * 5. Shutdown. +- * 6. Go to (1). +- */ +- static Future> start_waitInitialAnalysis_shutdown( +- {List roots, int numOfRepeats}) async { +- outOfTestExpect(roots, isNotNull, reason: 'roots'); +- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats'); +- // Repeat. +- List times = []; +- for (int i = 0; i < numOfRepeats; i++) { +- BenchmarkScenario instance = new BenchmarkScenario(); +- // Initialize Analysis Server. +- await instance.setUp(); +- await instance.subscribeToStatusNotifications(); +- // Set roots and analyze. +- Stopwatch stopwatch = new Stopwatch()..start(); +- await instance.sendAnalysisSetAnalysisRoots(roots, []); +- await instance.analysisFinished; +- times.add(stopwatch.elapsed.inMilliseconds); +- // Stop the server. +- await instance.shutdown(); +- } +- return times; +- } +- +- static String _getFileContent(String path) { +- File file = new File(path); +- outOfTestExpect(file.existsSync(), isTrue, +- reason: 'File $path does not exist.'); +- return file.readAsStringSync(); +- } +- +- /** +- * Return the index of [what] in [where] in the [file], fail if not found. +- */ +- static int _indexOf(String file, String where, String what) { +- int index = where.indexOf(what); +- outOfTestExpect(index, isNot(-1), reason: 'Cannot find |$what| in $file.'); +- return index; +- } +- +- /** +- * Return the end index if [what] in [where] in the [file], fail if not found. +- */ +- static int _indexOfEnd(String file, String where, String what) { +- return _indexOf(file, where, what) + what.length; +- } +-} +- +-class FileChange { +- final String afterStr; +- final int afterStrBack; +- final String insertStr; +- final String replaceWhat; +- final String replaceWith; +- +- FileChange( +- {this.afterStr, +- this.afterStrBack: 0, +- this.insertStr, +- this.replaceWhat, +- this.replaceWith}) { +- if (afterStr != null) { +- outOfTestExpect(insertStr, isNotNull, reason: 'insertStr'); +- } else if (replaceWhat != null) { +- outOfTestExpect(replaceWith, isNotNull, reason: 'replaceWith'); +- } +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart b/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart +deleted file mode 100644 +index 9a42862f084..00000000000 +--- a/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart ++++ /dev/null +@@ -1,187 +0,0 @@ +-// 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:io'; +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:path/path.dart' as path; +- +-import '../../test/integration/support/integration_tests.dart'; +-import '../benchmarks.dart'; +-import 'memory_tests.dart'; +- +-/// benchmarks: +-/// - analysis-server-cold-analysis +-/// - analysis-server-cold-memory +-class ColdAnalysisBenchmark extends Benchmark { +- ColdAnalysisBenchmark() +- : super( +- 'analysis-server-cold', +- 'Analysis server benchmarks of a large project on start-up, no ' +- 'existing driver cache.', +- kind: 'group'); +- +- int get maxIterations => 3; +- +- @override +- Future run( +- {bool quick: false, bool previewDart2: false}) async { +- if (!quick) { +- deleteServerCache(); +- } +- +- Stopwatch stopwatch = new Stopwatch()..start(); +- +- AnalysisServerMemoryUsageTest test = new AnalysisServerMemoryUsageTest(); +- await test.setUp(previewDart2: previewDart2); +- await test.subscribeToStatusNotifications(); +- await test.sendAnalysisSetAnalysisRoots(getProjectRoots(quick: quick), []); +- await test.analysisFinished; +- +- stopwatch.stop(); +- int usedBytes = test.getMemoryUsage(); +- +- CompoundBenchMarkResult result = new CompoundBenchMarkResult(id); +- result.add('analysis', +- new BenchMarkResult('micros', stopwatch.elapsedMicroseconds)); +- result.add('memory', new BenchMarkResult('bytes', usedBytes)); +- +- await test.shutdown(); +- +- return result; +- } +-} +- +-/// benchmarks: +-/// - analysis-server-warm-analysis +-/// - analysis-server-warm-memory +-/// - analysis-server-edit +-/// - analysis-server-completion +-class AnalysisBenchmark extends Benchmark { +- AnalysisBenchmark() +- : super( +- 'analysis-server', +- 'Analysis server benchmarks of a large project, with an existing ' +- 'driver cache.', +- kind: 'group'); +- +- @override +- Future run( +- {bool quick: false, bool previewDart2: false}) async { +- Stopwatch stopwatch = new Stopwatch()..start(); +- +- AnalysisServerMemoryUsageTest test = new AnalysisServerMemoryUsageTest(); +- await test.setUp(previewDart2: previewDart2); +- await test.subscribeToStatusNotifications(); +- await test.sendAnalysisSetAnalysisRoots(getProjectRoots(quick: quick), []); +- await test.analysisFinished; +- +- stopwatch.stop(); +- int usedBytes = test.getMemoryUsage(); +- +- CompoundBenchMarkResult result = new CompoundBenchMarkResult(id); +- result.add('warm-analysis', +- new BenchMarkResult('micros', stopwatch.elapsedMicroseconds)); +- result.add('warm-memory', new BenchMarkResult('bytes', usedBytes)); +- +- if (!quick) { +- // change timing +- final int editMicros = await _calcEditTiming(test); +- result.add('edit', new BenchMarkResult('micros', editMicros)); +- +- // code completion +- final int completionMicros = await _calcCompletionTiming(test); +- result.add('completion', new BenchMarkResult('micros', completionMicros)); +- } +- +- await test.shutdown(); +- +- return result; +- } +- +- Future _calcEditTiming( +- AbstractAnalysisServerIntegrationTest test) async { +- const int kGroupCount = 5; +- +- final String filePath = +- path.join(analysisServerSrcPath, 'lib/src/analysis_server.dart'); +- String contents = new File(filePath).readAsStringSync(); +- +- await test +- .sendAnalysisUpdateContent({filePath: new AddContentOverlay(contents)}); +- +- final Stopwatch stopwatch = new Stopwatch()..start(); +- +- for (int i = 0; i < kGroupCount; i++) { +- int startIndex = i * (contents.length ~/ (kGroupCount + 2)); +- int index = contents.indexOf(';', startIndex); +- contents = contents.substring(0, index + 1) + +- ' ' + +- contents.substring(index + 1); +- test.sendAnalysisUpdateContent( +- {filePath: new AddContentOverlay(contents)}); +- await test.analysisFinished; +- } +- +- stopwatch.stop(); +- +- return stopwatch.elapsedMicroseconds ~/ kGroupCount; +- } +- +- Future _calcCompletionTiming( +- AbstractAnalysisServerIntegrationTest test) async { +- const int kGroupCount = 10; +- +- final String filePath = +- path.join(analysisServerSrcPath, 'lib/src/analysis_server.dart'); +- String contents = new File(filePath).readAsStringSync(); +- +- await test +- .sendAnalysisUpdateContent({filePath: new AddContentOverlay(contents)}); +- +- int completionCount = 0; +- final Stopwatch stopwatch = new Stopwatch()..start(); +- +- Future _complete(int offset) async { +- CompletionGetSuggestionsResult result = +- await test.sendCompletionGetSuggestions(filePath, offset); +- +- Future future = test.onCompletionResults +- .where((CompletionResultsParams params) => +- params.id == result.id && params.isLast) +- .first; +- await future; +- +- completionCount++; +- } +- +- for (int i = 0; i < kGroupCount; i++) { +- int startIndex = i * (contents.length ~/ (kGroupCount + 2)); +- // Look for a line with a period in it that ends with a semi-colon. +- int index = +- contents.indexOf(new RegExp(r'\..*;$', multiLine: true), startIndex); +- +- await _complete(index - 10); +- await _complete(index - 1); +- await _complete(index); +- await _complete(index + 1); +- await _complete(index + 10); +- +- if (i + 1 < kGroupCount) { +- // mutate +- index = contents.indexOf(';', index); +- contents = contents.substring(0, index + 1) + +- ' ' + +- contents.substring(index + 1); +- await test.sendAnalysisUpdateContent( +- {filePath: new AddContentOverlay(contents)}); +- } +- } +- +- stopwatch.stop(); +- +- return stopwatch.elapsedMicroseconds ~/ completionCount; +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart +deleted file mode 100644 +index 0a1204195b9..00000000000 +--- a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart ++++ /dev/null +@@ -1,85 +0,0 @@ +-// Copyright (c) 2015, 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:io'; +- +-import 'package:args/args.dart'; +-import 'package:test/test.dart'; +- +-import 'performance_tests.dart'; +- +-const COMPLETION_OFFSET = 'offset'; +-const PRIORITY_FILE_OPTION = 'priority'; +-const SOURCE_OPTION = 'source'; +- +-/** +- * Pass in the directory of the source to be analyzed as option `--source`, +- * specify a priority file with `--priority` and an offset for completions +- * with a `--offset`. +- */ +-main(List arguments) async { +- ArgParser parser = _createArgParser(); +- var args = parser.parse(arguments); +- if (args[SOURCE_OPTION] == null) { +- print('path to source directory must be specified'); +- exit(1); +- } +- +- int offset = int.parse(args[COMPLETION_OFFSET]); +- String priorityFile = args[PRIORITY_FILE_OPTION]; +- String source = args[SOURCE_OPTION]; +- +- CompletionTimingTest test = +- new CompletionTimingTest(offset, priorityFile, source); +- await test.test_timing(); +-} +- +-ArgParser _createArgParser() => new ArgParser() +- ..addOption(SOURCE_OPTION, help: 'full path to source directory for analysis') +- ..addOption(PRIORITY_FILE_OPTION, help: 'full path to a priority file') +- ..addOption(COMPLETION_OFFSET, help: 'offset in file for code completions'); +- +-/** +- * CompletionTimingTest measures the time taken for the analysis server to respond with +- * completion suggestions for a given file and offset. The time measured starts when +- * the analysis root is set and is done when the completion suggestions are received +- * from the server. The test does not wait for analysis to be complete before asking for +- * completions. +- */ +-class CompletionTimingTest extends AbstractTimingTest { +- final int offset; +- final String priorityFile; +- final String source; +- +- List timings = []; +- +- CompletionTimingTest(this.offset, this.priorityFile, this.source); +- +- Future test_timing() async { +-// debugStdio(); +- +- expect(priorityFile, isNotNull, +- reason: 'A priority file must be specified for completion testing.'); +- expect(offset, isNotNull, +- reason: 'An offset must be specified for completion testing.'); +- +- await init(source); +- stopwatch.start(); +- +- onCompletionResults.listen((_) { +- timings.add(new Duration(milliseconds: stopwatch.elapsed.inMilliseconds)); +- }); +- +- setAnalysisRoot(); +- sendAnalysisSetPriorityFiles([priorityFile]); +- sendCompletionGetSuggestions(priorityFile, offset); +- +- await analysisFinished; +- +- print('analysis completed in ${stopwatch.elapsed}'); +- print('completion received at : $timings'); +- await shutdown(); +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart +deleted file mode 100644 +index 1971bf575ec..00000000000 +--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart ++++ /dev/null +@@ -1,133 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +-import 'dart:convert'; +-import 'dart:io'; +-import 'dart:math'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +- +-import '../../test/integration/support/integration_tests.dart'; +- +-void printMemoryResults(String id, String description, List sizes) { +- int minMemory = sizes.fold(sizes.first, min); +- int maxMemory = sizes.fold(sizes.first, max); +- String now = new DateTime.now().toUtc().toIso8601String(); +- print('$now ========== $id'); +- print('memory: $sizes'); +- print('min_memory: $minMemory'); +- print('max_memory: $maxMemory'); +- print(description.trim()); +- print('--------------------'); +- print(''); +- print(''); +-} +- +-/** +- * Base class for analysis server memory usage tests. +- */ +-class AnalysisServerMemoryUsageTest +- extends AbstractAnalysisServerIntegrationTest { +- static const int vmServicePort = 12345; +- +- int getMemoryUsage() { +- ProcessResult result = _run('curl', [ +- 'localhost:$vmServicePort/_getAllocationProfile\?isolateId=isolates/root\&gc=full' +- ]); +- Map json = JSON.decode(result.stdout); +- Map heaps = json['result']['heaps']; +- int newSpace = heaps['new']['used']; +- int oldSpace = heaps['old']['used']; +- return newSpace + oldSpace; +- } +- +- /** +- * Send the server an 'analysis.setAnalysisRoots' command directing it to +- * analyze [sourceDirectory]. +- */ +- Future setAnalysisRoot() => +- sendAnalysisSetAnalysisRoots([sourceDirectory.path], []); +- +- /** +- * The server is automatically started before every test. +- */ +- @override +- Future setUp({bool previewDart2: false}) { +- onAnalysisErrors.listen((AnalysisErrorsParams params) { +- currentAnalysisErrors[params.file] = params.errors; +- }); +- onServerError.listen((ServerErrorParams params) { +- // A server error should never happen during an integration test. +- fail('${params.message}\n${params.stackTrace}'); +- }); +- Completer serverConnected = new Completer(); +- onServerConnected.listen((_) { +- outOfTestExpect(serverConnected.isCompleted, isFalse); +- serverConnected.complete(); +- }); +- return startServer( +- servicesPort: vmServicePort, +- previewDart2: previewDart2, +- ).then((_) { +- server.listenToOutput(dispatchNotification); +- server.exitCode.then((_) { +- skipShutdown = true; +- }); +- return serverConnected.future; +- }); +- } +- +- /** +- * After every test, the server is stopped. +- */ +- Future shutdown() async => await shutdownIfNeeded(); +- +- /** +- * Enable [ServerService.STATUS] notifications so that [analysisFinished] +- * can be used. +- */ +- Future subscribeToStatusNotifications() async { +- await sendServerSetSubscriptions([ServerService.STATUS]); +- } +- +- /** +- * Synchronously run the given [executable] with the given [arguments]. Return +- * the result of running the process. +- */ +- ProcessResult _run(String executable, List arguments) { +- return Process.runSync(executable, arguments, +- stderrEncoding: UTF8, stdoutEncoding: UTF8); +- } +- +- /** +- * 1. Start Analysis Server. +- * 2. Set the analysis [roots]. +- * 3. Wait for analysis to complete. +- * 4. Record the heap size after analysis is finished. +- * 5. Shutdown. +- * 6. Go to (1). +- */ +- static Future> start_waitInitialAnalysis_shutdown( +- {List roots, int numOfRepeats}) async { +- outOfTestExpect(roots, isNotNull, reason: 'roots'); +- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats'); +- // Repeat. +- List sizes = []; +- for (int i = 0; i < numOfRepeats; i++) { +- AnalysisServerMemoryUsageTest test = new AnalysisServerMemoryUsageTest(); +- // Initialize Analysis Server. +- await test.setUp(); +- await test.subscribeToStatusNotifications(); +- // Set roots and analyze. +- await test.sendAnalysisSetAnalysisRoots(roots, []); +- await test.analysisFinished; +- sizes.add(test.getMemoryUsage()); +- // Stop the server. +- await test.shutdown(); +- } +- return sizes; +- } +-} +diff --git a/pkg/analysis_server/benchmark/perf/performance_tests.dart b/pkg/analysis_server/benchmark/perf/performance_tests.dart +deleted file mode 100644 +index 540678ca652..00000000000 +--- a/pkg/analysis_server/benchmark/perf/performance_tests.dart ++++ /dev/null +@@ -1,76 +0,0 @@ +-// Copyright (c) 2015, 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:io'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +- +-import '../../test/integration/support/integration_tests.dart'; +- +-/** +- * Base class for analysis server performance tests. +- */ +-abstract class AbstractAnalysisServerPerformanceTest +- extends AbstractAnalysisServerIntegrationTest { +- /** +- * Stopwatch for timing results; +- */ +- Stopwatch stopwatch = new Stopwatch(); +- +- /** +- * Send the server an 'analysis.setAnalysisRoots' command directing it to +- * analyze [sourceDirectory]. +- */ +- Future setAnalysisRoot() => +- sendAnalysisSetAnalysisRoots([sourceDirectory.path], []); +- +- /** +- * The server is automatically started before every test. +- */ +- @override +- Future setUp() { +- onAnalysisErrors.listen((AnalysisErrorsParams params) { +- currentAnalysisErrors[params.file] = params.errors; +- }); +- onServerError.listen((ServerErrorParams params) { +- // A server error should never happen during an integration test. +- fail('${params.message}\n${params.stackTrace}'); +- }); +- Completer serverConnected = new Completer(); +- onServerConnected.listen((_) { +- outOfTestExpect(serverConnected.isCompleted, isFalse); +- serverConnected.complete(); +- }); +- return startServer(checked: false).then((_) { +- server.listenToOutput(dispatchNotification); +- server.exitCode.then((_) { +- skipShutdown = true; +- }); +- return serverConnected.future; +- }); +- } +- +- /** +- * After every test, the server is stopped. +- */ +- Future shutdown() async => await shutdownIfNeeded(); +- +- /** +- * Enable [ServerService.STATUS] notifications so that [analysisFinished] +- * can be used. +- */ +- Future subscribeToStatusNotifications() async { +- await sendServerSetSubscriptions([ServerService.STATUS]); +- } +-} +- +-class AbstractTimingTest extends AbstractAnalysisServerPerformanceTest { +- Future init(String source) async { +- await super.setUp(); +- sourceDirectory = new Directory(source); +- return subscribeToStatusNotifications(); +- } +-} +diff --git a/pkg/analysis_server/benchmark/readme.md b/pkg/analysis_server/benchmark/readme.md +deleted file mode 100644 +index 24eb7ece492..00000000000 +--- a/pkg/analysis_server/benchmark/readme.md ++++ /dev/null +@@ -1,35 +0,0 @@ +-# Analysis Server Benchmarks +- +-## How to run the benchmarks +- +-To see a list of all available benchmarks, run: +- +-``` +-dart benchmark/benchmarks.dart list +-``` +- +-To run an individual benchmark, run: +- +-``` +-dart benchmark/benchmarks.dart run +-``` +- +-## How they're tested +- +-In order to make sure that our benchmarks don't regress in terms of their +-ability to run, we create one unit test per benchmark, and run those tests +-as part of our normal CI test suite. +- +-To save time on the CI, we only run one iteration of each benchmark +-(`--repeat=1`), and we run the benchmark on a smaller data set (`--quick`). +- +-See `test/benchmark_test.dart`. +- +-## To add a new benchmark +- +-Register the new benchmark in the `main()` method of benchmark/benchmarks.dart. +- +-## On the bots +- +-Our benchmarks run on a continuous performance testing system. Currently, the +-benchmarks need to be manually registered ahead of time. +diff --git a/pkg/analysis_server/bin/server.dart b/pkg/analysis_server/bin/server.dart +deleted file mode 100644 +index f0d075f6f8d..00000000000 +--- a/pkg/analysis_server/bin/server.dart ++++ /dev/null +@@ -1,13 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/starter.dart'; +- +-/** +- * Create and run an analysis server. +- */ +-void main(List args) { +- ServerStarter starter = new ServerStarter(); +- starter.start(args); +-} +diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html +deleted file mode 100644 +index 6528f6d2a99..00000000000 +--- a/pkg/analysis_server/doc/api.html ++++ /dev/null +@@ -1,4725 +0,0 @@ +- +- +- Analysis Server API Specification +- +- +-

Analysis Server API Specification

+-

Version +- 1.18.4 +-

+-

+- This document contains a specification of the API provided by the +- analysis server. The API in this document is currently under +- development. Changes to the API will be accompanied by an update to the +- protocol version number according to the principles of semantic +- versioning (semver.org). +-

+-

Overview

+-

+- The analysis server API is a bi-directional client-server +- API. The API is independent of the transport mechanism used, but +- is heavily influenced by a model in which sockets or character +- streams are used to transport JSON-RPC encoded information. +-

+-

Transport Mechanism

+-

+- The characters passed to the server are expected to be encoded +- using UTF-8. +-

+-

+- When character streams are used as the transport, messages are +- delineated by newlines. This means, in particular, that the JSON +- encoding process must not introduce newlines within a +- message. Note however that newlines are used in this document +- for readability. +-

+-

+- It is the client's responsibility to read output from the server to +- avoid its blocking. +-

+-

+- To ease interoperability with Lisp-based clients (which may not +- be able to easily distinguish between empty lists, empty maps, +- and null), client-to-server communication is allowed to replace +- any instance of "{}" or "[]" with null. The +- server will always properly represent empty lists as +- "[]" and empty maps as "{}". +-

+-

Communication Structure

+-

+- Clients can make a request of the server and the server will +- provide a response for each request that it receives. While many +- of the requests that can be made by a client are informational +- in nature, we have chosen to always return a response so that +- clients can know whether the request was received and was +- correct. +-

+-

+- There is no guarantee concerning the order in which responses +- will be returned, but there is a guarantee that the server will +- process requests in the order in which they are sent as long as +- the transport mechanism also makes this guarantee. Responses can +- be returned in an order that is different from the order in +- which the requests were received because some requests take +- longer to process than others. +-

+-

+- Every request is required to have two fields and may have two +- additional optional fields. The first required field is the ‘id’ +- field, which is only used by the server to associate a response +- with the request that generated the response. The second +- required field is the ‘method’ field, which is used to determine +- what the server is being requested to do. One optional field is +- the ‘params’ field, whose structure is dependent on the method +- being requested. The structure of this field is described with +- each request for which it is required. The other optional field +- is the 'clientRequestTime' field, which is a number indicating +- the time at which the client made the request (milliseconds +- since epoch). Providing clientRequestTime helps us track +- how responsive analysis server is to client requests +- and better address any issues that occur. +-

+-

+- Every response has up to three fields. The first field is the +- ‘id’ field, which is always present and whose value is the +- identifier that was passed to the request that generated the +- response. The second field is the ‘error’ field, which is only +- present if an error was encountered while processing the +- request. The third field is the ‘result’ field, whose structure +- is dependent on the method being responded to, and is described +- with each request that will produce it. +-

+-

+- The server can also communicate to the clients by sending a +- notification. The purpose of these notifications is to provide +- information to clients as it becomes available rather than to +- require that clients poll for it. Unless explicitly stated, all +- notifications are designed to return the complete information +- available at the time the notification is sent; clients are not +- required to update previously communicated +- results. Consequently, the server can and should return partial +- results before all results are available. For example, the +- syntactic errors for a file can be returned as soon as the +- syntactic analysis is complete, and both syntactic and semantic +- errors can be returned together at a later time. +-

+-

+- Each notification has two fields. The first field is the ‘event’ +- field, which identifies the kind of notification. The second +- field is the ‘params’ field, whose structure is dependent on the +- kind of notification being sent. The structure of this field is +- described with each notification. +-

+-

+- In order to be backward compatible, clients should ignore fields that were +- not specified in the version of the API on which they were based. Clients +- should also use the server.getVersion request to test that the version of +- the server supports an API before using it. +-

+-

Eventual Consistency

+-

+- The analysis server satisfies requests under the principle of +- eventual +- consistency. +- That is, in some cases it may return responses with the currently available +- results while it's catching up with unprocessed changes. +-

+-

Domains

+-

+- For convenience, the API is divided into domains. Each domain is specified +- in a separate section below. The specifications of the API’s refer to data +- structures beyond the standard JSON primitives. These data structures are +- documented in the section titled Types. +-

+- +-

Server

+- +-

Analysis

+- +-

Completion

+- +-

Search

+- +-

Edit

+- +-

Execution

+- +-

Diagnostic

+- +-

Command-line Arguments

+-

+- The command-line arguments that can be passed to the server. +-

+-

Options

+-
+-
+-
--client-id
+-
+-

+- Specifies an identifier associated with the client. Used when +- generating error reports. +-

+-

+- Clients are strongly encouraged to provide this information in +- order to improve the quality of information that can be provided +- to them. +-

+-
+-
+-
+-
--client-version
+-
+-

+- Specifies the version of the client that is communicating with +- the server. Used when generating error reports. +-

+-

+- Clients are strongly encouraged to provide this information in +- order to improve the quality of information that can be provided +- to them. +-

+-
+-
+-
+-
--no-error-notification
+-
+-

Deprecated: clients should no longer pass this option in

+- Disable notifications about errors (see analysis.error). If this +- flag is not specified then notifications will be sent for all +- errors produced for all files in the actual analysis roots. +-
+-
+-
+-
--no-index
+-
+-

Deprecated: clients should no longer pass this option in

+- This flag used to disable the server from generating an index, but now +- it has no effect. +-
+-
+-
+-
--file-read-mode
+-
+-

Deprecated: clients should no longer pass this option in

+- An enumeration of the ways files can be read from disk. Some clients +- normalize end of line characters which would make the file offset and +- range information incorrect. The default option is as-is, but +- can also be set to normalize-eol-always. The default option +- (as-is) reads files as they are on disk. The +- normalize-eol-always option does the following: +-
    +-
  • '\r\n' is converted to '\n';
  • +-
  • '\r' by itself is converted to '\n';
  • +-
  • this happens regardless of the OS editor is running on.
  • +-
+-
+-
+-
+-

Domains

+-

server domain

+-

+- The server domain contains API’s related to the execution of +- the server. +-

+- +- +- +- +- +- +-

Requests

server.getVersion
request: {
+-  "id": String
+-  "method": "server.getVersion"
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "version": String
+-  }
+-}
+-

Return the version number of the analysis server.

+- +-

returns:

version: String
+- +-

The version number of the analysis server.

+-
server.shutdown
request: {
+-  "id": String
+-  "method": "server.shutdown"
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Cleanly shutdown the analysis server. Requests that are +- received after this request will not be processed. Requests +- that were received before this request, but for which a +- response has not yet been sent, will not be responded to. No +- further responses or notifications will be sent after the +- response to this request has been sent. +-

+-
server.setSubscriptions
request: {
+-  "id": String
+-  "method": "server.setSubscriptions"
+-  "params": {
+-    "subscriptions": List<ServerService>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Subscribe for services. All previous subscriptions are +- replaced by the given set of services. +-

+-

+- It is an error if any of the elements in the list are not +- valid services. If there is an error, then the current +- subscriptions will remain unchanged. +-

+- +-

parameters:

subscriptions: List<ServerService>
+- +-

A list of the services being subscribed to.

+-

Notifications

server.connected
notification: {
+-  "event": "server.connected"
+-  "params": {
+-    "version": String
+-    "pid": int
+-    "sessionId": optional String
+-  }
+-}
+-

+- Reports that the server is running. This notification is +- issued once after the server has started running but before +- any requests are processed to let the client know that it +- started correctly. +-

+-

+- It is not possible to subscribe to or unsubscribe from this +- notification. +-

+- +-

parameters:

version: String
+- +-

The version number of the analysis server.

+-
pid: int
+- +-

The process id of the analysis server process.

+-
sessionId: String (optional)
+- +-

The session id for this session.

+-
server.error
notification: {
+-  "event": "server.error"
+-  "params": {
+-    "isFatal": bool
+-    "message": String
+-    "stackTrace": String
+-  }
+-}
+-

+- Reports that an unexpected error has occurred while +- executing the server. This notification is not used for +- problems with specific requests (which are returned as part +- of the response) but is used for exceptions that occur while +- performing other tasks, such as analysis or preparing +- notifications. +-

+-

+- It is not possible to subscribe to or unsubscribe from this +- notification. +-

+- +-

parameters:

isFatal: bool
+- +-

+- True if the error is a fatal error, meaning that the +- server will shutdown automatically after sending this +- notification. +-

+-
message: String
+- +-

+- The error message indicating what kind of error was +- encountered. +-

+-
stackTrace: String
+- +-

+- The stack trace associated with the generation of the +- error, used for debugging the server. +-

+-
server.status
notification: {
+-  "event": "server.status"
+-  "params": {
+-    "analysis": optional AnalysisStatus
+-    "pub": optional PubStatus
+-  }
+-}
+-

+- Reports the current status of the server. Parameters are +- omitted if there has been no change in the status +- represented by that parameter. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "STATUS" in +- the list of services passed in a server.setSubscriptions +- request. +-

+- +-

parameters:

analysis: AnalysisStatus (optional)
+- +-

+- The current status of analysis, including whether +- analysis is being performed and if so what is being +- analyzed. +-

+-
pub: PubStatus (optional)
+- +-

+- The current status of pub execution, indicating whether we are +- currently running pub. +-

+-
+-

analysis domain

+-

+- The analysis domain contains API’s related to the analysis of +- files. +-

+- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-

Requests

analysis.getErrors
request: {
+-  "id": String
+-  "method": "analysis.getErrors"
+-  "params": {
+-    "file": FilePath
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "errors": List<AnalysisError>
+-  }
+-}
+-

+- Return the errors associated with the given file. If the +- errors for the given file have not yet been computed, or the +- most recently computed errors for the given file are out of +- date, then the response for this request will be delayed +- until they have been computed. If some or all of the errors +- for the file cannot be computed, then the subset of the +- errors that can be computed will be returned and the +- response will contain an error to indicate why the errors +- could not be computed. If the content of the file changes after this +- request was received but before a response could be sent, then an +- error of type CONTENT_MODIFIED will be generated. +-

+-

+- This request is intended to be used by clients that cannot +- asynchronously apply updated error information. Clients that +- can apply error information as it becomes available +- should use the information provided by the 'analysis.errors' +- notification. +-

+-

+- If a request is made for a file which does not exist, or +- which is not currently subject to analysis (e.g. because it +- is not associated with any analysis root specified to +- analysis.setAnalysisRoots), an error of type +- GET_ERRORS_INVALID_FILE will be generated. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file for which errors are being requested. +-

+-

returns:

errors: List<AnalysisError>
+- +-

+- The errors associated with the file. +-

+-
analysis.getHover
request: {
+-  "id": String
+-  "method": "analysis.getHover"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "hovers": List<HoverInformation>
+-  }
+-}
+-

+- Return the hover information associate with the given +- location. If some or all of the hover information is not +- available at the time this request is processed the +- information will be omitted from the response. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file in which hover information is being requested. +-

+-
offset: int
+- +-

+- The offset for which hover information is being requested. +-

+-

returns:

hovers: List<HoverInformation>
+- +-

+- The hover information associated with the +- location. The list will be empty if no information +- could be determined for the location. The list can +- contain multiple items if the file is being analyzed +- in multiple contexts in conflicting ways (such as a +- part that is included in multiple libraries). +-

+-
analysis.getLibraryDependencies
request: {
+-  "id": String
+-  "method": "analysis.getLibraryDependencies"
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "libraries": List<FilePath>
+-    "packageMap": Map<String, Map<String, List<FilePath>>>
+-  }
+-}
+-

+- Return library dependency information for use in client-side indexing +- and package URI resolution. +-

+-

+- Clients that are only using the libraries field should consider using the +- analyzedFiles notification instead. +-

+- +-

returns:

libraries: List<FilePath>
+- +-

+- A list of the paths of library elements referenced by +- files in existing analysis roots. +-

+-
packageMap: Map<String, Map<String, List<FilePath>>>
+- +-

+- A mapping from context source roots to package maps which map +- package names to source directories for use in client-side +- package URI resolution. +-

+-
analysis.getNavigation
request: {
+-  "id": String
+-  "method": "analysis.getNavigation"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-    "length": int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "files": List<FilePath>
+-    "targets": List<NavigationTarget>
+-    "regions": List<NavigationRegion>
+-  }
+-}
+-

+- Return the navigation information associated with the given region of +- the given file. If the navigation information for the given file has +- not yet been computed, or the most recently computed navigation +- information for the given file is out of date, then the response for +- this request will be delayed until it has been computed. If the +- content of the file changes after this request was received but before +- a response could be sent, then an error of type +- CONTENT_MODIFIED will be generated. +-

+-

+- If a navigation region overlaps (but extends either before or after) +- the given region of the file it will be included in the result. This +- means that it is theoretically possible to get the same navigation +- region in response to multiple requests. Clients can avoid this by +- always choosing a region that starts at the beginning of a line and +- ends at the end of a (possibly different) line in the file. +-

+-

+- If a request is made for a file which does not exist, or +- which is not currently subject to analysis (e.g. because it +- is not associated with any analysis root specified to +- analysis.setAnalysisRoots), an error of type +- GET_NAVIGATION_INVALID_FILE will be generated. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file in which navigation information is being requested. +-

+-
offset: int
+- +-

+- The offset of the region for which navigation information is being +- requested. +-

+-
length: int
+- +-

+- The length of the region for which navigation information is being +- requested. +-

+-

returns:

files: List<FilePath>
+- +-

+- A list of the paths of files that are referenced by the navigation +- targets. +-

+-
targets: List<NavigationTarget>
+- +-

+- A list of the navigation targets that are referenced by the +- navigation regions. +-

+-
regions: List<NavigationRegion>
+- +-

+- A list of the navigation regions within the requested region of +- the file. +-

+-
analysis.getReachableSources
request: {
+-  "id": String
+-  "method": "analysis.getReachableSources"
+-  "params": {
+-    "file": FilePath
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "sources": Map<String, List<String>>
+-  }
+-}
+-

+- Return the transitive closure of reachable sources for a given file. +-

+-

+- If a request is made for a file which does not exist, or +- which is not currently subject to analysis (e.g. because it +- is not associated with any analysis root specified to +- analysis.setAnalysisRoots), an error of type +- GET_REACHABLE_SOURCES_INVALID_FILE will be generated. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file for which reachable source information is being requested. +-

+-

returns:

sources: Map<String, List<String>>
+- +-

+- A mapping from source URIs to directly reachable source URIs. For +- example, +- a file "foo.dart" that imports "bar.dart" would have the corresponding +- mapping +- { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has +- further imports +- (or exports) there will be a mapping from the URI "file:///bar.dart" +- to them. +- To check if a specific URI is reachable from a given file, clients can +- check +- for its presence in the resulting key set. +-

+-
analysis.reanalyze
request: {
+-  "id": String
+-  "method": "analysis.reanalyze"
+-  "params": {
+-    "roots": optional List<FilePath>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Force the re-analysis of everything contained in the specified +- analysis roots. This will cause all previously computed analysis +- results to be discarded and recomputed, and will cause all subscribed +- notifications to be re-sent. +-

+-

+- If no analysis roots are provided, then all current analysis roots +- will be re-analyzed. If an empty list of analysis roots is provided, +- then nothing will be re-analyzed. If the list contains one or more +- paths that are not currently analysis roots, then an error of type +- INVALID_ANALYSIS_ROOT will be generated. +-

+- +-

parameters:

roots: List<FilePath> (optional)
+- +-

+- A list of the analysis roots that are to be re-analyzed. +-

+-
analysis.setAnalysisRoots
request: {
+-  "id": String
+-  "method": "analysis.setAnalysisRoots"
+-  "params": {
+-    "included": List<FilePath>
+-    "excluded": List<FilePath>
+-    "packageRoots": optional Map<FilePath, FilePath>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Sets the root paths used to determine which files to analyze. The set +- of files to be analyzed are all of the files in one of the root paths +- that are not either explicitly or implicitly excluded. A file is +- explicitly excluded if it is in one of the excluded paths. A file is +- implicitly excluded if it is in a subdirectory of one of the root +- paths where the name of the subdirectory starts with a period (that +- is, a hidden directory). +-

+-

+- Note that this request determines the set of requested +- analysis roots. The actual set of analysis roots at any +- given time is the intersection of this set with the set of +- files and directories actually present on the +- filesystem. When the filesystem changes, the actual set of +- analysis roots is automatically updated, but the set of +- requested analysis roots is unchanged. This means that if +- the client sets an analysis root before the root becomes +- visible to server in the filesystem, there is no error; once +- the server sees the root in the filesystem it will start +- analyzing it. Similarly, server will stop analyzing files +- that are removed from the file system but they will remain +- in the set of requested roots. +-

+-

+- If an included path represents a file, then server will look +- in the directory containing the file for a pubspec.yaml +- file. If none is found, then the parents of the directory +- will be searched until such a file is found or the root of +- the file system is reached. If such a file is found, it will +- be used to resolve package: URI’s within the file. +-

+- +-

parameters:

included: List<FilePath>
+- +-

+- A list of the files and directories that should be +- analyzed. +-

+-
excluded: List<FilePath>
+- +-

+- A list of the files and directories within the +- included directories that should not be analyzed. +-

+-
packageRoots: Map<FilePath, FilePath> (optional)
+- +-

+- A mapping from source directories to package roots +- that should override the normal package: URI resolution +- mechanism. +-

+-

+- If a package root is a directory, then +- the analyzer will behave as though the associated +- source directory in the map contains a special +- pubspec.yaml file which resolves any package: URI to the +- corresponding path within that package root directory. The +- effect is the same as specifying the package root directory as +- a "--package_root" parameter to the Dart VM when +- executing any Dart file inside the source directory. +-

+-

+- If a package root is a file, then the analyzer +- will behave as though that file is a ".packages" file in the +- source directory. The effect is the same as specifying the file +- as a "--packages" parameter to the Dart VM when +- executing any Dart file inside the source directory. +-

+-

+- Files in any directories that are not overridden by this +- mapping have their package: URI's resolved using the +- normal pubspec.yaml mechanism. If this field is absent, +- or the empty map is specified, that indicates that the +- normal pubspec.yaml mechanism should always be used. +-

+-
analysis.setGeneralSubscriptions
request: {
+-  "id": String
+-  "method": "analysis.setGeneralSubscriptions"
+-  "params": {
+-    "subscriptions": List<GeneralAnalysisService>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Subscribe for general services (that is, services that are not +- specific to individual files). All previous subscriptions are replaced +- by the given set of services. +-

+-

+- It is an error if any of the elements in the list are not valid +- services. If there is an error, then the current subscriptions will +- remain unchanged. +-

+- +-

parameters:

subscriptions: List<GeneralAnalysisService>
+- +-

A list of the services being subscribed to.

+-
analysis.setPriorityFiles
request: {
+-  "id": String
+-  "method": "analysis.setPriorityFiles"
+-  "params": {
+-    "files": List<FilePath>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Set the priority files to the files in the given list. A +- priority file is a file that is given priority when +- scheduling which analysis work to do first. The list +- typically contains those files that are visible to the user +- and those for which analysis results will have the biggest +- impact on the user experience. The order of the files within +- the list is significant: the first file will be given higher +- priority than the second, the second higher priority than +- the third, and so on. +-

+-

+- Note that this request determines the set of requested +- priority files. The actual set of priority files is the +- intersection of the requested set of priority files with the +- set of files currently subject to analysis. (See +- analysis.setSubscriptions for a description of files that +- are subject to analysis.) +-

+-

+- If a requested priority file is a directory it is ignored, +- but remains in the set of requested priority files so that +- if it later becomes a file it can be included in the set of +- actual priority files. +-

+- +-

parameters:

files: List<FilePath>
+- +-

+- The files that are to be a priority for analysis. +-

+-
analysis.setSubscriptions
request: {
+-  "id": String
+-  "method": "analysis.setSubscriptions"
+-  "params": {
+-    "subscriptions": Map<AnalysisService, List<FilePath>>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Subscribe for services that are specific to individual files. +- All previous subscriptions are replaced by the current set of +- subscriptions. If a given service is not included as a key in the map +- then no files will be subscribed to the service, exactly as if the +- service had been included in the map with an explicit empty list of +- files. +-

+-

+- Note that this request determines the set of requested +- subscriptions. The actual set of subscriptions at any given +- time is the intersection of this set with the set of files +- currently subject to analysis. The files currently subject +- to analysis are the set of files contained within an actual +- analysis root but not excluded, plus all of the files +- transitively reachable from those files via import, export +- and part directives. (See analysis.setAnalysisRoots for an +- explanation of how the actual analysis roots are +- determined.) When the actual analysis roots change, the +- actual set of subscriptions is automatically updated, but +- the set of requested subscriptions is unchanged. +-

+-

+- If a requested subscription is a directory it is ignored, +- but remains in the set of requested subscriptions so that if +- it later becomes a file it can be included in the set of +- actual subscriptions. +-

+-

+- It is an error if any of the keys in the map are not valid +- services. If there is an error, then the existing +- subscriptions will remain unchanged. +-

+- +-

parameters:

subscriptions: Map<AnalysisService, List<FilePath>>
+- +-

+- A table mapping services to a list of the files being +- subscribed to the service. +-

+-
analysis.updateContent
request: {
+-  "id": String
+-  "method": "analysis.updateContent"
+-  "params": {
+-    "files": Map<FilePath, AddContentOverlay | ChangeContentOverlay | RemoveContentOverlay>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-  }
+-}
+-

+- Update the content of one or more files. Files that were +- previously updated but not included in this update remain +- unchanged. This effectively represents an overlay of the +- filesystem. The files whose content is overridden are +- therefore seen by server as being files with the given +- content, even if the files do not exist on the filesystem or +- if the file path represents the path to a directory on the +- filesystem. +-

+- +- +-

parameters:

files: Map<FilePath, AddContentOverlay | ChangeContentOverlay | RemoveContentOverlay>
+- +-

+- A table mapping the files whose content has changed to a +- description of the content change. +-

+-

returns:

analysis.updateOptions
request: {
+-  "id": String
+-  "method": "analysis.updateOptions"
+-  "params": {
+-    "options": AnalysisOptions
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

Deprecated: all of the options can be set by users in +- an analysis options file.

+-

+- Update the options controlling analysis based on the given +- set of options. Any options that are not included in the +- analysis options will not be changed. If there are options +- in the analysis options that are not valid, they will be +- silently ignored. +-

+- +-

parameters:

options: AnalysisOptions
+- +-

+- The options that are to be used to control analysis. +-

+-

Notifications

analysis.analyzedFiles
notification: {
+-  "event": "analysis.analyzedFiles"
+-  "params": {
+-    "directories": List<FilePath>
+-  }
+-}
+-

+- Reports the paths of the files that are being analyzed. +-

+-

+- This notification is not subscribed to by default. Clients can +- subscribe by including the value "ANALYZED_FILES" in the list +- of services passed in an analysis.setGeneralSubscriptions request. +-

+- +-

parameters:

directories: List<FilePath>
+- +-

+- A list of the paths of the files that are being analyzed. +-

+-
analysis.errors
notification: {
+-  "event": "analysis.errors"
+-  "params": {
+-    "file": FilePath
+-    "errors": List<AnalysisError>
+-  }
+-}
+-

+- Reports the errors associated with a given file. The set of +- errors included in the notification is always a complete +- list that supersedes any previously reported errors. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file containing the errors. +-

+-
errors: List<AnalysisError>
+- +-

+- The errors contained in the file. +-

+-
analysis.flushResults
notification: {
+-  "event": "analysis.flushResults"
+-  "params": {
+-    "files": List<FilePath>
+-  }
+-}
+-

+- Reports that any analysis results that were previously +- associated with the given files should be considered to be +- invalid because those files are no longer being analyzed, +- either because the analysis root that contained it is no +- longer being analyzed or because the file no longer exists. +-

+-

+- If a file is included in this notification and at some later +- time a notification with results for the file is received, +- clients should assume that the file is once again being +- analyzed and the information should be processed. +-

+-

+- It is not possible to subscribe to or unsubscribe from this +- notification. +-

+- +-

parameters:

files: List<FilePath>
+- +-

+- The files that are no longer being analyzed. +-

+-
analysis.folding
notification: {
+-  "event": "analysis.folding"
+-  "params": {
+-    "file": FilePath
+-    "regions": List<FoldingRegion>
+-  }
+-}
+-

+- Reports the folding regions associated with a given +- file. Folding regions can be nested, but will not be +- overlapping. Nesting occurs when a foldable element, such as +- a method, is nested inside another foldable element such as +- a class. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "FOLDING" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file containing the folding regions. +-

+-
regions: List<FoldingRegion>
+- +-

+- The folding regions contained in the file. +-

+-
analysis.highlights
notification: {
+-  "event": "analysis.highlights"
+-  "params": {
+-    "file": FilePath
+-    "regions": List<HighlightRegion>
+-  }
+-}
+-

+- Reports the highlight regions associated with a given file. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "HIGHLIGHTS" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file containing the highlight regions. +-

+-
regions: List<HighlightRegion>
+- +-

+- The highlight regions contained in the file. Each +- highlight region represents a particular syntactic or +- semantic meaning associated with some range. Note that +- the highlight regions that are returned can overlap +- other highlight regions if there is more than one +- meaning associated with a particular region. +-

+-
analysis.implemented
notification: {
+-  "event": "analysis.implemented"
+-  "params": {
+-    "file": FilePath
+-    "classes": List<ImplementedClass>
+-    "members": List<ImplementedMember>
+-  }
+-}
+-

+- Reports the classes that are implemented or extended and +- class members that are implemented or overridden in a file. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "IMPLEMENTED" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file with which the implementations are associated. +-

+-
classes: List<ImplementedClass>
+- +-

+- The classes defined in the file that are implemented or extended. +-

+-
members: List<ImplementedMember>
+- +-

+- The member defined in the file that are implemented or overridden. +-

+-
analysis.invalidate
notification: {
+-  "event": "analysis.invalidate"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-    "length": int
+-    "delta": int
+-  }
+-}
+-

+- Reports that the navigation information associated with a region of a +- single file has become invalid and should be re-requested. +-

+-

+- This notification is not subscribed to by default. Clients can +- subscribe by including the value "INVALIDATE" in the list of +- services passed in an analysis.setSubscriptions request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file whose information has been invalidated. +-

+-
offset: int
+- +-

+- The offset of the invalidated region. +-

+-
length: int
+- +-

+- The length of the invalidated region. +-

+-
delta: int
+- +-

+- The delta to be applied to the offsets in information that follows +- the invalidated region in order to update it so that it doesn't +- need to be re-requested. +-

+-
analysis.navigation
notification: {
+-  "event": "analysis.navigation"
+-  "params": {
+-    "file": FilePath
+-    "regions": List<NavigationRegion>
+-    "targets": List<NavigationTarget>
+-    "files": List<FilePath>
+-  }
+-}
+-

+- Reports the navigation targets associated with a given file. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "NAVIGATION" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file containing the navigation regions. +-

+-
regions: List<NavigationRegion>
+- +-

+- The navigation regions contained in the file. +- The regions are sorted by their offsets. +- Each navigation region represents a list of targets +- associated with some range. The lists will usually +- contain a single target, but can contain more in the +- case of a part that is included in multiple libraries +- or in Dart code that is compiled against multiple +- versions of a package. Note that the navigation +- regions that are returned do not overlap other +- navigation regions. +-

+-
targets: List<NavigationTarget>
+- +-

+- The navigation targets referenced in the file. +- They are referenced by NavigationRegions by their +- index in this array. +-

+-
files: List<FilePath>
+- +-

+- The files containing navigation targets referenced in the file. +- They are referenced by NavigationTargets by their +- index in this array. +-

+-
analysis.occurrences
notification: {
+-  "event": "analysis.occurrences"
+-  "params": {
+-    "file": FilePath
+-    "occurrences": List<Occurrences>
+-  }
+-}
+-

+- Reports the occurrences of references to elements within a +- single file. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "OCCURRENCES" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file in which the references occur. +-

+-
occurrences: List<Occurrences>
+- +-

+- The occurrences of references to elements within the +- file. +-

+-
analysis.outline
notification: {
+-  "event": "analysis.outline"
+-  "params": {
+-    "file": FilePath
+-    "kind": FileKind
+-    "libraryName": optional String
+-    "outline": Outline
+-  }
+-}
+-

+- Reports the outline associated with a single file. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "OUTLINE" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file with which the outline is associated. +-

+-
kind: FileKind
+- +-

+- The kind of the file. +-

+-
libraryName: String (optional)
+- +-

+- The name of the library defined by the file using a "library" +- directive, or referenced by a "part of" directive. If both +- "library" and "part of" directives are present, then the +- "library" directive takes precedence. +- This field will be omitted if the file has neither "library" +- nor "part of" directives. +-

+-
outline: Outline
+- +-

+- The outline associated with the file. +-

+-
analysis.overrides
notification: {
+-  "event": "analysis.overrides"
+-  "params": {
+-    "file": FilePath
+-    "overrides": List<Override>
+-  }
+-}
+-

+- Reports the overriding members in a file. +-

+-

+- This notification is not subscribed to by default. Clients +- can subscribe by including the value "OVERRIDES" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file with which the overrides are associated. +-

+-
overrides: List<Override>
+- +-

+- The overrides associated with the file. +-

+-
+-

completion domain

+-

+- The code completion domain contains commands related to +- getting code completion suggestions. +-

+- +- +-

Requests

completion.getSuggestions
request: {
+-  "id": String
+-  "method": "completion.getSuggestions"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "id": CompletionId
+-  }
+-}
+-

+- Request that completion suggestions for the given offset in +- the given file be returned. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the point at which suggestions are +- to be made. +-

+-
offset: int
+- +-

+- The offset within the file at which suggestions are to +- be made. +-

+-

returns:

id: CompletionId
+- +-

+- The identifier used to associate results with this +- completion request. +-

+-

Notifications

completion.results
notification: {
+-  "event": "completion.results"
+-  "params": {
+-    "id": CompletionId
+-    "replacementOffset": int
+-    "replacementLength": int
+-    "results": List<CompletionSuggestion>
+-    "isLast": bool
+-  }
+-}
+-

+- Reports the completion suggestions that should be presented +- to the user. The set of suggestions included in the +- notification is always a complete list that supersedes any +- previously reported suggestions. +-

+- +-

parameters:

id: CompletionId
+- +-

+- The id associated with the completion. +-

+-
replacementOffset: int
+- +-

+- The offset of the start of the text to be +- replaced. This will be different than the offset used +- to request the completion suggestions if there was a +- portion of an identifier before the original +- offset. In particular, the replacementOffset will be +- the offset of the beginning of said identifier. +-

+-
replacementLength: int
+- +-

+- The length of the text to be replaced if the remainder +- of the identifier containing the cursor is to be +- replaced when the suggestion is applied (that is, the +- number of characters in the existing identifier). +-

+-
results: List<CompletionSuggestion>
+- +-

+- The completion suggestions being reported. The +- notification contains all possible completions at the +- requested cursor position, even those that do not match +- the characters the user has already typed. This allows +- the client to respond to further keystrokes from the +- user without having to make additional requests. +-

+-
isLast: bool
+- +-

+- True if this is that last set of results that will be +- returned for the indicated completion. +-

+-
+-

search domain

+-

+- The search domain contains commands related to searches that +- can be performed against the code base. +-

+- +- +- +- +- +- +-

Requests

search.findElementReferences
request: {
+-  "id": String
+-  "method": "search.findElementReferences"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-    "includePotential": bool
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "id": optional SearchId
+-    "element": optional Element
+-  }
+-}
+-

+- Perform a search for references to the element defined or +- referenced at the given offset in the given file. +-

+-

+- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the declaration of or reference to +- the element used to define the search. +-

+-
offset: int
+- +-

+- The offset within the file of the declaration of or +- reference to the element. +-

+-
includePotential: bool
+- +-

+- True if potential matches are to be included in the +- results. +-

+-

returns:

id: SearchId (optional)
+- +-

+- The identifier used to associate results with this +- search request. +-

+-

+- If no element was found at the given location, this +- field will be absent, and no results will be reported +- via the search.results notification. +-

+-
element: Element (optional)
+- +-

+- The element referenced or defined at the given offset +- and whose references will be returned in the search +- results. +-

+-

+- If no element was found at the given location, this +- field will be absent. +-

+-
search.findMemberDeclarations
request: {
+-  "id": String
+-  "method": "search.findMemberDeclarations"
+-  "params": {
+-    "name": String
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "id": SearchId
+-  }
+-}
+-

+- Perform a search for declarations of members whose name is +- equal to the given name. +-

+-

+- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

+- +- +-

parameters:

name: String
+- +-

+- The name of the declarations to be found. +-

+-

returns:

id: SearchId
+- +-

+- The identifier used to associate results with this +- search request. +-

+-
search.findMemberReferences
request: {
+-  "id": String
+-  "method": "search.findMemberReferences"
+-  "params": {
+-    "name": String
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "id": SearchId
+-  }
+-}
+-

+- Perform a search for references to members whose name is +- equal to the given name. This search does not check to see +- that there is a member defined with the given name, so it is +- able to find references to undefined members as well. +-

+-

+- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

+- +- +-

parameters:

name: String
+- +-

+- The name of the references to be found. +-

+-

returns:

id: SearchId
+- +-

+- The identifier used to associate results with this +- search request. +-

+-
search.findTopLevelDeclarations
request: {
+-  "id": String
+-  "method": "search.findTopLevelDeclarations"
+-  "params": {
+-    "pattern": String
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "id": SearchId
+-  }
+-}
+-

+- Perform a search for declarations of top-level elements +- (classes, typedefs, getters, setters, functions and fields) +- whose name matches the given pattern. +-

+-

+- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

+- +- +-

parameters:

pattern: String
+- +-

+- The regular expression used to match the names of the +- declarations to be found. +-

+-

returns:

id: SearchId
+- +-

+- The identifier used to associate results with this +- search request. +-

+-
search.getTypeHierarchy
request: {
+-  "id": String
+-  "method": "search.getTypeHierarchy"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-    "superOnly": optional bool
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "hierarchyItems": optional List<TypeHierarchyItem>
+-  }
+-}
+-

+- Return the type hierarchy of the class declared or +- referenced at the given location. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the declaration or reference to the +- type for which a hierarchy is being requested. +-

+-
offset: int
+- +-

+- The offset of the name of the type within the file. +-

+-
superOnly: bool (optional)
+- +-

+- True if the client is only requesting superclasses and +- interfaces hierarchy. +-

+-

returns:

hierarchyItems: List<TypeHierarchyItem> (optional)
+- +-

+- A list of the types in the requested hierarchy. The +- first element of the list is the item representing the +- type for which the hierarchy was requested. The index of +- other elements of the list is unspecified, but +- correspond to the integers used to reference supertype +- and subtype items within the items. +-

+-

+- This field will be absent if the code at the given file +- and offset does not represent a type, or if the file has +- not been sufficiently analyzed to allow a type hierarchy +- to be produced. +-

+-

Notifications

search.results
notification: {
+-  "event": "search.results"
+-  "params": {
+-    "id": SearchId
+-    "results": List<SearchResult>
+-    "isLast": bool
+-  }
+-}
+-

+- Reports some or all of the results of performing a requested +- search. Unlike other notifications, this notification +- contains search results that should be added to any +- previously received search results associated with the same +- search id. +-

+- +-

parameters:

id: SearchId
+- +-

+- The id associated with the search. +-

+-
results: List<SearchResult>
+- +-

+- The search results being reported. +-

+-
isLast: bool
+- +-

+- True if this is that last set of results that will be +- returned for the indicated search. +-

+-
+-

edit domain

+-

+- The edit domain contains commands related to edits that can be +- applied to the code. +-

+- +- +- +- +- +- +- +- +- +- +- +- +-

Requests

edit.format
request: {
+-  "id": String
+-  "method": "edit.format"
+-  "params": {
+-    "file": FilePath
+-    "selectionOffset": int
+-    "selectionLength": int
+-    "lineLength": optional int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "edits": List<SourceEdit>
+-    "selectionOffset": int
+-    "selectionLength": int
+-  }
+-}
+-

+- Format the contents of a single file. The currently selected region of +- text is passed in so that the selection can be preserved across the +- formatting operation. The updated selection will be as close to +- matching the original as possible, but whitespace at the beginning or +- end of the selected region will be ignored. If preserving selection +- information is not required, zero (0) can be specified for both the +- selection offset and selection length. +-

+-

+- If a request is made for a file which does not exist, or which is not +- currently subject to analysis (e.g. because it is not associated with +- any analysis root specified to analysis.setAnalysisRoots), an error of +- type FORMAT_INVALID_FILE will be generated. If the source +- contains syntax errors, an error of type FORMAT_WITH_ERRORS +- will be generated. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the code to be formatted. +-

+-
selectionOffset: int
+- +-

+- The offset of the current selection in the file. +-

+-
selectionLength: int
+- +-

+- The length of the current selection in the file. +-

+-
lineLength: int (optional)
+- +-

+- The line length to be used by the formatter. +-

+-

returns:

edits: List<SourceEdit>
+- +-

+- The edit(s) to be applied in order to format the code. The list +- will be empty if the code was already formatted (there are no +- changes). +-

+-
selectionOffset: int
+- +-

+- The offset of the selection after formatting the code. +-

+-
selectionLength: int
+- +-

+- The length of the selection after formatting the code. +-

+-
edit.getAssists
request: {
+-  "id": String
+-  "method": "edit.getAssists"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-    "length": int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "assists": List<SourceChange>
+-  }
+-}
+-

+- Return the set of assists that are available at the given +- location. An assist is distinguished from a refactoring +- primarily by the fact that it affects a single file and does +- not require user input in order to be performed. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the code for which assists are being +- requested. +-

+-
offset: int
+- +-

+- The offset of the code for which assists are being +- requested. +-

+-
length: int
+- +-

+- The length of the code for which assists are being +- requested. +-

+-

returns:

assists: List<SourceChange>
+- +-

+- The assists that are available at the given location. +-

+-
edit.getAvailableRefactorings
request: {
+-  "id": String
+-  "method": "edit.getAvailableRefactorings"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-    "length": int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "kinds": List<RefactoringKind>
+-  }
+-}
+-

+- Get a list of the kinds of refactorings that are valid for +- the given selection in the given file. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the code on which the refactoring +- would be based. +-

+-
offset: int
+- +-

+- The offset of the code on which the refactoring would be +- based. +-

+-
length: int
+- +-

+- The length of the code on which the refactoring would be +- based. +-

+-

returns:

kinds: List<RefactoringKind>
+- +-

+- The kinds of refactorings that are valid for the given +- selection. +-

+-
edit.getFixes
request: {
+-  "id": String
+-  "method": "edit.getFixes"
+-  "params": {
+-    "file": FilePath
+-    "offset": int
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "fixes": List<AnalysisErrorFixes>
+-  }
+-}
+-

+- Return the set of fixes that are available for the errors at +- a given offset in a given file. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The file containing the errors for which fixes are being +- requested. +-

+-
offset: int
+- +-

+- The offset used to select the errors for which fixes +- will be returned. +-

+-

returns:

fixes: List<AnalysisErrorFixes>
+- +-

+- The fixes that are available for the errors at the given offset. +-

+-
edit.getRefactoring
request: {
+-  "id": String
+-  "method": "edit.getRefactoring"
+-  "params": {
+-    "kind": RefactoringKind
+-    "file": FilePath
+-    "offset": int
+-    "length": int
+-    "validateOnly": bool
+-    "options": optional RefactoringOptions
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "initialProblems": List<RefactoringProblem>
+-    "optionsProblems": List<RefactoringProblem>
+-    "finalProblems": List<RefactoringProblem>
+-    "feedback": optional RefactoringFeedback
+-    "change": optional SourceChange
+-    "potentialEdits": optional List<String>
+-  }
+-}
+-

+- Get the changes required to perform a refactoring. +-

+-

+- If another refactoring request is received during the processing +- of this one, an error of type REFACTORING_REQUEST_CANCELLED +- will be generated. +-

+- +- +-

parameters:

kind: RefactoringKind
+- +-

+- The kind of refactoring to be performed. +-

+-
file: FilePath
+- +-

+- The file containing the code involved in the +- refactoring. +-

+-
offset: int
+- +-

+- The offset of the region involved in the refactoring. +-

+-
length: int
+- +-

+- The length of the region involved in the refactoring. +-

+-
validateOnly: bool
+- +-

+- True if the client is only requesting that the values of +- the options be validated and no change be generated. +-

+-
options: RefactoringOptions (optional)
+- +-

+- Data used to provide values provided by the user. The +- structure of the data is dependent on the kind of +- refactoring being performed. The data that is expected is +- documented in the section titled Refactorings, labeled as +- "Options". This field can be omitted if the refactoring +- does not require any options or if the values of those +- options are not known. +-

+-

returns:

initialProblems: List<RefactoringProblem>
+- +-

+- The initial status of the refactoring, i.e. problems related to +- the context in which the refactoring is requested. +- The array will be empty if there are no known problems. +-

+-
optionsProblems: List<RefactoringProblem>
+- +-

+- The options validation status, i.e. problems in the given options, +- such as light-weight validation of a new name, flags +- compatibility, etc. +- The array will be empty if there are no known problems. +-

+-
finalProblems: List<RefactoringProblem>
+- +-

+- The final status of the refactoring, i.e. problems identified in +- the result of a full, potentially expensive validation and / or +- change creation. +- The array will be empty if there are no known problems. +-

+-
feedback: RefactoringFeedback (optional)
+- +-

+- Data used to provide feedback to the user. The structure +- of the data is dependent on the kind of refactoring +- being created. The data that is returned is documented +- in the section titled Refactorings, labeled as +- "Feedback". +-

+-
change: SourceChange (optional)
+- +-

+- The changes that are to be applied to affect the +- refactoring. This field will be omitted if there are +- problems that prevent a set of changes from being +- computed, such as having no options specified for a +- refactoring that requires them, or if only validation +- was requested. +-

+-
potentialEdits: List<String> (optional)
+- +-

+- The ids of source edits that are not known to be valid. An edit is +- not known to be valid if there was insufficient type information +- for the server to be able to determine whether or not the code +- needs to be modified, such as when a member is being renamed and +- there is a reference to a member from an unknown type. This field +- will be omitted if the change field is omitted or if there are no +- potential edits for the refactoring. +-

+-
edit.sortMembers
request: {
+-  "id": String
+-  "method": "edit.sortMembers"
+-  "params": {
+-    "file": FilePath
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "edit": SourceFileEdit
+-  }
+-}
+-

+- Sort all of the directives, unit and class members +- of the given Dart file. +-

+-

+- If a request is made for a file that does not exist, does not belong +- to an analysis root or is not a Dart file, +- SORT_MEMBERS_INVALID_FILE will be generated. +-

+-

+- If the Dart file has scan or parse errors, +- SORT_MEMBERS_PARSE_ERRORS will be generated. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The Dart file to sort. +-

+-

returns:

edit: SourceFileEdit
+- +-

+- The file edit that is to be applied to the given file to effect +- the sorting. +-

+-
edit.organizeDirectives
request: {
+-  "id": String
+-  "method": "edit.organizeDirectives"
+-  "params": {
+-    "file": FilePath
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "edit": SourceFileEdit
+-  }
+-}
+-

+- Organizes all of the directives - removes unused imports and sorts +- directives of the given Dart file according to the +- Dart Style +- Guide. +-

+-

+- If a request is made for a file that does not exist, does not belong +- to an analysis root or is not a Dart file, +- FILE_NOT_ANALYZED will be generated. +-

+-

+- If directives of the Dart file cannot be organized, for example +- because it has scan or parse errors, or by other reasons, +- ORGANIZE_DIRECTIVES_ERROR will be generated. The message +- will provide details about the reason. +-

+- +- +-

parameters:

file: FilePath
+- +-

+- The Dart file to organize directives in. +-

+-

returns:

edit: SourceFileEdit
+- +-

+- The file edit that is to be applied to the given file to effect +- the organizing. +-

+-
+-

execution domain

+-

+- The execution domain contains commands related to providing an execution +- or debugging experience. +-

+- +- +- +- +- +-

Requests

execution.createContext
request: {
+-  "id": String
+-  "method": "execution.createContext"
+-  "params": {
+-    "contextRoot": FilePath
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "id": ExecutionContextId
+-  }
+-}
+-

+- Create an execution context for the executable file with the given +- path. The context that is created will persist until +- execution.deleteContext is used to delete it. Clients, therefore, are +- responsible for managing the lifetime of execution contexts. +-

+- +- +-

parameters:

contextRoot: FilePath
+- +-

+- The path of the Dart or HTML file that will be launched, or the +- path of the directory containing the file. +-

+-

returns:

id: ExecutionContextId
+- +-

+- The identifier used to refer to the execution context that was +- created. +-

+-
execution.deleteContext
request: {
+-  "id": String
+-  "method": "execution.deleteContext"
+-  "params": {
+-    "id": ExecutionContextId
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Delete the execution context with the given identifier. The context id +- is no longer valid after this command. The server is allowed to re-use +- ids when they are no longer valid. +-

+- +-

parameters:

id: ExecutionContextId
+- +-

+- The identifier of the execution context that is to be deleted. +-

+-
execution.mapUri
request: {
+-  "id": String
+-  "method": "execution.mapUri"
+-  "params": {
+-    "id": ExecutionContextId
+-    "file": optional FilePath
+-    "uri": optional String
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "file": optional FilePath
+-    "uri": optional String
+-  }
+-}
+-

+- Map a URI from the execution context to the file that it corresponds +- to, or map a file to the URI that it corresponds to in the execution +- context. +-

+-

+- Exactly one of the file and uri fields must be provided. If both +- fields are provided, then an error of type INVALID_PARAMETER +- will be generated. Similarly, if neither field is provided, then an +- error of type INVALID_PARAMETER will be generated. +-

+-

+- If the file field is provided and the value is not the path of a file +- (either the file does not exist or the path references something other +- than a file), then an error of type INVALID_PARAMETER will +- be generated. +-

+-

+- If the uri field is provided and the value is not a valid URI or if +- the URI references something that is not a file (either a file that +- does not exist or something other than a file), then an error of type +- INVALID_PARAMETER will be generated. +-

+-

+- If the contextRoot used to create the execution context does not +- exist, then an error of type INVALID_EXECUTION_CONTEXT will +- be generated. +-

+- +- +-

parameters:

id: ExecutionContextId
+- +-

+- The identifier of the execution context in which the URI is to be +- mapped. +-

+-
file: FilePath (optional)
+- +-

+- The path of the file to be mapped into a URI. +-

+-
uri: String (optional)
+- +-

+- The URI to be mapped into a file path. +-

+-

returns:

file: FilePath (optional)
+- +-

+- The file to which the URI was mapped. This field is omitted if the +- uri field was not given in the request. +-

+-
uri: String (optional)
+- +-

+- The URI to which the file path was mapped. This field is omitted +- if the file field was not given in the request. +-

+-
execution.setSubscriptions
request: {
+-  "id": String
+-  "method": "execution.setSubscriptions"
+-  "params": {
+-    "subscriptions": List<ExecutionService>
+-  }
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-}
+-

+- Deprecated: the analysis server no longer fires +- LAUNCH_DATA events. +-

+-

+- Subscribe for services. All previous subscriptions are replaced by the +- given set of services. +-

+-

+- It is an error if any of the elements in the list are not valid +- services. If there is an error, then the current subscriptions will +- remain unchanged. +-

+- +-

parameters:

subscriptions: List<ExecutionService>
+- +-

+- A list of the services being subscribed to. +-

+-

Notifications

execution.launchData
notification: {
+-  "event": "execution.launchData"
+-  "params": {
+-    "file": FilePath
+-    "kind": optional ExecutableKind
+-    "referencedFiles": optional List<FilePath>
+-  }
+-}
+-

+- Reports information needed to allow a single file to be launched. +-

+-

+- This notification is not subscribed to by default. Clients can +- subscribe by including the value "LAUNCH_DATA" in the list of services +- passed in an execution.setSubscriptions request. +-

+- +-

parameters:

file: FilePath
+- +-

+- The file for which launch data is being provided. This will either +- be a Dart library or an HTML file. +-

+-
kind: ExecutableKind (optional)
+- +-

+- The kind of the executable file. This field is omitted if the file +- is not a Dart file. +-

+-
referencedFiles: List<FilePath> (optional)
+- +-

+- A list of the Dart files that are referenced by the file. This +- field is omitted if the file is not an HTML file. +-

+-
+-

diagnostic domain

+-

+- The diagnostic domain contains server diagnostics APIs. +-

+- +- +-

Requests

diagnostic.getDiagnostics
request: {
+-  "id": String
+-  "method": "diagnostic.getDiagnostics"
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "contexts": List<ContextData>
+-  }
+-}
+-

Return server diagnostics.

+- +-

returns:

contexts: List<ContextData>
+- +-

The list of analysis contexts.

+-
diagnostic.getServerPort
request: {
+-  "id": String
+-  "method": "diagnostic.getServerPort"
+-}

response: {
+-  "id": String
+-  "error": optional RequestError
+-  "result": {
+-    "port": int
+-  }
+-}
+-

+- Return the port of the diagnostic web server. If the server is not running +- this call will start the server. If unable to start the diagnostic web +- server, +- this call will return an error of DEBUG_PORT_COULD_NOT_BE_OPENED. +-

+- +-

returns:

port: int
+- +-

The diagnostic server port.

+-
+- +- +- +-

Types

+-

+- This section contains descriptions of the data types referenced +- in the API’s of the various domains. +-

+- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-
AddContentOverlay: object
+-

+- A directive to begin overlaying the contents of a file. The supplied +- content will be used for analysis in place of the file contents in the +- filesystem. +-

+-

+- If this directive is used on a file that already has a file content +- overlay, the old overlay is discarded and replaced with the new one. +-

+- +-
type = "add"
+- +-
content: String
+- +-

+- The new content of the file. +-

+-
AnalysisError: object
+-

+- An indication of an error, warning, or hint that was produced by the +- analysis. +-

+- +-
severity: AnalysisErrorSeverity
+- +-

+- The severity of the error. +-

+-
type: AnalysisErrorType
+- +-

+- The type of the error. +-

+-
location: Location
+- +-

+- The location associated with the error. +-

+-
message: String
+- +-

+- The message to be displayed for this error. The message should +- indicate what is wrong with the code and why it is wrong. +-

+-
correction: String (optional)
+- +-

+- The correction message to be displayed for this error. The correction +- message should indicate how the user can fix the error. The field is +- omitted if there is no correction message associated with the error +- code. +-

+-
code: String
+- +-

+- The name, as a string, of the error code associated with this error. +-

+-
hasFix: bool (optional)
+- +-

+- A hint to indicate to interested clients that this error has an +- associated fix (or fixes). The absence of this field implies there +- are not known to be fixes. Note that since the operation to calculate +- whether fixes apply needs to be performant it is possible that +- complicated tests will be skipped and a false negative returned. For +- this reason, this attribute should be treated as a "hint". Despite the +- possibility of false negatives, no false positives should be returned. +- If a client sees this flag set they can proceed with the confidence +- that there are in fact associated fixes. +-

+-
AnalysisErrorFixes: object
+-

+- A list of fixes associated with a specific error. +-

+- +-
error: AnalysisError
+- +-

+- The error with which the fixes are associated. +-

+-
fixes: List<SourceChange>
+- +-

+- The fixes associated with the error. +-

+-
AnalysisErrorSeverity: String
+-

+- An enumeration of the possible severities of analysis errors. +-

+- +-
INFO
WARNING
ERROR
AnalysisErrorType: String
+-

+- An enumeration of the possible types of analysis errors. +-

+- +-
CHECKED_MODE_COMPILE_TIME_ERROR
COMPILE_TIME_ERROR
HINT
LINT
STATIC_TYPE_WARNING
STATIC_WARNING
SYNTACTIC_ERROR
TODO
AnalysisOptions: object
+-

Deprecated: the only reference to this type has been +- deprecated.

+-

+- A set of options controlling what kind of analysis is to be +- performed. If the value of a field is omitted the value of the +- option will not be changed. +-

+- +-
enableAsync: bool (optional)
+- +-

Deprecated: this feature is always enabled.

+-

+- True if the client wants to enable support for the +- proposed async feature. +-

+-
enableDeferredLoading: bool (optional)
+- +-

Deprecated: this feature is always enabled.

+-

+- True if the client wants to enable support for the +- proposed deferred loading feature. +-

+-
enableEnums: bool (optional)
+- +-

Deprecated: this feature is always enabled.

+-

+- True if the client wants to enable support for the +- proposed enum feature. +-

+-
enableNullAwareOperators: bool (optional)
+- +-

Deprecated: this feature is always enabled.

+-

+- True if the client wants to enable support for the +- proposed "null aware operators" feature. +-

+-
enableSuperMixins: bool (optional)
+- +-

+- True if the client wants to enable support for the +- proposed "less restricted mixins" proposal (DEP 34). +-

+-
generateDart2jsHints: bool (optional)
+- +-

+- True if hints that are specific to dart2js should be +- generated. This option is ignored if generateHints is false. +-

+-
generateHints: bool (optional)
+- +-

+- True if hints should be generated as part of generating +- errors and warnings. +-

+-
generateLints: bool (optional)
+- +-

+- True if lints should be generated as part of generating +- errors and warnings. +-

+-
AnalysisService: String
+-

+- An enumeration of the services provided by the analysis domain that +- are related to a specific list of files. +-

+- +-
CLOSING_LABELS
FOLDING
HIGHLIGHTS
IMPLEMENTED
INVALIDATE
+- +-

+- This service is not currently implemented and will become a +- GeneralAnalysisService in a future release. +-

+-
NAVIGATION
OCCURRENCES
OUTLINE
OVERRIDES
AnalysisStatus: object
+-

+- An indication of the current state of analysis. +-

+- +-
isAnalyzing: bool
+- +-

True if analysis is currently being performed.

+-
analysisTarget: String (optional)
+- +-

+- The name of the current target of analysis. This field is +- omitted if analyzing is false. +-

+-
ChangeContentOverlay: object
+-

+- A directive to modify an existing file content overlay. One or more ranges +- of text are deleted from the old file content overlay and replaced with +- new text. +-

+-

+- The edits are applied in the order in which they occur in the list. This +- means that the offset of each edit must be correct under the assumption +- that all previous edits have been applied. +-

+-

+- It is an error to use this overlay on a file that does not yet have a file +- content overlay or that has had its overlay removed via +- RemoveContentOverlay. +-

+-

+- If any of the edits cannot be applied due to its offset or length being +- out of range, an INVALID_OVERLAY_CHANGE error will be reported. +-

+- +-
type = "change"
+- +-
edits: List<SourceEdit>
+- +-

+- The edits to be applied to the file. +-

+-
ClosingLabel: object
+-

+- A label that is associated with a range of code that may be useful to +- render at the end of the range to aid code readability. For example, a +- constructor call that spans multiple lines may result in a closing label +- to allow the constructor type/name to be rendered alongside the closing +- parenthesis. +-

+- +-
offset: int
+- +-

+- The offset of the construct being labelled. +-

+-
length: int
+- +-

+- The length of the whole construct to be labelled. +-

+-
label: String
+- +-

+- The label associated with this range that should be displayed to the +- user. +-

+-
CompletionId: String
+- +-

+- An identifier used to associate completion results with a +- completion request. +-

+-
CompletionSuggestion: object
+-

+- A suggestion for how to complete partially entered text. Many of the +- fields are optional, depending on the kind of element being suggested. +-

+- +-
kind: CompletionSuggestionKind
+- +-

+- The kind of element being suggested. +-

+-
relevance: int
+- +-

+- The relevance of this completion suggestion where a higher number +- indicates a higher relevance. +-

+-
completion: String
+- +-

+- The identifier to be inserted if the suggestion is selected. If the +- suggestion is for a method or function, the client might want to +- additionally insert a template for the parameters. The information +- required in order to do so is contained in other fields. +-

+-
selectionOffset: int
+- +-

+- The offset, relative to the beginning of the completion, of where the +- selection should be placed after insertion. +-

+-
selectionLength: int
+- +-

+- The number of characters that should be selected after insertion. +-

+-
isDeprecated: bool
+- +-

+- True if the suggested element is deprecated. +-

+-
isPotential: bool
+- +-

+- True if the element is not known to be valid for the target. This +- happens if the type of the target is dynamic. +-

+-
docSummary: String (optional)
+- +-

+- An abbreviated version of the Dartdoc associated with the element +- being suggested, This field is omitted if there is no Dartdoc +- associated with the element. +-

+-
docComplete: String (optional)
+- +-

+- The Dartdoc associated with the element being suggested. This field is +- omitted if there is no Dartdoc associated with the element. +-

+-
declaringType: String (optional)
+- +-

+- The class that declares the element being suggested. This field is +- omitted if the suggested element is not a member of a class. +-

+-
defaultArgumentListString: String (optional)
+- +-

+- A default String for use in generating argument list source contents +- on the client side. +-

+-
defaultArgumentListTextRanges: List<int> (optional)
+- +-

+- Pairs of offsets and lengths describing 'defaultArgumentListString' +- text ranges suitable for use by clients to set up linked edits of +- default argument source contents. For example, given an argument list +- string 'x, y', the corresponding text range [0, 1, 3, 1], indicates +- two text ranges of length 1, starting at offsets 0 and 3. Clients can +- use these ranges to treat the 'x' and 'y' values specially for linked +- edits. +-

+-
element: Element (optional)
+- +-

+- Information about the element reference being suggested. +-

+-
returnType: String (optional)
+- +-

+- The return type of the getter, function or method or the type of the +- field being suggested. This field is omitted if the suggested element +- is not a getter, function or method. +-

+-
parameterNames: List<String> (optional)
+- +-

+- The names of the parameters of the function or method being suggested. +- This field is omitted if the suggested element is not a setter, +- function or method. +-

+-
parameterTypes: List<String> (optional)
+- +-

+- The types of the parameters of the function or method being suggested. +- This field is omitted if the parameterNames field is omitted. +-

+-
requiredParameterCount: int (optional)
+- +-

+- The number of required parameters for the function or method being +- suggested. This field is omitted if the parameterNames field is +- omitted. +-

+-
hasNamedParameters: bool (optional)
+- +-

+- True if the function or method being suggested has at least one named +- parameter. This field is omitted if the parameterNames field is +- omitted. +-

+-
parameterName: String (optional)
+- +-

+- The name of the optional parameter being suggested. This field is +- omitted if the suggestion is not the addition of an optional argument +- within an argument list. +-

+-
parameterType: String (optional)
+- +-

+- The type of the options parameter being suggested. This field is +- omitted if the parameterName field is omitted. +-

+-
importUri: String (optional)
+- +-

+- The import to be added if the suggestion is out of scope and needs +- an import to be added to be in scope. +-

+-
CompletionSuggestionKind: String
+-

+- An enumeration of the kinds of elements that can be included in a +- completion suggestion. +-

+- +-
ARGUMENT_LIST
+- +-

+- A list of arguments for the method or function that is being +- invoked. For this suggestion kind, the completion field is a +- textual representation of the invocation and the parameterNames, +- parameterTypes, and requiredParameterCount attributes are defined. +-

+-
IMPORT
IDENTIFIER
+- +-

+- The element identifier should be inserted at the completion +- location. For example "someMethod" in import 'myLib.dart' show +- someMethod;. For suggestions of this kind, the element +- attribute is defined and the completion field is the element's +- identifier. +-

+-
INVOCATION
+- +-

+- The element is being invoked at the completion location. For +- example, 'someMethod' in x.someMethod();. For suggestions +- of this kind, the element attribute is defined and the completion +- field is the element's identifier. +-

+-
KEYWORD
+- +-

+- A keyword is being suggested. For suggestions of this kind, the +- completion is the keyword. +-

+-
NAMED_ARGUMENT
+- +-

+- A named argument for the current call site is being suggested. For +- suggestions of this kind, the completion is the named argument +- identifier including a trailing ':' and a space. +-

+-
OPTIONAL_ARGUMENT
PARAMETER
ContextData: object
+-

+- Information about an analysis context. +-

+- +-
name: String
+- +-

+- The name of the context. +-

+-
explicitFileCount: int
+- +-

+- Explicitly analyzed files. +-

+-
implicitFileCount: int
+- +-

+- Implicitly analyzed files. +-

+-
workItemQueueLength: int
+- +-

+- The number of work items in the queue. +-

+-
cacheEntryExceptions: List<String>
+- +-

+- Exceptions associated with cache entries. +-

+-
Element: object
+-

+- Information about an element (something that can be declared in code). +-

+- +-
kind: ElementKind
+- +-

+- The kind of the element. +-

+-
name: String
+- +-

+- The name of the element. This is typically used as the label in the +- outline. +-

+-
location: Location (optional)
+- +-

+- The location of the name in the declaration of the element. +-

+-
flags: int
+- +-

+- A bit-map containing the following flags: +-

+-
    +-
  • +- 0x01 - set if the element is explicitly or implicitly abstract +-
  • +-
  • +- 0x02 - set if the element was declared to be ‘const’ +-
  • +-
  • +- 0x04 - set if the element was declared to be ‘final’ +-
  • +-
  • +- 0x08 - set if the element is a static member of a class or is a +- top-level function or field +-
  • +-
  • +- 0x10 - set if the element is private +-
  • +-
  • +- 0x20 - set if the element is deprecated +-
  • +-
+-
parameters: String (optional)
+- +-

+- The parameter list for the element. If the element is not a method or +- function this field will not be defined. If the element doesn't have +- parameters (e.g. getter), this field will not be defined. If the +- element has zero parameters, this field will have a value of "()". +-

+-
returnType: String (optional)
+- +-

+- The return type of the element. If the element is not a method or +- function this field will not be defined. If the element does not have +- a declared return type, this field will contain an empty string. +-

+-
typeParameters: String (optional)
+- +-

+- The type parameter list for the element. If the element doesn't have +- type parameters, this field will not be defined. +-

+-
ElementKind: String
+-

+- An enumeration of the kinds of elements. +-

+- +-
CLASS
CLASS_TYPE_ALIAS
COMPILATION_UNIT
CONSTRUCTOR
CONSTRUCTOR_INVOCATION
ENUM
ENUM_CONSTANT
FIELD
FILE
FUNCTION
FUNCTION_INVOCATION
FUNCTION_TYPE_ALIAS
GETTER
LABEL
LIBRARY
LOCAL_VARIABLE
METHOD
PARAMETER
PREFIX
SETTER
TOP_LEVEL_VARIABLE
TYPE_PARAMETER
UNIT_TEST_GROUP
UNIT_TEST_TEST
UNKNOWN
ExecutableFile: object
+-

+- A description of an executable file. +-

+- +-
file: FilePath
+- +-

+- The path of the executable file. +-

+-
kind: ExecutableKind
+- +-

+- The kind of the executable file. +-

+-
ExecutableKind: String
+-

+- An enumeration of the kinds of executable files. +-

+- +-
CLIENT
EITHER
NOT_EXECUTABLE
SERVER
ExecutionContextId: String
+- +-

+- The identifier for a execution context. +-

+-
ExecutionService: String
+-

+- An enumeration of the services provided by the execution +- domain. +-

+- +-
LAUNCH_DATA
FileKind: String
+-

+- An enumeration of the kinds of files. +-

+- +-
LIBRARY
PART
FilePath: String
+- +-

+- The absolute, normalized path of a file. +-

+-

+- If the format of a file path in a request is not valid, e.g. the path is +- not absolute or is not normalized, then an error of type +- INVALID_FILE_PATH_FORMAT will be generated. +-

+-
FoldingKind: String
+-

+- An enumeration of the kinds of folding regions. +-

+- +-
COMMENT
CLASS_MEMBER
DIRECTIVES
DOCUMENTATION_COMMENT
TOP_LEVEL_DECLARATION
FoldingRegion: object
+-

+- A description of a region that can be folded. +-

+- +-
kind: FoldingKind
+- +-

+- The kind of the region. +-

+-
offset: int
+- +-

+- The offset of the region to be folded. +-

+-
length: int
+- +-

+- The length of the region to be folded. +-

+-
GeneralAnalysisService: String
+-

+- An enumeration of the services provided by the analysis domain that are +- general in nature (that is, are not specific to some list of files). +-

+- +-
ANALYZED_FILES
HighlightRegion: object
+-

+- A description of a region that could have special highlighting associated +- with it. +-

+- +-
type: HighlightRegionType
+- +-

+- The type of highlight associated with the region. +-

+-
offset: int
+- +-

+- The offset of the region to be highlighted. +-

+-
length: int
+- +-

+- The length of the region to be highlighted. +-

+-
HighlightRegionType: String
+-

+- An enumeration of the kinds of highlighting that can be applied to files. +-

+- +-
ANNOTATION
BUILT_IN
CLASS
COMMENT_BLOCK
COMMENT_DOCUMENTATION
COMMENT_END_OF_LINE
CONSTRUCTOR
DIRECTIVE
DYNAMIC_TYPE
+- +-

Only for version 1 of highlight.

+-
DYNAMIC_LOCAL_VARIABLE_DECLARATION
+- +-

Only for version 2 of highlight.

+-
DYNAMIC_LOCAL_VARIABLE_REFERENCE
+- +-

Only for version 2 of highlight.

+-
DYNAMIC_PARAMETER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
DYNAMIC_PARAMETER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
ENUM
ENUM_CONSTANT
FIELD
+- +-

Only for version 1 of highlight.

+-
FIELD_STATIC
+- +-

Only for version 1 of highlight.

+-
FUNCTION
+- +-

Only for version 1 of highlight.

+-
FUNCTION_DECLARATION
+- +-

Only for version 1 of highlight.

+-
FUNCTION_TYPE_ALIAS
GETTER_DECLARATION
+- +-

Only for version 1 of highlight.

+-
IDENTIFIER_DEFAULT
IMPORT_PREFIX
INSTANCE_FIELD_DECLARATION
+- +-

Only for version 2 of highlight.

+-
INSTANCE_FIELD_REFERENCE
+- +-

Only for version 2 of highlight.

+-
INSTANCE_GETTER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
INSTANCE_GETTER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
INSTANCE_METHOD_DECLARATION
+- +-

Only for version 2 of highlight.

+-
INSTANCE_METHOD_REFERENCE
+- +-

Only for version 2 of highlight.

+-
INSTANCE_SETTER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
INSTANCE_SETTER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
INVALID_STRING_ESCAPE
+- +-

Only for version 2 of highlight.

+-
KEYWORD
LABEL
LIBRARY_NAME
+- +-

Only for version 2 of highlight.

+-
LITERAL_BOOLEAN
LITERAL_DOUBLE
LITERAL_INTEGER
LITERAL_LIST
LITERAL_MAP
LITERAL_STRING
LOCAL_FUNCTION_DECLARATION
+- +-

Only for version 2 of highlight.

+-
LOCAL_FUNCTION_REFERENCE
+- +-

Only for version 2 of highlight.

+-
LOCAL_VARIABLE
+- +-

Only for version 1 of highlight.

+-
LOCAL_VARIABLE_DECLARATION
LOCAL_VARIABLE_REFERENCE
+- +-

Only for version 2 of highlight.

+-
METHOD
+- +-

Only for version 1 of highlight.

+-
METHOD_DECLARATION
+- +-

Only for version 1 of highlight.

+-
METHOD_DECLARATION_STATIC
+- +-

Only for version 1 of highlight.

+-
METHOD_STATIC
+- +-

Only for version 1 of highlight.

+-
PARAMETER
+- +-

Only for version 1 of highlight.

+-
SETTER_DECLARATION
+- +-

Only for version 1 of highlight.

+-
TOP_LEVEL_VARIABLE
+- +-

Only for version 1 of highlight.

+-
PARAMETER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
PARAMETER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
STATIC_FIELD_DECLARATION
+- +-

Only for version 2 of highlight.

+-
STATIC_GETTER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
STATIC_GETTER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
STATIC_METHOD_DECLARATION
+- +-

Only for version 2 of highlight.

+-
STATIC_METHOD_REFERENCE
+- +-

Only for version 2 of highlight.

+-
STATIC_SETTER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
STATIC_SETTER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_FUNCTION_DECLARATION
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_FUNCTION_REFERENCE
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_GETTER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_GETTER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_SETTER_DECLARATION
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_SETTER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
TOP_LEVEL_VARIABLE_DECLARATION
+- +-

Only for version 2 of highlight.

+-
TYPE_NAME_DYNAMIC
TYPE_PARAMETER
UNRESOLVED_INSTANCE_MEMBER_REFERENCE
+- +-

Only for version 2 of highlight.

+-
VALID_STRING_ESCAPE
+- +-

Only for version 2 of highlight.

+-
HoverInformation: object
+-

+- The hover information associated with a specific location. +-

+- +-
offset: int
+- +-

+- The offset of the range of characters that encompasses the +- cursor position and has the same hover information as the +- cursor position. +-

+-
length: int
+- +-

+- The length of the range of characters that encompasses the +- cursor position and has the same hover information as the +- cursor position. +-

+-
containingLibraryPath: String (optional)
+- +-

+- The path to the defining compilation unit of the library +- in which the referenced element is declared. This data is +- omitted if there is no referenced element, or if the +- element is declared inside an HTML file. +-

+-
containingLibraryName: String (optional)
+- +-

+- The name of the library in which the referenced element is +- declared. This data is omitted if there is no referenced +- element, or if the element is declared inside an HTML +- file. +-

+-
containingClassDescription: String (optional)
+- +-

+- A human-readable description of the class declaring the element +- being referenced. This data is omitted if there is no referenced +- element, or if the element is not a class member. +-

+-
dartdoc: String (optional)
+- +-

+- The dartdoc associated with the referenced element. Other +- than the removal of the comment delimiters, including +- leading asterisks in the case of a block comment, the +- dartdoc is unprocessed markdown. This data is omitted if +- there is no referenced element, or if the element has no +- dartdoc. +-

+-
elementDescription: String (optional)
+- +-

+- A human-readable description of the element being +- referenced. This data is omitted if there is no referenced +- element. +-

+-
elementKind: String (optional)
+- +-

+- A human-readable description of the kind of element being +- referenced (such as "class" or "function type +- alias"). This data is omitted if there is no referenced +- element. +-

+-
isDeprecated: bool (optional)
+- +-

+- True if the referenced element is deprecated. +-

+-
parameter: String (optional)
+- +-

+- A human-readable description of the parameter +- corresponding to the expression being hovered over. This +- data is omitted if the location is not in an argument to a +- function. +-

+-
propagatedType: String (optional)
+- +-

+- The name of the propagated type of the expression. This +- data is omitted if the location does not correspond to an +- expression or if there is no propagated type information. +-

+-
staticType: String (optional)
+- +-

+- The name of the static type of the expression. This data +- is omitted if the location does not correspond to an +- expression. +-

+-
ImplementedClass: object
+-

+- A description of a class that is implemented or extended. +-

+- +-
offset: int
+- +-

+- The offset of the name of the implemented class. +-

+-
length: int
+- +-

+- The length of the name of the implemented class. +-

+-
ImplementedMember: object
+-

+- A description of a class member that is implemented or overridden. +-

+- +-
offset: int
+- +-

+- The offset of the name of the implemented member. +-

+-
length: int
+- +-

+- The length of the name of the implemented member. +-

+-
ImportedElements: object
+-

+- A description of the elements that are referenced in a region of a file +- that come from a single imported library. +-

+- +-
path: FilePath
+- +-

+- The absolute and normalized path of the file containing the library. +-

+-
prefix: String
+- +-

+- The prefix that was used when importing the library into the original +- source. +-

+-
elements: List<String>
+- +-

+- The names of the elements imported from the library. +-

+-
KytheEntry: object
+-

+- This object matches the format and documentation of the Entry object +- documented in the +- Kythe Storage +- Model. +-

+- +-
source: KytheVName
+- +-

+- The ticket of the source node. +-

+-
kind: String (optional)
+- +-

+- An edge label. The schema defines which labels are meaningful. +-

+-
target: KytheVName (optional)
+- +-

+- The ticket of the target node. +-

+-
fact: String
+- +-

+- A fact label. The schema defines which fact labels are meaningful. +-

+-
value: List<int> (optional)
+- +-

+- The String value of the fact. +-

+-
KytheVName: object
+-

+- This object matches the format and documentation of the Vector-Name object +- documented in the +- Kythe +- Storage Model. +-

+- +-
signature: String
+- +-

+- An opaque signature generated by the analyzer. +-

+-
corpus: String
+- +-

+- The corpus of source code this KytheVName belongs to. +- Loosely, a corpus is a collection of related files, such as the +- contents of a given source repository. +-

+-
root: String
+- +-

+- A corpus-specific root label, typically a directory path or project +- identifier, denoting a distinct subset of the corpus. This may also be +- used to designate virtual collections like generated files. +-

+-
path: String
+- +-

+- A path-structured label describing the “location” of the named object +- relative to the corpus and the root. +-

+-
language: String
+- +-

+- The language this name belongs to. +-

+-
LinkedEditGroup: object
+-

+- A collection of positions that should be linked (edited simultaneously) +- for the purposes of updating code after a source change. For example, if a +- set of edits introduced a new variable name, the group would contain all +- of the positions of the variable name so that if the client wanted to let +- the user edit the variable name after the operation, all occurrences of +- the name could be edited simultaneously. +-

+- +-
positions: List<Position>
+- +-

+- The positions of the regions that should be edited simultaneously. +-

+-
length: int
+- +-

+- The length of the regions that should be edited simultaneously. +-

+-
suggestions: List<LinkedEditSuggestion>
+- +-

+- Pre-computed suggestions for what every region might want to be +- changed to. +-

+-
LinkedEditSuggestion: object
+-

+- A suggestion of a value that could be used to replace all of the linked +- edit regions in a LinkedEditGroup. +-

+- +-
value: String
+- +-

+- The value that could be used to replace all of the linked edit +- regions. +-

+-
kind: LinkedEditSuggestionKind
+- +-

+- The kind of value being proposed. +-

+-
LinkedEditSuggestionKind: String
+-

+- An enumeration of the kind of values that can be suggested for a linked +- edit. +-

+- +-
METHOD
PARAMETER
TYPE
VARIABLE
Location: object
+-

+- A location (character range) within a file. +-

+- +-
file: FilePath
+- +-

+- The file containing the range. +-

+-
offset: int
+- +-

+- The offset of the range. +-

+-
length: int
+- +-

+- The length of the range. +-

+-
startLine: int
+- +-

+- The one-based index of the line containing the first character of the +- range. +-

+-
startColumn: int
+- +-

+- The one-based index of the column containing the first character of +- the range. +-

+-
NavigationRegion: object
+-

+- A description of a region from which the user can navigate to the +- declaration of an element. +-

+- +-
offset: int
+- +-

+- The offset of the region from which the user can navigate. +-

+-
length: int
+- +-

+- The length of the region from which the user can navigate. +-

+-
targets: List<int>
+- +-

+- The indexes of the targets (in the enclosing navigation response) to +- which the given region is bound. By opening the target, clients can +- implement one form of navigation. This list cannot be empty. +-

+-
NavigationTarget: object
+-

+- A description of a target to which the user can navigate. +-

+- +-
kind: ElementKind
+- +-

+- The kind of the element. +-

+-
fileIndex: int
+- +-

+- The index of the file (in the enclosing navigation response) to +- navigate to. +-

+-
offset: int
+- +-

+- The offset of the region to which the user can navigate. +-

+-
length: int
+- +-

+- The length of the region to which the user can navigate. +-

+-
startLine: int
+- +-

+- The one-based index of the line containing the first character of the +- region. +-

+-
startColumn: int
+- +-

+- The one-based index of the column containing the first character of +- the region. +-

+-
Occurrences: object
+-

+- A description of the references to a single element within a single file. +-

+- +-
element: Element
+- +-

+- The element that was referenced. +-

+-
offsets: List<int>
+- +-

+- The offsets of the name of the referenced element within the file. +-

+-
length: int
+- +-

+- The length of the name of the referenced element. +-

+-
Outline: object
+-

+- An node in the outline structure of a file. +-

+- +-
element: Element
+- +-

+- A description of the element represented by this node. +-

+-
offset: int
+- +-

+- The offset of the first character of the element. This is different +- than the offset in the Element, which is the offset of the name of the +- element. It can be used, for example, to map locations in the file +- back to an outline. +-

+-
length: int
+- +-

+- The length of the element. +-

+-
children: List<Outline> (optional)
+- +-

+- The children of the node. The field will be omitted if the node has no +- children. +-

+-
OverriddenMember: object
+-

+- A description of a member that is being overridden. +-

+- +-
element: Element
+- +-

+- The element that is being overridden. +-

+-
className: String
+- +-

+- The name of the class in which the member is defined. +-

+-
Override: object
+-

+- A description of a member that overrides an inherited member. +-

+- +-
offset: int
+- +-

+- The offset of the name of the overriding member. +-

+-
length: int
+- +-

+- The length of the name of the overriding member. +-

+-
superclassMember: OverriddenMember (optional)
+- +-

+- The member inherited from a superclass that is overridden +- by the overriding member. The field is omitted if there is +- no superclass member, in which case there must be at least +- one interface member. +-

+-
interfaceMembers: List<OverriddenMember> (optional)
+- +-

+- The members inherited from interfaces that are overridden +- by the overriding member. The field is omitted if there +- are no interface members, in which case there must be a +- superclass member. +-

+-
Position: object
+-

+- A position within a file. +-

+- +-
file: FilePath
+- +-

+- The file containing the position. +-

+-
offset: int
+- +-

+- The offset of the position. +-

+-
PostfixTemplateDescriptor: object
+-

+- The description of a postfix completion template. +-

+- +-
name: String
+- +-

+- The template name, shown in the UI. +-

+-
key: String
+- +-

+- The unique template key, not shown in the UI. +-

+-
example: String
+- +-

+- A short example of the transformation performed when the template is +- applied. +-

+-
PubStatus: object
+-

+- An indication of the current state of pub execution. +-

+- +-
isListingPackageDirs: bool
+- +-

+- True if the server is currently running pub to produce a list of +- package directories. +-

+-
RefactoringFeedback: object
+-

+- An abstract superclass of all refactoring feedbacks. +-

+- +-
RefactoringKind: String
+-

+- An enumeration of the kinds of refactorings that can be created. +-

+- +-
CONVERT_GETTER_TO_METHOD
CONVERT_METHOD_TO_GETTER
EXTRACT_LOCAL_VARIABLE
EXTRACT_METHOD
INLINE_LOCAL_VARIABLE
INLINE_METHOD
MOVE_FILE
RENAME
SORT_MEMBERS
RefactoringMethodParameter: object
+- +-

+- A description of a parameter in a method refactoring. +-

+- +-
id: String (optional)
+- +-

+- The unique identifier of the parameter. Clients may omit this field +- for the parameters they want to add. +-

+-
kind: RefactoringMethodParameterKind
+- +-

+- The kind of the parameter. +-

+-
type: String
+- +-

+- The type that should be given to the parameter, or the return type of +- the parameter's function type. +-

+-
name: String
+- +-

+- The name that should be given to the parameter. +-

+-
parameters: String (optional)
+- +-

+- The parameter list of the parameter's function type. If the parameter +- is not of a function type, this field will not be defined. If the +- function type has zero parameters, this field will have a value of +- '()'. +-

+-
RefactoringMethodParameterKind: String
+-

+- An enumeration of the kinds of parameters. +-

+- +-
REQUIRED
POSITIONAL
NAMED
RefactoringOptions: object
+-

+- An abstract superclass of all refactoring options. +-

+- +-
RefactoringProblem: object
+-

+- A description of a problem related to a refactoring. +-

+- +-
severity: RefactoringProblemSeverity
+- +-

+- The severity of the problem being represented. +-

+-
message: String
+- +-

+- A human-readable description of the problem being represented. +-

+-
location: Location (optional)
+- +-

+- The location of the problem being represented. This field is omitted +- unless there is a specific location associated with the problem (such +- as a location where an element being renamed will be shadowed). +-

+-
RefactoringProblemSeverity: String
+-

+- An enumeration of the severities of problems that can be returned by the +- refactoring requests. +-

+- +-
INFO
+- +-

+- A minor code problem. No example, because it is not used yet. +-

+-
WARNING
+- +-

+- A minor code problem. For example names of local variables should be +- camel case and start with a lower case letter. Staring the name of a +- variable with an upper case is OK from the language point of view, but +- it is nice to warn the user. +-

+-
ERROR
+- +-

+- The refactoring technically can be performed, but there is a logical +- problem. For example the name of a local variable being extracted +- conflicts with another name in the scope, or duplicate parameter names +- in the method being extracted, or a conflict between a parameter name +- and a local variable, etc. In some cases the location of the problem +- is also provided, so the IDE can show user the location and the +- problem, and let the user decide whether they want to perform the +- refactoring. For example the name conflict might be expected, and the +- user wants to fix it afterwards. +-

+-
FATAL
+- +-

+- A fatal error, which prevents performing the refactoring. For example +- the name of a local variable being extracted is not a valid +- identifier, or selection is not a valid expression. +-

+-
RemoveContentOverlay: object
+-

+- A directive to remove an existing file content overlay. After processing +- this directive, the file contents will once again be read from the file +- system. +-

+-

+- If this directive is used on a file that doesn't currently have a content +- overlay, it has no effect. +-

+- +-
type = "remove"
+- +-
RequestError: object
+-

+- An indication of a problem with the execution of the server, +- typically in response to a request. +-

+- +-
code: RequestErrorCode
+- +-

+- A code that uniquely identifies the error that occurred. +-

+-
message: String
+- +-

+- A short description of the error. +-

+-
stackTrace: String (optional)
+- +-

+- The stack trace associated with processing the request, +- used for debugging the server. +-

+-
RequestErrorCode: String
+-

+- An enumeration of the types of errors that can occur in the +- execution of the server. +-

+- +-
CONTENT_MODIFIED
+- +-

+- An "analysis.getErrors" or "analysis.getNavigation" request could +- not be satisfied because the content of the file changed before +- the requested results could be computed. +-

+-
DEBUG_PORT_COULD_NOT_BE_OPENED
+- +-

+- The server was unable to open a port for the diagnostic server. +-

+-
FILE_NOT_ANALYZED
+- +-

+- A request specified a FilePath which does not match a file in +- an analysis root, or the requested operation is not available +- for the file. +-

+-
FORMAT_INVALID_FILE
+- +-

+- An "edit.format" request specified a FilePath +- which does not match a Dart file in an analysis root. +-

+-
FORMAT_WITH_ERRORS
+- +-

+- An "edit.format" request specified a file that contains syntax +- errors. +-

+-
GET_ERRORS_INVALID_FILE
+- +-

+- An "analysis.getErrors" request specified a FilePath +- which does not match a file currently subject to +- analysis. +-

+-
GET_IMPORTED_ELEMENTS_INVALID_FILE
+- +-

+- An "analysis.getImportedElements" request specified a FilePath that +- does not match a file currently subject to analysis. +-

+-
GET_KYTHE_ENTRIES_INVALID_FILE
+- +-

+- An "analysis.getKytheEntries" request specified a FilePath that does +- not match a file that is currently subject to analysis. +-

+-
GET_NAVIGATION_INVALID_FILE
+- +-

+- An "analysis.getNavigation" request specified a FilePath +- which does not match a file currently subject to +- analysis. +-

+-
GET_REACHABLE_SOURCES_INVALID_FILE
+- +-

+- An "analysis.getReachableSources" request specified a FilePath +- which does not match a file currently subject to +- analysis. +-

+-
IMPORT_ELEMENTS_INVALID_FILE
+- +-

+- An "edit.importElements" request specified a FilePath that does not +- match a file currently subject to analysis. +-

+-
INVALID_ANALYSIS_ROOT
+- +-

+- A path passed as an argument to a request (such as +- analysis.reanalyze) is required to be an analysis root, but isn't. +-

+-
INVALID_EXECUTION_CONTEXT
+- +-

+- The context root used to create an execution context does not +- exist. +-

+-
INVALID_FILE_PATH_FORMAT
+- +-

+- The format of the given file path is invalid, e.g. is not +- absolute and normalized. +-

+-
INVALID_OVERLAY_CHANGE
+- +-

+- An "analysis.updateContent" request contained a +- ChangeContentOverlay object which can't be applied, due +- to an edit having an offset or length that is out of +- range. +-

+-
INVALID_PARAMETER
+- +-

+- One of the method parameters was invalid. +-

+-
INVALID_REQUEST
+- +-

+- A malformed request was received. +-

+-
ORGANIZE_DIRECTIVES_ERROR
+- +-

+- An "edit.organizeDirectives" request specified a Dart file that +- cannot be analyzed. The reason is described in the message. +-

+-
REFACTORING_REQUEST_CANCELLED
+- +-

+- Another refactoring request was received during processing of +- this one. +-

+-
SERVER_ALREADY_STARTED
+- +-

+- The analysis server has already been started (and hence +- won't accept new connections). +-

+-

+- This error is included for future expansion; at present +- the analysis server can only speak to one client at a +- time so this error will never occur. +-

+-
SERVER_ERROR
+- +-

+- An internal error occurred in the analysis server. +- Also see the server.error notification. +-

+-
SORT_MEMBERS_INVALID_FILE
+- +-

+- An "edit.sortMembers" request specified a FilePath +- which does not match a Dart file in an analysis root. +-

+-
SORT_MEMBERS_PARSE_ERRORS
+- +-

+- An "edit.sortMembers" request specified a Dart file that has +- scan or parse errors. +-

+-
UNANALYZED_PRIORITY_FILES
+- +-

+- An "analysis.setPriorityFiles" request includes one or +- more files that are not being analyzed. +-

+-

+- This is a legacy error; it will be removed before the +- API reaches version 1.0. +-

+- +-
UNKNOWN_REQUEST
+- +-

+- A request was received which the analysis server does +- not recognize, or cannot handle in its current +- configuration. +-

+-
UNKNOWN_SOURCE
+- +-

+- The analysis server was requested to perform an action +- on a source that does not exist. +-

+-
UNSUPPORTED_FEATURE
+- +-

+- The analysis server was requested to perform an action +- which is not supported. +-

+-

+- This is a legacy error; it will be removed before the +- API reaches version 1.0. +-

+- +-
SearchId: String
+- +-

+- An identifier used to associate search results with a search +- request. +-

+-
SearchResult: object
+-

+- A single result from a search request. +-

+- +-
location: Location
+- +-

+- The location of the code that matched the search criteria. +-

+-
kind: SearchResultKind
+- +-

+- The kind of element that was found or the kind of +- reference that was found. +-

+-
isPotential: bool
+- +-

+- True if the result is a potential match but cannot be +- confirmed to be a match. For example, if all references to +- a method m defined in some class were requested, and a +- reference to a method m from an unknown class were found, +- it would be marked as being a potential match. +-

+-
path: List<Element>
+- +-

+- The elements that contain the result, starting with the +- most immediately enclosing ancestor and ending with the +- library. +-

+-
SearchResultKind: String
+-

+- An enumeration of the kinds of search results returned by the +- search domain. +-

+- +-
DECLARATION
+- +-

+- The declaration of an element. +-

+-
INVOCATION
+- +-

+- The invocation of a function or method. +-

+-
READ
+- +-

+- A reference to a field, parameter or variable where it is being read. +-

+-
READ_WRITE
+- +-

+- A reference to a field, parameter or variable where it is being read +- and written. +-

+-
REFERENCE
+- +-

+- A reference to an element. +-

+-
UNKNOWN
+- +-

+- Some other kind of search result. +-

+-
WRITE
+- +-

+- A reference to a field, parameter or variable where it is being +- written. +-

+-
ServerService: String
+-

+- An enumeration of the services provided by the server domain. +-

+- +-
STATUS
SourceChange: object
+-

+- A description of a set of edits that implement a single conceptual change. +-

+- +-
message: String
+- +-

+- A human-readable description of the change to be applied. +-

+-
edits: List<SourceFileEdit>
+- +-

+- A list of the edits used to effect the change, grouped by file. +-

+-
linkedEditGroups: List<LinkedEditGroup>
+- +-

+- A list of the linked editing groups used to customize the changes that +- were made. +-

+-
selection: Position (optional)
+- +-

+- The position that should be selected after the edits have been +- applied. +-

+-
SourceEdit: object
+-

+- A description of a single change to a single file. +-

+- +-
offset: int
+- +-

+- The offset of the region to be modified. +-

+-
length: int
+- +-

+- The length of the region to be modified. +-

+-
replacement: String
+- +-

+- The code that is to replace the specified region in the original code. +-

+-
id: String (optional)
+- +-

+- An identifier that uniquely identifies this source edit from other +- edits in the same response. This field is omitted unless a containing +- structure needs to be able to identify the edit for some reason. +-

+-

+- For example, some refactoring operations can produce edits that might +- not be appropriate (referred to as potential edits). Such edits will +- have an id so that they can be referenced. Edits in the same response +- that do not need to be referenced will not have an id. +-

+-
SourceFileEdit: object
+-

+- A description of a set of changes to a single file. +-

+- +-
file: FilePath
+- +-

+- The file containing the code to be modified. +-

+-
fileStamp: long
+- +-

+- The modification stamp of the file at the moment when the change was +- created, in milliseconds since the "Unix epoch". Will be -1 if the +- file did not exist and should be created. The client may use this +- field to make sure that the file was not changed since then, so it is +- safe to apply the change. +-

+-
edits: List<SourceEdit>
+- +-

+- A list of the edits used to effect the change. +-

+-
TypeHierarchyItem: object
+-

+- A representation of a class in a type hierarchy. +-

+- +-
classElement: Element
+- +-

+- The class element represented by this item. +-

+-
displayName: String (optional)
+- +-

+- The name to be displayed for the class. This field will be +- omitted if the display name is the same as the name of the +- element. The display name is different if there is +- additional type information to be displayed, such as type +- arguments. +-

+-
memberElement: Element (optional)
+- +-

+- The member in the class corresponding to the member on +- which the hierarchy was requested. This field will be +- omitted if the hierarchy was not requested for a member or +- if the class does not have a corresponding member. +-

+-
superclass: int (optional)
+- +-

+- The index of the item representing the superclass of +- this class. This field will be omitted if this item +- represents the class Object. +-

+-
interfaces: List<int>
+- +-

+- The indexes of the items representing the interfaces +- implemented by this class. The list will be empty if +- there are no implemented interfaces. +-

+-
mixins: List<int>
+- +-

+- The indexes of the items representing the mixins +- referenced by this class. The list will be empty if +- there are no classes mixed in to this class. +-

+-
subclasses: List<int>
+- +-

+- The indexes of the items representing the subtypes of +- this class. The list will be empty if there are no +- subtypes or if this item represents a supertype of the +- pivot type. +-

+-
+- +-

Refactorings

+-

+- This section contains additional information for each kind of +- refactoring. In addition to a brief description of the +- refactoring, there is a specification of the feedback that is +- provided when a refactoring is requested using the +- edit.getRefactoring request (designed to improve the UX) +- and the options that may be provided to edit.getRefactoring. +-

+- +- +- +- +- +- +- +- +-
CONVERT_GETTER_TO_METHOD
+-

+- Convert a getter into a method by removing the keyword get +- and adding an empty parameter list. +-

+-

+- It is an error if the range contains anything other than all +- or part of the name of a single getter. +-

+-

Feedback:

none

Options:

none

CONVERT_METHOD_TO_GETTER
+-

+- Convert a method into a getter by adding the keyword get and +- removing the parameter list. +-

+-

+- It is an error if the range contains anything other than all +- or part of the name of a single method or if the method has +- a non-empty parameter list. +-

+-

Feedback:

none

Options:

none

EXTRACT_LOCAL_VARIABLE
+-

+- Create a local variable initialized by the expression that covers +- the specified selection. +-

+-

+- It is an error if the selection range is not covered by a +- complete expression. +-

+- +- +-

Feedback:

coveringExpressionOffsets: List<int> (optional)
+- +-

+- The offsets of the expressions that cover the specified +- selection, from the down most to the up most. +-

+-
coveringExpressionLengths: List<int> (optional)
+- +-

+- The lengths of the expressions that cover the specified +- selection, from the down most to the up most. +-

+-
names: List<String>
+- +-

+- The proposed names for the local variable. +-

+-
offsets: List<int>
+- +-

+- The offsets of the expressions that would be replaced by +- a reference to the variable. +-

+-
lengths: List<int>
+- +-

+- The lengths of the expressions that would be replaced by +- a reference to the variable. The lengths correspond to +- the offsets. In other words, for a given expression, if +- the offset of that expression is offsets[i], then +- the length of that expression is lengths[i]. +-

+-

Options:

name: String
+- +-

+- The name that the local variable should be given. +-

+-
extractAll: bool
+- +-

+- True if all occurrences of the expression within the +- scope in which the variable will be defined should be +- replaced by a reference to the local variable. The +- expression used to initiate the refactoring will always +- be replaced. +-

+-
EXTRACT_METHOD
+-

+- Create a method whose body is the specified expression or +- list of statements, possibly augmented with a return +- statement. +-

+-

+- It is an error if the range contains anything other than a +- complete expression (no partial expressions are allowed) or +- a complete sequence of statements. +-

+- +- +-

Feedback:

offset: int
+- +-

+- The offset to the beginning of the expression or +- statements that will be extracted. +-

+-
length: int
+- +-

+- The length of the expression or statements that will be +- extracted. +-

+-
returnType: String
+- +-

+- The proposed return type for the method. +- If the returned element does not have a declared return type, +- this field will contain an empty string. +-

+-
names: List<String>
+- +-

+- The proposed names for the method. +-

+-
canCreateGetter: bool
+- +-

+- True if a getter could be created rather than a method. +-

+-
parameters: List<RefactoringMethodParameter>
+- +-

+- The proposed parameters for the method. +-

+-
offsets: List<int>
+- +-

+- The offsets of the expressions or statements that would +- be replaced by an invocation of the method. +-

+-
lengths: List<int>
+- +-

+- The lengths of the expressions or statements that would +- be replaced by an invocation of the method. The lengths +- correspond to the offsets. In other words, for a given +- expression (or block of statements), if the offset of +- that expression is offsets[i], then the length +- of that expression is lengths[i]. +-

+-

Options:

returnType: String
+- +-

+- The return type that should be defined for the method. +-

+-
createGetter: bool
+- +-

+- True if a getter should be created rather than a +- method. It is an error if this field is true and the +- list of parameters is non-empty. +-

+-
name: String
+- +-

+- The name that the method should be given. +-

+-
parameters: List<RefactoringMethodParameter>
+- +-

+- The parameters that should be defined for the method. +-

+-

+- It is an error if a REQUIRED or NAMED parameter follows a +- POSITIONAL parameter. +- It is an error if a REQUIRED or POSITIONAL parameter follows a +- NAMED parameter. +-

+-
    +-
  • +- To change the order and/or update proposed parameters, add +- parameters with the same identifiers as proposed. +-
  • +-
  • To add new parameters, omit their identifier.
  • +-
  • To remove some parameters, omit them in this list.
  • +-
+-
extractAll: bool
+- +-

+- True if all occurrences of the expression or statements +- should be replaced by an invocation of the method. The +- expression or statements used to initiate the +- refactoring will always be replaced. +-

+-
INLINE_LOCAL_VARIABLE
+-

+- Inline the initializer expression of a local variable in +- place of any references to that variable. +-

+-

+- It is an error if the range contains anything other than all +- or part of the name of a single local variable. +-

+- +-

Feedback:

name: String
+- +-

+- The name of the variable being inlined. +-

+-
occurrences: int
+- +-

+- The number of times the variable occurs. +-

+-

Options:

none

INLINE_METHOD
+-

+- Inline a method in place of one or all references to that +- method. +-

+-

+- It is an error if the range contains anything other than all +- or part of the name of a single method. +-

+- +- +-

Feedback:

className: String (optional)
+- +-

+- The name of the class enclosing the method being inlined. +- If not a class member is being inlined, this field will be absent. +-

+-
methodName: String
+- +-

+- The name of the method (or function) being inlined. +-

+-
isDeclaration: bool
+- +-

+- True if the declaration of the method is selected. +- So all references should be inlined. +-

+-

Options:

deleteSource: bool
+- +-

+- True if the method being inlined should be removed. +- It is an error if this field is true and inlineAll is false. +-

+-
inlineAll: bool
+- +-

+- True if all invocations of the method should be inlined, +- or false if only the invocation site used to create this +- refactoring should be inlined. +-

+-
MOVE_FILE
+-

+- Move the given file and update all of the references to that file +- and from it. The move operation is supported in general case - for +- renaming a file in the same folder, moving it to a different folder +- or both. +-

+-

+- The refactoring must be activated before an actual file moving +- operation is performed. +-

+-

+- The "offset" and "length" fields from the request are ignored, but the +- file specified in the request specifies the file to be moved. +-

+- +-

Feedback:

none

Options:

newFile: FilePath
+- +-

+- The new file path to which the given file is being moved. +-

+-
RENAME
+-

+- Rename a given element and all of the references to that +- element. +-

+-

+- It is an error if the range contains anything other than all +- or part of the name of a single function (including methods, +- getters and setters), variable (including fields, parameters +- and local variables), class or function type. +-

+- +- +-

Feedback:

offset: int
+- +-

+- The offset to the beginning of the name selected to be +- renamed. +-

+-
length: int
+- +-

+- The length of the name selected to be renamed. +-

+-
elementKindName: String
+- +-

+- The human-readable description of the kind of element being +- renamed (such as "class" or "function type +- alias"). +-

+-
oldName: String
+- +-

+- The old name of the element before the refactoring. +-

+-

Options:

newName: String
+- +-

+- The name that the element should have after the +- refactoring. +-

+-
+-

Errors

+-

+- This section contains a list of all of the errors that are +- produced by the server and the data that is returned with each. +-

+-

+- TODO: TBD +-

+-

Index

+-

Domains

server ()

analysis ()

completion ()

Requests
Notifications

search ()

edit ()

execution ()

diagnostic ()

Types ()

Refactorings ()

+- +- +- +\ No newline at end of file +diff --git a/pkg/analysis_server/lib/plugin/analysis/occurrences/occurrences_core.dart b/pkg/analysis_server/lib/plugin/analysis/occurrences/occurrences_core.dart +deleted file mode 100644 +index 22a85fd8135..00000000000 +--- a/pkg/analysis_server/lib/plugin/analysis/occurrences/occurrences_core.dart ++++ /dev/null +@@ -1,17 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart' show Occurrences; +- +-/** +- * An object used to record occurrences into. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class OccurrencesCollector { +- /** +- * Record a new element occurrences. +- */ +- void addOccurrences(Occurrences occurrences); +-} +diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart +deleted file mode 100644 +index f4d1e6254e5..00000000000 +--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart ++++ /dev/null +@@ -1,90 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show SourceChange; +-import 'package:analyzer_plugin/utilities/assist/assist.dart'; +- +-/** +- * A description of a single proposed assist. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class Assist { +- /** +- * An empty list of assists. +- */ +- static const List EMPTY_LIST = const []; +- +- /** +- * A comparator that can be used to sort assists by their relevance. The most +- * relevant assists will be sorted before assists with a lower relevance. +- */ +- static final Comparator SORT_BY_RELEVANCE = +- (Assist firstAssist, Assist secondAssist) => +- firstAssist.kind.priority - secondAssist.kind.priority; +- +- /** +- * A description of the assist being proposed. +- */ +- final AssistKind kind; +- +- /** +- * The change to be made in order to apply the assist. +- */ +- final SourceChange change; +- +- /** +- * Initialize a newly created assist to have the given [kind] and [change]. +- */ +- Assist(this.kind, this.change); +- +- @override +- String toString() { +- return 'Assist(kind=$kind, change=$change)'; +- } +-} +- +-/** +- * An object used to provide context information for [AssistContributor]s. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class AssistContext { +- /** +- * The analysis driver used to access analysis results. +- */ +- AnalysisDriver get analysisDriver; +- +- /** +- * The length of the selection. +- */ +- int get selectionLength; +- +- /** +- * The start of the selection. +- */ +- int get selectionOffset; +- +- /** +- * The source to get assists in. +- */ +- Source get source; +-} +- +-/** +- * An object used to produce assists for a specific location. +- * +- * Clients may implement this class when implementing plugins. +- */ +-abstract class AssistContributor { +- /** +- * Completes with a list of assists for the given [context]. +- */ +- Future> computeAssists(AssistContext context); +-} +diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart +deleted file mode 100644 +index 44198cd69d3..00000000000 +--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart ++++ /dev/null +@@ -1,107 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * An object used to provide context information for [DartAssistContributor]s. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class DartAssistContext { +- /** +- * The analysis driver used to access analysis results. +- */ +- AnalysisDriver get analysisDriver; +- +- /** +- * The provider for parsed or resolved ASTs. +- */ +- AstProvider get astProvider; +- +- /** +- * The length of the selection. +- */ +- int get selectionLength; +- +- /** +- * The start of the selection. +- */ +- int get selectionOffset; +- +- /** +- * The source to get assists in. +- */ +- Source get source; +- +- /** +- * The [CompilationUnit] to compute assists in. +- */ +- CompilationUnit get unit; +-} +- +-/** +- * An [AssistContributor] that can be used to contribute assists for Dart files. +- * +- * Clients may extend this class when implementing plugins. +- */ +-abstract class DartAssistContributor implements AssistContributor { +- @override +- Future> computeAssists(AssistContext context) async { +- AnalysisDriver driver = context.analysisDriver; +- Source source = context.source; +- if (!AnalysisEngine.isDartFileName(source.fullName)) { +- return Assist.EMPTY_LIST; +- } +- CompilationUnit unit = (await driver.getResult(source.fullName)).unit; +- if (unit == null) { +- return Assist.EMPTY_LIST; +- } +- DartAssistContext dartContext = new _DartAssistContextImpl( +- new AstProviderForDriver(driver), context, unit); +- return internalComputeAssists(dartContext); +- } +- +- /** +- * Completes with a list of assists for the given [context]. +- */ +- Future> internalComputeAssists(DartAssistContext context); +-} +- +-/** +- * The implementation of [DartAssistContext]. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class _DartAssistContextImpl implements DartAssistContext { +- @override +- final AstProvider astProvider; +- +- final AssistContext _context; +- +- @override +- final CompilationUnit unit; +- +- _DartAssistContextImpl(this.astProvider, this._context, this.unit); +- +- @override +- AnalysisDriver get analysisDriver => _context.analysisDriver; +- +- @override +- int get selectionLength => _context.selectionLength; +- +- @override +- int get selectionOffset => _context.selectionOffset; +- +- @override +- Source get source => _context.source; +-} +diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart +deleted file mode 100644 +index 91a813f8214..00000000000 +--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart ++++ /dev/null +@@ -1,88 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analyzer/error/error.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show SourceChange; +-import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +- +-/** +- * A description of a single proposed fix for some problem. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class Fix { +- /** +- * An empty list of fixes. +- */ +- static const List EMPTY_LIST = const []; +- +- /** +- * A comparator that can be used to sort fixes by their relevance. The most +- * relevant fixes will be sorted before fixes with a lower relevance. +- */ +- static final Comparator SORT_BY_RELEVANCE = +- (Fix firstFix, Fix secondFix) => +- firstFix.kind.priority - secondFix.kind.priority; +- +- /** +- * A description of the fix being proposed. +- */ +- final FixKind kind; +- +- /** +- * The change to be made in order to apply the fix. +- */ +- final SourceChange change; +- +- /** +- * Initialize a newly created fix to have the given [kind] and [change]. +- */ +- Fix(this.kind, this.change); +- +- @override +- String toString() { +- return 'Fix(kind=$kind, change=$change)'; +- } +-} +- +-/** +- * An object used to provide context information for [FixContributor]s. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class FixContext { +- /** +- * The analysis driver used to access analysis results. +- */ +- AnalysisDriver get analysisDriver; +- +- /** +- * The error to fix, should be reported by the given [analysisDriver]. +- */ +- AnalysisError get error; +- +- /** +- * The [ResourceProvider] to access files and folders. +- */ +- ResourceProvider get resourceProvider; +-} +- +-/** +- * An object used to produce fixes for a specific error. Fix contributors are +- * long-lived objects and must not retain any state between invocations of +- * [computeFixes]. +- * +- * Clients may implement this class when implementing plugins. +- */ +-abstract class FixContributor { +- /** +- * Return a list of fixes for the given [context]. +- */ +- Future> computeFixes(FixContext context); +-} +diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart +deleted file mode 100644 +index e5b0f1f5625..00000000000 +--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart ++++ /dev/null +@@ -1,73 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +-import 'package:analysis_server/src/services/correction/fix_internal.dart' +- show DartFixContextImpl; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * Complete with top-level declarations with the given [name]. +- */ +-typedef Future> GetTopLevelDeclarations( +- String name); +- +-/** +- * An object used to provide context information for [DartFixContributor]s. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class DartFixContext implements FixContext { +- /** +- * The provider for parsed or resolved ASTs. +- */ +- AstProvider get astProvider; +- +- /** +- * The function to get top-level declarations from. +- */ +- GetTopLevelDeclarations get getTopLevelDeclarations; +- +- /** +- * The [CompilationUnit] to compute fixes in. +- */ +- CompilationUnit get unit; +-} +- +-/** +- * A [FixContributor] that can be used to contribute fixes for errors in Dart +- * files. +- * +- * Clients may extend this class when implementing plugins. +- */ +-abstract class DartFixContributor implements FixContributor { +- @override +- Future> computeFixes(FixContext context) async { +- AnalysisDriver driver = context.analysisDriver; +- Source source = context.error.source; +- if (!AnalysisEngine.isDartFileName(source.fullName)) { +- return Fix.EMPTY_LIST; +- } +- CompilationUnit unit = (await driver.getResult(source.fullName)).unit; +- if (unit == null) { +- return Fix.EMPTY_LIST; +- } +- DartFixContext dartContext = +- new DartFixContextImpl(context, new AstProviderForDriver(driver), unit); +- return internalComputeFixes(dartContext); +- } +- +- /** +- * Return a list of fixes for the given [context]. +- */ +- Future> internalComputeFixes(DartFixContext context); +-} +diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart +deleted file mode 100644 +index 10272553807..00000000000 +--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart ++++ /dev/null +@@ -1,216 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Utilities for converting Dart entities into analysis server's protocol +- * entities. +- */ +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analyzer/dart/element/element.dart' as engine; +-import 'package:analyzer/src/generated/utilities_dart.dart' as engine; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * Return a protocol [Element] corresponding to the given [engine.Element]. +- */ +-Element convertElement(engine.Element element) { +- String name = element.displayName; +- String elementTypeParameters = _getTypeParametersString(element); +- String elementParameters = _getParametersString(element); +- String elementReturnType = getReturnTypeString(element); +- ElementKind kind = convertElementToElementKind(element); +- return new Element( +- kind, +- name, +- Element.makeFlags( +- isPrivate: element.isPrivate, +- isDeprecated: element.isDeprecated, +- isAbstract: _isAbstract(element), +- isConst: _isConst(element), +- isFinal: _isFinal(element), +- isStatic: _isStatic(element)), +- location: newLocation_fromElement(element), +- typeParameters: elementTypeParameters, +- parameters: elementParameters, +- returnType: elementReturnType); +-} +- +-/** +- * Return a protocol [ElementKind] corresponding to the given +- * [engine.ElementKind]. +- * +- * This does not take into account that an instance of [ClassElement] can be an +- * enum and an instance of [FieldElement] can be an enum constant. +- * Use [convertElementToElementKind] where possible. +- */ +-ElementKind convertElementKind(engine.ElementKind kind) { +- if (kind == engine.ElementKind.CLASS) { +- return ElementKind.CLASS; +- } +- if (kind == engine.ElementKind.COMPILATION_UNIT) { +- return ElementKind.COMPILATION_UNIT; +- } +- if (kind == engine.ElementKind.CONSTRUCTOR) { +- return ElementKind.CONSTRUCTOR; +- } +- if (kind == engine.ElementKind.FIELD) { +- return ElementKind.FIELD; +- } +- if (kind == engine.ElementKind.FUNCTION) { +- return ElementKind.FUNCTION; +- } +- if (kind == engine.ElementKind.FUNCTION_TYPE_ALIAS) { +- return ElementKind.FUNCTION_TYPE_ALIAS; +- } +- if (kind == engine.ElementKind.GETTER) { +- return ElementKind.GETTER; +- } +- if (kind == engine.ElementKind.LABEL) { +- return ElementKind.LABEL; +- } +- if (kind == engine.ElementKind.LIBRARY) { +- return ElementKind.LIBRARY; +- } +- if (kind == engine.ElementKind.LOCAL_VARIABLE) { +- return ElementKind.LOCAL_VARIABLE; +- } +- if (kind == engine.ElementKind.METHOD) { +- return ElementKind.METHOD; +- } +- if (kind == engine.ElementKind.PARAMETER) { +- return ElementKind.PARAMETER; +- } +- if (kind == engine.ElementKind.PREFIX) { +- return ElementKind.PREFIX; +- } +- if (kind == engine.ElementKind.SETTER) { +- return ElementKind.SETTER; +- } +- if (kind == engine.ElementKind.TOP_LEVEL_VARIABLE) { +- return ElementKind.TOP_LEVEL_VARIABLE; +- } +- if (kind == engine.ElementKind.TYPE_PARAMETER) { +- return ElementKind.TYPE_PARAMETER; +- } +- return ElementKind.UNKNOWN; +-} +- +-/** +- * Return an [ElementKind] corresponding to the given [engine.Element]. +- */ +-ElementKind convertElementToElementKind(engine.Element element) { +- if (element is engine.ClassElement && element.isEnum) { +- return ElementKind.ENUM; +- } +- if (element is engine.FieldElement && +- element.isEnumConstant && +- // MyEnum.values and MyEnum.one.index return isEnumConstant = true +- // so these additional checks are necessary. +- // TODO(danrubel) MyEnum.values is constant, but is a list +- // so should it return isEnumConstant = true? +- // MyEnum.one.index is final but *not* constant +- // so should it return isEnumConstant = true? +- // Or should we return ElementKind.ENUM_CONSTANT here +- // in either or both of these cases? +- element.type != null && +- element.type.element == element.enclosingElement) { +- return ElementKind.ENUM_CONSTANT; +- } +- return convertElementKind(element.kind); +-} +- +-String _getParametersString(engine.Element element) { +- // TODO(scheglov) expose the corresponding feature from ExecutableElement +- List parameters; +- if (element is engine.ExecutableElement) { +- // valid getters don't have parameters +- if (element.kind == engine.ElementKind.GETTER && +- element.parameters.isEmpty) { +- return null; +- } +- parameters = element.parameters; +- } else if (element is engine.FunctionTypeAliasElement) { +- parameters = element.parameters; +- } else { +- return null; +- } +- StringBuffer sb = new StringBuffer(); +- String closeOptionalString = ''; +- for (engine.ParameterElement parameter in parameters) { +- if (sb.isNotEmpty) { +- sb.write(', '); +- } +- if (closeOptionalString.isEmpty) { +- engine.ParameterKind kind = parameter.parameterKind; +- if (kind == engine.ParameterKind.NAMED) { +- sb.write('{'); +- closeOptionalString = '}'; +- } +- if (kind == engine.ParameterKind.POSITIONAL) { +- sb.write('['); +- closeOptionalString = ']'; +- } +- } +- parameter.appendToWithoutDelimiters(sb); +- } +- sb.write(closeOptionalString); +- return '(' + sb.toString() + ')'; +-} +- +-String _getTypeParametersString(engine.Element element) { +- List typeParameters; +- if (element is engine.ClassElement) { +- typeParameters = element.typeParameters; +- } else if (element is engine.FunctionTypeAliasElement) { +- typeParameters = element.typeParameters; +- } +- if (typeParameters == null || typeParameters.isEmpty) { +- return null; +- } +- return '<${typeParameters.join(', ')}>'; +-} +- +-bool _isAbstract(engine.Element element) { +- // TODO(scheglov) add isAbstract to Element API +- if (element is engine.ClassElement) { +- return element.isAbstract; +- } +- if (element is engine.MethodElement) { +- return element.isAbstract; +- } +- if (element is engine.PropertyAccessorElement) { +- return element.isAbstract; +- } +- return false; +-} +- +-bool _isConst(engine.Element element) { +- // TODO(scheglov) add isConst to Element API +- if (element is engine.ConstructorElement) { +- return element.isConst; +- } +- if (element is engine.VariableElement) { +- return element.isConst; +- } +- return false; +-} +- +-bool _isFinal(engine.Element element) { +- // TODO(scheglov) add isFinal to Element API +- if (element is engine.VariableElement) { +- return element.isFinal; +- } +- return false; +-} +- +-bool _isStatic(engine.Element element) { +- // TODO(scheglov) add isStatic to Element API +- if (element is engine.ExecutableElement) { +- return element.isStatic; +- } +- if (element is engine.PropertyInducingElement) { +- return element.isStatic; +- } +- return false; +-} +diff --git a/pkg/analysis_server/lib/protocol/protocol.dart b/pkg/analysis_server/lib/protocol/protocol.dart +deleted file mode 100644 +index df989b1d9f5..00000000000 +--- a/pkg/analysis_server/lib/protocol/protocol.dart ++++ /dev/null +@@ -1,673 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Support for client code that needs to interact with the requests, responses +- * and notifications that are part of the analysis server's wire protocol. +- */ +-import 'dart:convert' hide JsonDecoder; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart'; +- +-export 'package:analyzer_plugin/protocol/protocol.dart' show Enum; +- +-/** +- * A [RequestHandler] that supports [startup] and [shutdown] methods. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class DomainHandler implements RequestHandler { +- /** +- * Perform any operations associated with the shutdown of the domain. It is +- * not guaranteed that this method will be called. If it is, it will be +- * called after the last [Request] has been made. +- */ +- void shutdown() {} +- +- /** +- * Perform any operations associated with the startup of the domain. This +- * will be called before the first [Request]. +- */ +- void startup() {} +-} +- +-/** +- * A notification that can be sent from the server about an event that occurred. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class Notification { +- /** +- * The name of the JSON attribute containing the name of the event that +- * triggered the notification. +- */ +- static const String EVENT = 'event'; +- +- /** +- * The name of the JSON attribute containing the result values. +- */ +- static const String PARAMS = 'params'; +- +- /** +- * The name of the event that triggered the notification. +- */ +- final String event; +- +- /** +- * A table mapping the names of notification parameters to their values, or +- * `null` if there are no notification parameters. +- */ +- final Map params; +- +- /** +- * Initialize a newly created [Notification] to have the given [event] name. +- * If [params] is provided, it will be used as the params; otherwise no +- * params will be used. +- */ +- Notification(this.event, [this.params]); +- +- /** +- * Initialize a newly created instance based on the given JSON data. +- */ +- factory Notification.fromJson(Map json) { +- return new Notification(json[Notification.EVENT], +- json[Notification.PARAMS] as Map); +- } +- +- /** +- * Return a table representing the structure of the Json object that will be +- * sent to the client to represent this response. +- */ +- Map toJson() { +- Map jsonObject = {}; +- jsonObject[EVENT] = event; +- if (params != null) { +- jsonObject[PARAMS] = params; +- } +- return jsonObject; +- } +-} +- +-/** +- * A request that was received from the client. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class Request { +- /** +- * The name of the JSON attribute containing the id of the request. +- */ +- static const String ID = 'id'; +- +- /** +- * The name of the JSON attribute containing the name of the request. +- */ +- static const String METHOD = 'method'; +- +- /** +- * The name of the JSON attribute containing the request parameters. +- */ +- static const String PARAMS = 'params'; +- +- /** +- * The name of the optional JSON attribute indicating the time (milliseconds +- * since epoch) at which the client made the request. +- */ +- static const String CLIENT_REQUEST_TIME = 'clientRequestTime'; +- +- /** +- * The unique identifier used to identify this request. +- */ +- final String id; +- +- /** +- * The method being requested. +- */ +- final String method; +- +- /** +- * A table mapping the names of request parameters to their values. +- */ +- final Map params; +- +- /** +- * The time (milliseconds since epoch) at which the client made the request +- * or `null` if this information is not provided by the client. +- */ +- final int clientRequestTime; +- +- /** +- * Initialize a newly created [Request] to have the given [id] and [method] +- * name. If [params] is supplied, it is used as the "params" map for the +- * request. Otherwise an empty "params" map is allocated. +- */ +- Request(this.id, this.method, +- [Map params, this.clientRequestTime]) +- : params = params ?? {}; +- +- /** +- * Return a request parsed from the given json, or `null` if the [data] is +- * not a valid json representation of a request. The [data] is expected to +- * have the following format: +- * +- * { +- * 'clientRequestTime': millisecondsSinceEpoch +- * 'id': String, +- * 'method': methodName, +- * 'params': { +- * paramter_name: value +- * } +- * } +- * +- * where both the parameters and clientRequestTime are optional. +- * +- * The parameters can contain any number of name/value pairs. The +- * clientRequestTime must be an int representing the time at which the client +- * issued the request (milliseconds since epoch). +- */ +- factory Request.fromJson(Map result) { +- var id = result[Request.ID]; +- var method = result[Request.METHOD]; +- if (id is! String || method is! String) { +- return null; +- } +- var time = result[Request.CLIENT_REQUEST_TIME]; +- if (time != null && time is! int) { +- return null; +- } +- var params = result[Request.PARAMS]; +- if (params is Map || params == null) { +- return new Request(id, method, params as Map, time); +- } else { +- return null; +- } +- } +- +- /** +- * Return a request parsed from the given [data], or `null` if the [data] is +- * not a valid json representation of a request. The [data] is expected to +- * have the following format: +- * +- * { +- * 'clientRequestTime': millisecondsSinceEpoch +- * 'id': String, +- * 'method': methodName, +- * 'params': { +- * paramter_name: value +- * } +- * } +- * +- * where both the parameters and clientRequestTime are optional. +- * +- * The parameters can contain any number of name/value pairs. The +- * clientRequestTime must be an int representing the time at which the client +- * issued the request (milliseconds since epoch). +- */ +- factory Request.fromString(String data) { +- try { +- var result = JSON.decode(data); +- if (result is Map) { +- return new Request.fromJson(result as Map); +- } +- return null; +- } catch (exception) { +- return null; +- } +- } +- +- @override +- int get hashCode { +- return id.hashCode; +- } +- +- @override +- bool operator ==(Object other) { +- return other is Request && +- id == other.id && +- method == other.method && +- clientRequestTime == other.clientRequestTime && +- _equalMaps(params, other.params); +- } +- +- /** +- * Return a table representing the structure of the Json object that will be +- * sent to the client to represent this response. +- */ +- Map toJson() { +- Map jsonObject = {}; +- jsonObject[ID] = id; +- jsonObject[METHOD] = method; +- if (params.isNotEmpty) { +- jsonObject[PARAMS] = params; +- } +- if (clientRequestTime != null) { +- jsonObject[CLIENT_REQUEST_TIME] = clientRequestTime; +- } +- return jsonObject; +- } +- +- bool _equalLists(List first, List second) { +- if (first == null) { +- return second == null; +- } +- if (second == null) { +- return false; +- } +- int length = first.length; +- if (length != second.length) { +- return false; +- } +- for (int i = 0; i < length; i++) { +- if (!_equalObjects(first[i], second[i])) { +- return false; +- } +- } +- return true; +- } +- +- bool _equalMaps(Map first, Map second) { +- if (first == null) { +- return second == null; +- } +- if (second == null) { +- return false; +- } +- if (first.length != second.length) { +- return false; +- } +- for (var key in first.keys) { +- if (!second.containsKey(key)) { +- return false; +- } +- if (!_equalObjects(first[key], second[key])) { +- return false; +- } +- } +- return true; +- } +- +- bool _equalObjects(Object first, Object second) { +- if (first == null) { +- return second == null; +- } +- if (second == null) { +- return false; +- } +- if (first is Map) { +- if (second is Map) { +- return _equalMaps(first, second); +- } +- return false; +- } +- if (first is List) { +- if (second is List) { +- return _equalLists(first, second); +- } +- return false; +- } +- return first == second; +- } +-} +- +-/** +- * An exception that occurred during the handling of a request that requires +- * that an error be returned to the client. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RequestFailure implements Exception { +- /** +- * The response to be returned as a result of the failure. +- */ +- final Response response; +- +- /** +- * Initialize a newly created exception to return the given reponse. +- */ +- RequestFailure(this.response); +-} +- +-/** +- * An object that can handle requests and produce responses for them. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class RequestHandler { +- /** +- * Attempt to handle the given [request]. If the request is not recognized by +- * this handler, return `null` so that other handlers will be given a chance +- * to handle it. Otherwise, return the response that should be passed back to +- * the client. +- */ +- Response handleRequest(Request request); +-} +- +-/** +- * A response to a request. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class Response { +- /** +- * The [Response] instance that is returned when a real [Response] cannot +- * be provided at the moment. +- */ +- static final Response DELAYED_RESPONSE = new Response('DELAYED_RESPONSE'); +- +- /** +- * The name of the JSON attribute containing the id of the request for which +- * this is a response. +- */ +- static const String ID = 'id'; +- +- /** +- * The name of the JSON attribute containing the error message. +- */ +- static const String ERROR = 'error'; +- +- /** +- * The name of the JSON attribute containing the result values. +- */ +- static const String RESULT = 'result'; +- +- /** +- * The unique identifier used to identify the request that this response is +- * associated with. +- */ +- final String id; +- +- /** +- * The error that was caused by attempting to handle the request, or `null` if +- * there was no error. +- */ +- final RequestError error; +- +- /** +- * A table mapping the names of result fields to their values. Should be +- * `null` if there is no result to send. +- */ +- Map result; +- +- /** +- * Initialize a newly created instance to represent a response to a request +- * with the given [id]. If [_result] is provided, it will be used as the +- * result; otherwise an empty result will be used. If an [error] is provided +- * then the response will represent an error condition. +- */ +- Response(this.id, {Map result, this.error}) : result = result; +- +- /** +- * Create and return the `DEBUG_PORT_COULD_NOT_BE_OPENED` error response. +- */ +- Response.debugPortCouldNotBeOpened(Request request, dynamic error) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.DEBUG_PORT_COULD_NOT_BE_OPENED, '$error')); +- +- /** +- * Initialize a newly created instance to represent the FILE_NOT_ANALYZED +- * error condition. +- */ +- Response.fileNotAnalyzed(Request request, String file) +- : this(request.id, +- error: new RequestError(RequestErrorCode.FILE_NOT_ANALYZED, +- 'File is not analyzed: $file.')); +- +- /** +- * Initialize a newly created instance to represent the FORMAT_INVALID_FILE +- * error condition. +- */ +- Response.formatInvalidFile(Request request) +- : this(request.id, +- error: new RequestError(RequestErrorCode.FORMAT_INVALID_FILE, +- 'Error during `edit.format`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the FORMAT_WITH_ERROR +- * error condition. +- */ +- Response.formatWithErrors(Request request) +- : this(request.id, +- error: new RequestError(RequestErrorCode.FORMAT_WITH_ERRORS, +- 'Error during `edit.format`: source contains syntax errors.')); +- +- /** +- * Initialize a newly created instance based on the given JSON data. +- */ +- factory Response.fromJson(Map json) { +- try { +- Object id = json[Response.ID]; +- if (id is! String) { +- return null; +- } +- Object error = json[Response.ERROR]; +- RequestError decodedError; +- if (error is Map) { +- decodedError = new RequestError.fromJson( +- new ResponseDecoder(null), '.error', error); +- } +- Object result = json[Response.RESULT]; +- Map decodedResult; +- if (result is Map) { +- decodedResult = result as Map; +- } +- return new Response(id, error: decodedError, result: decodedResult); +- } catch (exception) { +- return null; +- } +- } +- +- /** +- * Initialize a newly created instance to represent the +- * GET_ERRORS_INVALID_FILE error condition. +- */ +- Response.getErrorsInvalidFile(Request request) +- : this(request.id, +- error: new RequestError(RequestErrorCode.GET_ERRORS_INVALID_FILE, +- 'Error during `analysis.getErrors`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the +- * GET_IMPORTED_ELEMENTS_INVALID_FILE error condition. +- */ +- Response.getImportedElementsInvalidFile(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.GET_IMPORTED_ELEMENTS_INVALID_FILE, +- 'Error during `analysis.getImportedElements`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the +- * GET_KYTHE_ENTRIES_INVALID_FILE error condition. +- */ +- Response.getKytheEntriesInvalidFile(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.GET_KYTHE_ENTRIES_INVALID_FILE, +- 'Error during `analysis.getKytheEntries`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the +- * GET_NAVIGATION_INVALID_FILE error condition. +- */ +- Response.getNavigationInvalidFile(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.GET_NAVIGATION_INVALID_FILE, +- 'Error during `analysis.getNavigation`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the +- * GET_REACHABLE_SOURCES_INVALID_FILE error condition. +- */ +- Response.getReachableSourcesInvalidFile(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE, +- 'Error during `analysis.getReachableSources`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the +- * IMPORT_ELEMENTS_INVALID_FILE error condition. +- */ +- Response.importElementsInvalidFile(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.IMPORT_ELEMENTS_INVALID_FILE, +- 'Error during `edit.importElements`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by an analysis.reanalyze [request] that specifies an analysis root that is +- * not in the current list of analysis roots. +- */ +- Response.invalidAnalysisRoot(Request request, String rootPath) +- : this(request.id, +- error: new RequestError(RequestErrorCode.INVALID_ANALYSIS_ROOT, +- "Invalid analysis root: $rootPath")); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a [request] that specifies an execution context whose context root does +- * not exist. +- */ +- Response.invalidExecutionContext(Request request, String contextId) +- : this(request.id, +- error: new RequestError(RequestErrorCode.INVALID_EXECUTION_CONTEXT, +- "Invalid execution context: $contextId")); +- +- /** +- * Initialize a newly created instance to represent the +- * INVALID_FILE_PATH_FORMAT error condition. +- */ +- Response.invalidFilePathFormat(Request request, path) +- : this(request.id, +- error: new RequestError(RequestErrorCode.INVALID_FILE_PATH_FORMAT, +- 'Invalid file path format: $path')); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a [request] that had invalid parameter. [path] is the path to the +- * invalid parameter, in Javascript notation (e.g. "foo.bar" means that the +- * parameter "foo" contained a key "bar" whose value was the wrong type). +- * [expectation] is a description of the type of data that was expected. +- */ +- Response.invalidParameter(Request request, String path, String expectation) +- : this(request.id, +- error: new RequestError(RequestErrorCode.INVALID_PARAMETER, +- "Invalid parameter '$path'. $expectation.")); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a malformed request. +- */ +- Response.invalidRequestFormat() +- : this('', +- error: new RequestError( +- RequestErrorCode.INVALID_REQUEST, 'Invalid request')); +- +- /** +- * Initialize a newly created instance to represent the +- * ORGANIZE_DIRECTIVES_ERROR error condition. +- */ +- Response.organizeDirectivesError(Request request, String message) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.ORGANIZE_DIRECTIVES_ERROR, message)); +- +- /** +- * Initialize a newly created instance to represent the +- * REFACTORING_REQUEST_CANCELLED error condition. +- */ +- Response.refactoringRequestCancelled(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.REFACTORING_REQUEST_CANCELLED, +- 'The `edit.getRefactoring` request was cancelled.')); +- +- /** +- * Initialize a newly created instance to represent the SERVER_ERROR error +- * condition. +- */ +- factory Response.serverError(Request request, exception, stackTrace) { +- RequestError error = +- new RequestError(RequestErrorCode.SERVER_ERROR, exception.toString()); +- if (stackTrace != null) { +- error.stackTrace = stackTrace.toString(); +- } +- return new Response(request.id, error: error); +- } +- +- /** +- * Initialize a newly created instance to represent the +- * SORT_MEMBERS_INVALID_FILE error condition. +- */ +- Response.sortMembersInvalidFile(Request request) +- : this(request.id, +- error: new RequestError(RequestErrorCode.SORT_MEMBERS_INVALID_FILE, +- 'Error during `edit.sortMembers`: invalid file.')); +- +- /** +- * Initialize a newly created instance to represent the +- * SORT_MEMBERS_PARSE_ERRORS error condition. +- */ +- Response.sortMembersParseErrors(Request request, int numErrors) +- : this(request.id, +- error: new RequestError(RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS, +- 'Error during `edit.sortMembers`: file has $numErrors scan/parse errors.')); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a `analysis.setPriorityFiles` [request] that includes one or more files +- * that are not being analyzed. +- */ +- Response.unanalyzedPriorityFiles(String requestId, String fileNames) +- : this(requestId, +- error: new RequestError(RequestErrorCode.UNANALYZED_PRIORITY_FILES, +- "Unanalyzed files cannot be a priority: '$fileNames'")); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a [request] that cannot be handled by any known handlers. +- */ +- Response.unknownRequest(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.UNKNOWN_REQUEST, 'Unknown request')); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a [request] referencing a source that does not exist. +- */ +- Response.unknownSource(Request request) +- : this(request.id, +- error: new RequestError( +- RequestErrorCode.UNKNOWN_SOURCE, 'Unknown source')); +- +- /** +- * Initialize a newly created instance to represent an error condition caused +- * by a [request] for a service that is not supported. +- */ +- Response.unsupportedFeature(String requestId, String message) +- : this(requestId, +- error: new RequestError( +- RequestErrorCode.UNSUPPORTED_FEATURE, message)); +- +- /** +- * Return a table representing the structure of the Json object that will be +- * sent to the client to represent this response. +- */ +- Map toJson() { +- Map jsonObject = {}; +- jsonObject[ID] = id; +- if (error != null) { +- jsonObject[ERROR] = error.toJson(); +- } +- if (result != null) { +- jsonObject[RESULT] = result; +- } +- return jsonObject; +- } +-} +diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart +deleted file mode 100644 +index 9ff059c1f58..00000000000 +--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart ++++ /dev/null +@@ -1,258 +0,0 @@ +-// 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. +-// +-// This file has been automatically generated. Please do not edit it manually. +-// To regenerate the file, use the script +-// "pkg/analysis_server/tool/spec/generate_files". +- +-const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles'; +-const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories'; +-const String ANALYSIS_NOTIFICATION_CLOSING_LABELS = 'analysis.closingLabels'; +-const String ANALYSIS_NOTIFICATION_CLOSING_LABELS_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_CLOSING_LABELS_LABELS = 'labels'; +-const String ANALYSIS_NOTIFICATION_ERRORS = 'analysis.errors'; +-const String ANALYSIS_NOTIFICATION_ERRORS_ERRORS = 'errors'; +-const String ANALYSIS_NOTIFICATION_ERRORS_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_FLUSH_RESULTS = 'analysis.flushResults'; +-const String ANALYSIS_NOTIFICATION_FLUSH_RESULTS_FILES = 'files'; +-const String ANALYSIS_NOTIFICATION_FOLDING = 'analysis.folding'; +-const String ANALYSIS_NOTIFICATION_FOLDING_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_FOLDING_REGIONS = 'regions'; +-const String ANALYSIS_NOTIFICATION_HIGHLIGHTS = 'analysis.highlights'; +-const String ANALYSIS_NOTIFICATION_HIGHLIGHTS_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_HIGHLIGHTS_REGIONS = 'regions'; +-const String ANALYSIS_NOTIFICATION_IMPLEMENTED = 'analysis.implemented'; +-const String ANALYSIS_NOTIFICATION_IMPLEMENTED_CLASSES = 'classes'; +-const String ANALYSIS_NOTIFICATION_IMPLEMENTED_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_IMPLEMENTED_MEMBERS = 'members'; +-const String ANALYSIS_NOTIFICATION_INVALIDATE = 'analysis.invalidate'; +-const String ANALYSIS_NOTIFICATION_INVALIDATE_DELTA = 'delta'; +-const String ANALYSIS_NOTIFICATION_INVALIDATE_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_INVALIDATE_LENGTH = 'length'; +-const String ANALYSIS_NOTIFICATION_INVALIDATE_OFFSET = 'offset'; +-const String ANALYSIS_NOTIFICATION_NAVIGATION = 'analysis.navigation'; +-const String ANALYSIS_NOTIFICATION_NAVIGATION_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_NAVIGATION_FILES = 'files'; +-const String ANALYSIS_NOTIFICATION_NAVIGATION_REGIONS = 'regions'; +-const String ANALYSIS_NOTIFICATION_NAVIGATION_TARGETS = 'targets'; +-const String ANALYSIS_NOTIFICATION_OCCURRENCES = 'analysis.occurrences'; +-const String ANALYSIS_NOTIFICATION_OCCURRENCES_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_OCCURRENCES_OCCURRENCES = 'occurrences'; +-const String ANALYSIS_NOTIFICATION_OUTLINE = 'analysis.outline'; +-const String ANALYSIS_NOTIFICATION_OUTLINE_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_OUTLINE_KIND = 'kind'; +-const String ANALYSIS_NOTIFICATION_OUTLINE_LIBRARY_NAME = 'libraryName'; +-const String ANALYSIS_NOTIFICATION_OUTLINE_OUTLINE = 'outline'; +-const String ANALYSIS_NOTIFICATION_OVERRIDES = 'analysis.overrides'; +-const String ANALYSIS_NOTIFICATION_OVERRIDES_FILE = 'file'; +-const String ANALYSIS_NOTIFICATION_OVERRIDES_OVERRIDES = 'overrides'; +-const String ANALYSIS_REQUEST_GET_ERRORS = 'analysis.getErrors'; +-const String ANALYSIS_REQUEST_GET_ERRORS_FILE = 'file'; +-const String ANALYSIS_REQUEST_GET_HOVER = 'analysis.getHover'; +-const String ANALYSIS_REQUEST_GET_HOVER_FILE = 'file'; +-const String ANALYSIS_REQUEST_GET_HOVER_OFFSET = 'offset'; +-const String ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS = +- 'analysis.getImportedElements'; +-const String ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS_FILE = 'file'; +-const String ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS_LENGTH = 'length'; +-const String ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS_OFFSET = 'offset'; +-const String ANALYSIS_REQUEST_GET_LIBRARY_DEPENDENCIES = +- 'analysis.getLibraryDependencies'; +-const String ANALYSIS_REQUEST_GET_NAVIGATION = 'analysis.getNavigation'; +-const String ANALYSIS_REQUEST_GET_NAVIGATION_FILE = 'file'; +-const String ANALYSIS_REQUEST_GET_NAVIGATION_LENGTH = 'length'; +-const String ANALYSIS_REQUEST_GET_NAVIGATION_OFFSET = 'offset'; +-const String ANALYSIS_REQUEST_GET_REACHABLE_SOURCES = +- 'analysis.getReachableSources'; +-const String ANALYSIS_REQUEST_GET_REACHABLE_SOURCES_FILE = 'file'; +-const String ANALYSIS_REQUEST_REANALYZE = 'analysis.reanalyze'; +-const String ANALYSIS_REQUEST_REANALYZE_ROOTS = 'roots'; +-const String ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS = 'analysis.setAnalysisRoots'; +-const String ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_EXCLUDED = 'excluded'; +-const String ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_INCLUDED = 'included'; +-const String ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS_PACKAGE_ROOTS = 'packageRoots'; +-const String ANALYSIS_REQUEST_SET_GENERAL_SUBSCRIPTIONS = +- 'analysis.setGeneralSubscriptions'; +-const String ANALYSIS_REQUEST_SET_GENERAL_SUBSCRIPTIONS_SUBSCRIPTIONS = +- 'subscriptions'; +-const String ANALYSIS_REQUEST_SET_PRIORITY_FILES = 'analysis.setPriorityFiles'; +-const String ANALYSIS_REQUEST_SET_PRIORITY_FILES_FILES = 'files'; +-const String ANALYSIS_REQUEST_SET_SUBSCRIPTIONS = 'analysis.setSubscriptions'; +-const String ANALYSIS_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS = 'subscriptions'; +-const String ANALYSIS_REQUEST_UPDATE_CONTENT = 'analysis.updateContent'; +-const String ANALYSIS_REQUEST_UPDATE_CONTENT_FILES = 'files'; +-const String ANALYSIS_REQUEST_UPDATE_OPTIONS = 'analysis.updateOptions'; +-const String ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS = 'options'; +-const String ANALYSIS_RESPONSE_GET_ERRORS_ERRORS = 'errors'; +-const String ANALYSIS_RESPONSE_GET_HOVER_HOVERS = 'hovers'; +-const String ANALYSIS_RESPONSE_GET_IMPORTED_ELEMENTS_ELEMENTS = 'elements'; +-const String ANALYSIS_RESPONSE_GET_LIBRARY_DEPENDENCIES_LIBRARIES = 'libraries'; +-const String ANALYSIS_RESPONSE_GET_LIBRARY_DEPENDENCIES_PACKAGE_MAP = +- 'packageMap'; +-const String ANALYSIS_RESPONSE_GET_NAVIGATION_FILES = 'files'; +-const String ANALYSIS_RESPONSE_GET_NAVIGATION_REGIONS = 'regions'; +-const String ANALYSIS_RESPONSE_GET_NAVIGATION_TARGETS = 'targets'; +-const String ANALYSIS_RESPONSE_GET_REACHABLE_SOURCES_SOURCES = 'sources'; +-const String ANALYTICS_REQUEST_ENABLE = 'analytics.enable'; +-const String ANALYTICS_REQUEST_ENABLE_VALUE = 'value'; +-const String ANALYTICS_REQUEST_IS_ENABLED = 'analytics.isEnabled'; +-const String ANALYTICS_REQUEST_SEND_EVENT = 'analytics.sendEvent'; +-const String ANALYTICS_REQUEST_SEND_EVENT_ACTION = 'action'; +-const String ANALYTICS_REQUEST_SEND_TIMING = 'analytics.sendTiming'; +-const String ANALYTICS_REQUEST_SEND_TIMING_EVENT = 'event'; +-const String ANALYTICS_REQUEST_SEND_TIMING_MILLIS = 'millis'; +-const String ANALYTICS_RESPONSE_IS_ENABLED_ENABLED = 'enabled'; +-const String COMPLETION_NOTIFICATION_RESULTS = 'completion.results'; +-const String COMPLETION_NOTIFICATION_RESULTS_ID = 'id'; +-const String COMPLETION_NOTIFICATION_RESULTS_IS_LAST = 'isLast'; +-const String COMPLETION_NOTIFICATION_RESULTS_REPLACEMENT_LENGTH = +- 'replacementLength'; +-const String COMPLETION_NOTIFICATION_RESULTS_REPLACEMENT_OFFSET = +- 'replacementOffset'; +-const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results'; +-const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions'; +-const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file'; +-const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset'; +-const String COMPLETION_RESPONSE_GET_SUGGESTIONS_ID = 'id'; +-const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics'; +-const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort'; +-const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts'; +-const String DIAGNOSTIC_RESPONSE_GET_SERVER_PORT_PORT = 'port'; +-const String EDIT_REQUEST_FORMAT = 'edit.format'; +-const String EDIT_REQUEST_FORMAT_FILE = 'file'; +-const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength'; +-const String EDIT_REQUEST_FORMAT_SELECTION_LENGTH = 'selectionLength'; +-const String EDIT_REQUEST_FORMAT_SELECTION_OFFSET = 'selectionOffset'; +-const String EDIT_REQUEST_GET_ASSISTS = 'edit.getAssists'; +-const String EDIT_REQUEST_GET_ASSISTS_FILE = 'file'; +-const String EDIT_REQUEST_GET_ASSISTS_LENGTH = 'length'; +-const String EDIT_REQUEST_GET_ASSISTS_OFFSET = 'offset'; +-const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS = +- 'edit.getAvailableRefactorings'; +-const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_FILE = 'file'; +-const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_LENGTH = 'length'; +-const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_OFFSET = 'offset'; +-const String EDIT_REQUEST_GET_FIXES = 'edit.getFixes'; +-const String EDIT_REQUEST_GET_FIXES_FILE = 'file'; +-const String EDIT_REQUEST_GET_FIXES_OFFSET = 'offset'; +-const String EDIT_REQUEST_GET_POSTFIX_COMPLETION = 'edit.getPostfixCompletion'; +-const String EDIT_REQUEST_GET_POSTFIX_COMPLETION_FILE = 'file'; +-const String EDIT_REQUEST_GET_POSTFIX_COMPLETION_KEY = 'key'; +-const String EDIT_REQUEST_GET_POSTFIX_COMPLETION_OFFSET = 'offset'; +-const String EDIT_REQUEST_GET_REFACTORING = 'edit.getRefactoring'; +-const String EDIT_REQUEST_GET_REFACTORING_FILE = 'file'; +-const String EDIT_REQUEST_GET_REFACTORING_KIND = 'kind'; +-const String EDIT_REQUEST_GET_REFACTORING_LENGTH = 'length'; +-const String EDIT_REQUEST_GET_REFACTORING_OFFSET = 'offset'; +-const String EDIT_REQUEST_GET_REFACTORING_OPTIONS = 'options'; +-const String EDIT_REQUEST_GET_REFACTORING_VALIDATE_ONLY = 'validateOnly'; +-const String EDIT_REQUEST_GET_STATEMENT_COMPLETION = +- 'edit.getStatementCompletion'; +-const String EDIT_REQUEST_GET_STATEMENT_COMPLETION_FILE = 'file'; +-const String EDIT_REQUEST_GET_STATEMENT_COMPLETION_OFFSET = 'offset'; +-const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements'; +-const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements'; +-const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file'; +-const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE = +- 'edit.isPostfixCompletionApplicable'; +-const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file'; +-const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_KEY = 'key'; +-const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_OFFSET = 'offset'; +-const String EDIT_REQUEST_LIST_POSTFIX_COMPLETION_TEMPLATES = +- 'edit.listPostfixCompletionTemplates'; +-const String EDIT_REQUEST_ORGANIZE_DIRECTIVES = 'edit.organizeDirectives'; +-const String EDIT_REQUEST_ORGANIZE_DIRECTIVES_FILE = 'file'; +-const String EDIT_REQUEST_SORT_MEMBERS = 'edit.sortMembers'; +-const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file'; +-const String EDIT_RESPONSE_FORMAT_EDITS = 'edits'; +-const String EDIT_RESPONSE_FORMAT_SELECTION_LENGTH = 'selectionLength'; +-const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset'; +-const String EDIT_RESPONSE_GET_ASSISTS_ASSISTS = 'assists'; +-const String EDIT_RESPONSE_GET_AVAILABLE_REFACTORINGS_KINDS = 'kinds'; +-const String EDIT_RESPONSE_GET_FIXES_FIXES = 'fixes'; +-const String EDIT_RESPONSE_GET_POSTFIX_COMPLETION_CHANGE = 'change'; +-const String EDIT_RESPONSE_GET_REFACTORING_CHANGE = 'change'; +-const String EDIT_RESPONSE_GET_REFACTORING_FEEDBACK = 'feedback'; +-const String EDIT_RESPONSE_GET_REFACTORING_FINAL_PROBLEMS = 'finalProblems'; +-const String EDIT_RESPONSE_GET_REFACTORING_INITIAL_PROBLEMS = 'initialProblems'; +-const String EDIT_RESPONSE_GET_REFACTORING_OPTIONS_PROBLEMS = 'optionsProblems'; +-const String EDIT_RESPONSE_GET_REFACTORING_POTENTIAL_EDITS = 'potentialEdits'; +-const String EDIT_RESPONSE_GET_STATEMENT_COMPLETION_CHANGE = 'change'; +-const String EDIT_RESPONSE_GET_STATEMENT_COMPLETION_WHITESPACE_ONLY = +- 'whitespaceOnly'; +-const String EDIT_RESPONSE_IMPORT_ELEMENTS_EDIT = 'edit'; +-const String EDIT_RESPONSE_IS_POSTFIX_COMPLETION_APPLICABLE_VALUE = 'value'; +-const String EDIT_RESPONSE_LIST_POSTFIX_COMPLETION_TEMPLATES_TEMPLATES = +- 'templates'; +-const String EDIT_RESPONSE_ORGANIZE_DIRECTIVES_EDIT = 'edit'; +-const String EDIT_RESPONSE_SORT_MEMBERS_EDIT = 'edit'; +-const String EXECUTION_NOTIFICATION_LAUNCH_DATA = 'execution.launchData'; +-const String EXECUTION_NOTIFICATION_LAUNCH_DATA_FILE = 'file'; +-const String EXECUTION_NOTIFICATION_LAUNCH_DATA_KIND = 'kind'; +-const String EXECUTION_NOTIFICATION_LAUNCH_DATA_REFERENCED_FILES = +- 'referencedFiles'; +-const String EXECUTION_REQUEST_CREATE_CONTEXT = 'execution.createContext'; +-const String EXECUTION_REQUEST_CREATE_CONTEXT_CONTEXT_ROOT = 'contextRoot'; +-const String EXECUTION_REQUEST_DELETE_CONTEXT = 'execution.deleteContext'; +-const String EXECUTION_REQUEST_DELETE_CONTEXT_ID = 'id'; +-const String EXECUTION_REQUEST_MAP_URI = 'execution.mapUri'; +-const String EXECUTION_REQUEST_MAP_URI_FILE = 'file'; +-const String EXECUTION_REQUEST_MAP_URI_ID = 'id'; +-const String EXECUTION_REQUEST_MAP_URI_URI = 'uri'; +-const String EXECUTION_REQUEST_SET_SUBSCRIPTIONS = 'execution.setSubscriptions'; +-const String EXECUTION_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS = +- 'subscriptions'; +-const String EXECUTION_RESPONSE_CREATE_CONTEXT_ID = 'id'; +-const String EXECUTION_RESPONSE_MAP_URI_FILE = 'file'; +-const String EXECUTION_RESPONSE_MAP_URI_URI = 'uri'; +-const String KYTHE_REQUEST_GET_KYTHE_ENTRIES = 'kythe.getKytheEntries'; +-const String KYTHE_REQUEST_GET_KYTHE_ENTRIES_FILE = 'file'; +-const String KYTHE_RESPONSE_GET_KYTHE_ENTRIES_ENTRIES = 'entries'; +-const String KYTHE_RESPONSE_GET_KYTHE_ENTRIES_FILES = 'files'; +-const String SEARCH_NOTIFICATION_RESULTS = 'search.results'; +-const String SEARCH_NOTIFICATION_RESULTS_ID = 'id'; +-const String SEARCH_NOTIFICATION_RESULTS_IS_LAST = 'isLast'; +-const String SEARCH_NOTIFICATION_RESULTS_RESULTS = 'results'; +-const String SEARCH_REQUEST_FIND_ELEMENT_REFERENCES = +- 'search.findElementReferences'; +-const String SEARCH_REQUEST_FIND_ELEMENT_REFERENCES_FILE = 'file'; +-const String SEARCH_REQUEST_FIND_ELEMENT_REFERENCES_INCLUDE_POTENTIAL = +- 'includePotential'; +-const String SEARCH_REQUEST_FIND_ELEMENT_REFERENCES_OFFSET = 'offset'; +-const String SEARCH_REQUEST_FIND_MEMBER_DECLARATIONS = +- 'search.findMemberDeclarations'; +-const String SEARCH_REQUEST_FIND_MEMBER_DECLARATIONS_NAME = 'name'; +-const String SEARCH_REQUEST_FIND_MEMBER_REFERENCES = +- 'search.findMemberReferences'; +-const String SEARCH_REQUEST_FIND_MEMBER_REFERENCES_NAME = 'name'; +-const String SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS = +- 'search.findTopLevelDeclarations'; +-const String SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS_PATTERN = 'pattern'; +-const String SEARCH_REQUEST_GET_TYPE_HIERARCHY = 'search.getTypeHierarchy'; +-const String SEARCH_REQUEST_GET_TYPE_HIERARCHY_FILE = 'file'; +-const String SEARCH_REQUEST_GET_TYPE_HIERARCHY_OFFSET = 'offset'; +-const String SEARCH_REQUEST_GET_TYPE_HIERARCHY_SUPER_ONLY = 'superOnly'; +-const String SEARCH_RESPONSE_FIND_ELEMENT_REFERENCES_ELEMENT = 'element'; +-const String SEARCH_RESPONSE_FIND_ELEMENT_REFERENCES_ID = 'id'; +-const String SEARCH_RESPONSE_FIND_MEMBER_DECLARATIONS_ID = 'id'; +-const String SEARCH_RESPONSE_FIND_MEMBER_REFERENCES_ID = 'id'; +-const String SEARCH_RESPONSE_FIND_TOP_LEVEL_DECLARATIONS_ID = 'id'; +-const String SEARCH_RESPONSE_GET_TYPE_HIERARCHY_HIERARCHY_ITEMS = +- 'hierarchyItems'; +-const String SERVER_NOTIFICATION_CONNECTED = 'server.connected'; +-const String SERVER_NOTIFICATION_CONNECTED_PID = 'pid'; +-const String SERVER_NOTIFICATION_CONNECTED_SESSION_ID = 'sessionId'; +-const String SERVER_NOTIFICATION_CONNECTED_VERSION = 'version'; +-const String SERVER_NOTIFICATION_ERROR = 'server.error'; +-const String SERVER_NOTIFICATION_ERROR_IS_FATAL = 'isFatal'; +-const String SERVER_NOTIFICATION_ERROR_MESSAGE = 'message'; +-const String SERVER_NOTIFICATION_ERROR_STACK_TRACE = 'stackTrace'; +-const String SERVER_NOTIFICATION_STATUS = 'server.status'; +-const String SERVER_NOTIFICATION_STATUS_ANALYSIS = 'analysis'; +-const String SERVER_NOTIFICATION_STATUS_PUB = 'pub'; +-const String SERVER_REQUEST_GET_VERSION = 'server.getVersion'; +-const String SERVER_REQUEST_SET_SUBSCRIPTIONS = 'server.setSubscriptions'; +-const String SERVER_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS = 'subscriptions'; +-const String SERVER_REQUEST_SHUTDOWN = 'server.shutdown'; +-const String SERVER_RESPONSE_GET_VERSION_VERSION = 'version'; +diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart +deleted file mode 100644 +index 20400573c49..00000000000 +--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart ++++ /dev/null +@@ -1,15802 +0,0 @@ +-// 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. +-// +-// This file has been automatically generated. Please do not edit it manually. +-// To regenerate the file, use the script +-// "pkg/analysis_server/tool/spec/generate_files". +- +-import 'dart:convert' hide JsonDecoder; +- +-import 'package:analyzer/src/generated/utilities_general.dart'; +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * analysis.analyzedFiles params +- * +- * { +- * "directories": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisAnalyzedFilesParams implements HasToJson { +- List _directories; +- +- /** +- * A list of the paths of the files that are being analyzed. +- */ +- List get directories => _directories; +- +- /** +- * A list of the paths of the files that are being analyzed. +- */ +- void set directories(List value) { +- assert(value != null); +- this._directories = value; +- } +- +- AnalysisAnalyzedFilesParams(List directories) { +- this.directories = directories; +- } +- +- factory AnalysisAnalyzedFilesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List directories; +- if (json.containsKey("directories")) { +- directories = jsonDecoder.decodeList(jsonPath + ".directories", +- json["directories"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "directories"); +- } +- return new AnalysisAnalyzedFilesParams(directories); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.analyzedFiles params", json); +- } +- } +- +- factory AnalysisAnalyzedFilesParams.fromNotification( +- Notification notification) { +- return new AnalysisAnalyzedFilesParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["directories"] = directories; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.analyzedFiles", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisAnalyzedFilesParams) { +- return listEqual( +- directories, other.directories, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, directories.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.closingLabels params +- * +- * { +- * "file": FilePath +- * "labels": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisClosingLabelsParams implements HasToJson { +- String _file; +- +- List _labels; +- +- /** +- * The file the closing labels relate to. +- */ +- String get file => _file; +- +- /** +- * The file the closing labels relate to. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * Closing labels relevant to the file. Each item represents a useful label +- * associated with some range with may be useful to display to the user +- * within the editor at the end of the range to indicate what construct is +- * closed at that location. Closing labels include constructor/method calls +- * and List arguments that span multiple lines. Note that the ranges that are +- * returned can overlap each other because they may be associated with +- * constructs that can be nested. +- */ +- List get labels => _labels; +- +- /** +- * Closing labels relevant to the file. Each item represents a useful label +- * associated with some range with may be useful to display to the user +- * within the editor at the end of the range to indicate what construct is +- * closed at that location. Closing labels include constructor/method calls +- * and List arguments that span multiple lines. Note that the ranges that are +- * returned can overlap each other because they may be associated with +- * constructs that can be nested. +- */ +- void set labels(List value) { +- assert(value != null); +- this._labels = value; +- } +- +- AnalysisClosingLabelsParams(String file, List labels) { +- this.file = file; +- this.labels = labels; +- } +- +- factory AnalysisClosingLabelsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List labels; +- if (json.containsKey("labels")) { +- labels = jsonDecoder.decodeList( +- jsonPath + ".labels", +- json["labels"], +- (String jsonPath, Object json) => +- new ClosingLabel.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "labels"); +- } +- return new AnalysisClosingLabelsParams(file, labels); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.closingLabels params", json); +- } +- } +- +- factory AnalysisClosingLabelsParams.fromNotification( +- Notification notification) { +- return new AnalysisClosingLabelsParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["labels"] = +- labels.map((ClosingLabel value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.closingLabels", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisClosingLabelsParams) { +- return file == other.file && +- listEqual( +- labels, other.labels, (ClosingLabel a, ClosingLabel b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, labels.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * AnalysisErrorFixes +- * +- * { +- * "error": AnalysisError +- * "fixes": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisErrorFixes implements HasToJson { +- AnalysisError _error; +- +- List _fixes; +- +- /** +- * The error with which the fixes are associated. +- */ +- AnalysisError get error => _error; +- +- /** +- * The error with which the fixes are associated. +- */ +- void set error(AnalysisError value) { +- assert(value != null); +- this._error = value; +- } +- +- /** +- * The fixes associated with the error. +- */ +- List get fixes => _fixes; +- +- /** +- * The fixes associated with the error. +- */ +- void set fixes(List value) { +- assert(value != null); +- this._fixes = value; +- } +- +- AnalysisErrorFixes(AnalysisError error, {List fixes}) { +- this.error = error; +- if (fixes == null) { +- this.fixes = []; +- } else { +- this.fixes = fixes; +- } +- } +- +- factory AnalysisErrorFixes.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- AnalysisError error; +- if (json.containsKey("error")) { +- error = new AnalysisError.fromJson( +- jsonDecoder, jsonPath + ".error", json["error"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "error"); +- } +- List fixes; +- if (json.containsKey("fixes")) { +- fixes = jsonDecoder.decodeList( +- jsonPath + ".fixes", +- json["fixes"], +- (String jsonPath, Object json) => +- new SourceChange.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "fixes"); +- } +- return new AnalysisErrorFixes(error, fixes: fixes); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "AnalysisErrorFixes", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["error"] = error.toJson(); +- result["fixes"] = +- fixes.map((SourceChange value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisErrorFixes) { +- return error == other.error && +- listEqual( +- fixes, other.fixes, (SourceChange a, SourceChange b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, error.hashCode); +- hash = JenkinsSmiHash.combine(hash, fixes.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.errors params +- * +- * { +- * "file": FilePath +- * "errors": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisErrorsParams implements HasToJson { +- String _file; +- +- List _errors; +- +- /** +- * The file containing the errors. +- */ +- String get file => _file; +- +- /** +- * The file containing the errors. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The errors contained in the file. +- */ +- List get errors => _errors; +- +- /** +- * The errors contained in the file. +- */ +- void set errors(List value) { +- assert(value != null); +- this._errors = value; +- } +- +- AnalysisErrorsParams(String file, List errors) { +- this.file = file; +- this.errors = errors; +- } +- +- factory AnalysisErrorsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List errors; +- if (json.containsKey("errors")) { +- errors = jsonDecoder.decodeList( +- jsonPath + ".errors", +- json["errors"], +- (String jsonPath, Object json) => +- new AnalysisError.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "errors"); +- } +- return new AnalysisErrorsParams(file, errors); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.errors params", json); +- } +- } +- +- factory AnalysisErrorsParams.fromNotification(Notification notification) { +- return new AnalysisErrorsParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["errors"] = +- errors.map((AnalysisError value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.errors", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisErrorsParams) { +- return file == other.file && +- listEqual(errors, other.errors, +- (AnalysisError a, AnalysisError b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, errors.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.flushResults params +- * +- * { +- * "files": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisFlushResultsParams implements HasToJson { +- List _files; +- +- /** +- * The files that are no longer being analyzed. +- */ +- List get files => _files; +- +- /** +- * The files that are no longer being analyzed. +- */ +- void set files(List value) { +- assert(value != null); +- this._files = value; +- } +- +- AnalysisFlushResultsParams(List files) { +- this.files = files; +- } +- +- factory AnalysisFlushResultsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List files; +- if (json.containsKey("files")) { +- files = jsonDecoder.decodeList( +- jsonPath + ".files", json["files"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "files"); +- } +- return new AnalysisFlushResultsParams(files); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.flushResults params", json); +- } +- } +- +- factory AnalysisFlushResultsParams.fromNotification( +- Notification notification) { +- return new AnalysisFlushResultsParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["files"] = files; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.flushResults", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisFlushResultsParams) { +- return listEqual(files, other.files, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, files.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.folding params +- * +- * { +- * "file": FilePath +- * "regions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisFoldingParams implements HasToJson { +- String _file; +- +- List _regions; +- +- /** +- * The file containing the folding regions. +- */ +- String get file => _file; +- +- /** +- * The file containing the folding regions. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The folding regions contained in the file. +- */ +- List get regions => _regions; +- +- /** +- * The folding regions contained in the file. +- */ +- void set regions(List value) { +- assert(value != null); +- this._regions = value; +- } +- +- AnalysisFoldingParams(String file, List regions) { +- this.file = file; +- this.regions = regions; +- } +- +- factory AnalysisFoldingParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List regions; +- if (json.containsKey("regions")) { +- regions = jsonDecoder.decodeList( +- jsonPath + ".regions", +- json["regions"], +- (String jsonPath, Object json) => +- new FoldingRegion.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "regions"); +- } +- return new AnalysisFoldingParams(file, regions); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.folding params", json); +- } +- } +- +- factory AnalysisFoldingParams.fromNotification(Notification notification) { +- return new AnalysisFoldingParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["regions"] = +- regions.map((FoldingRegion value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.folding", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisFoldingParams) { +- return file == other.file && +- listEqual(regions, other.regions, +- (FoldingRegion a, FoldingRegion b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, regions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getErrors params +- * +- * { +- * "file": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetErrorsParams implements RequestParams { +- String _file; +- +- /** +- * The file for which errors are being requested. +- */ +- String get file => _file; +- +- /** +- * The file for which errors are being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- AnalysisGetErrorsParams(String file) { +- this.file = file; +- } +- +- factory AnalysisGetErrorsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- return new AnalysisGetErrorsParams(file); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.getErrors params", json); +- } +- } +- +- factory AnalysisGetErrorsParams.fromRequest(Request request) { +- return new AnalysisGetErrorsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.getErrors", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetErrorsParams) { +- return file == other.file; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getErrors result +- * +- * { +- * "errors": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetErrorsResult implements ResponseResult { +- List _errors; +- +- /** +- * The errors associated with the file. +- */ +- List get errors => _errors; +- +- /** +- * The errors associated with the file. +- */ +- void set errors(List value) { +- assert(value != null); +- this._errors = value; +- } +- +- AnalysisGetErrorsResult(List errors) { +- this.errors = errors; +- } +- +- factory AnalysisGetErrorsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List errors; +- if (json.containsKey("errors")) { +- errors = jsonDecoder.decodeList( +- jsonPath + ".errors", +- json["errors"], +- (String jsonPath, Object json) => +- new AnalysisError.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "errors"); +- } +- return new AnalysisGetErrorsResult(errors); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.getErrors result", json); +- } +- } +- +- factory AnalysisGetErrorsResult.fromResponse(Response response) { +- return new AnalysisGetErrorsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["errors"] = +- errors.map((AnalysisError value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetErrorsResult) { +- return listEqual( +- errors, other.errors, (AnalysisError a, AnalysisError b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, errors.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getHover params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetHoverParams implements RequestParams { +- String _file; +- +- int _offset; +- +- /** +- * The file in which hover information is being requested. +- */ +- String get file => _file; +- +- /** +- * The file in which hover information is being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset for which hover information is being requested. +- */ +- int get offset => _offset; +- +- /** +- * The offset for which hover information is being requested. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- AnalysisGetHoverParams(String file, int offset) { +- this.file = file; +- this.offset = offset; +- } +- +- factory AnalysisGetHoverParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- return new AnalysisGetHoverParams(file, offset); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.getHover params", json); +- } +- } +- +- factory AnalysisGetHoverParams.fromRequest(Request request) { +- return new AnalysisGetHoverParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.getHover", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetHoverParams) { +- return file == other.file && offset == other.offset; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getHover result +- * +- * { +- * "hovers": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetHoverResult implements ResponseResult { +- List _hovers; +- +- /** +- * The hover information associated with the location. The list will be empty +- * if no information could be determined for the location. The list can +- * contain multiple items if the file is being analyzed in multiple contexts +- * in conflicting ways (such as a part that is included in multiple +- * libraries). +- */ +- List get hovers => _hovers; +- +- /** +- * The hover information associated with the location. The list will be empty +- * if no information could be determined for the location. The list can +- * contain multiple items if the file is being analyzed in multiple contexts +- * in conflicting ways (such as a part that is included in multiple +- * libraries). +- */ +- void set hovers(List value) { +- assert(value != null); +- this._hovers = value; +- } +- +- AnalysisGetHoverResult(List hovers) { +- this.hovers = hovers; +- } +- +- factory AnalysisGetHoverResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List hovers; +- if (json.containsKey("hovers")) { +- hovers = jsonDecoder.decodeList( +- jsonPath + ".hovers", +- json["hovers"], +- (String jsonPath, Object json) => +- new HoverInformation.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "hovers"); +- } +- return new AnalysisGetHoverResult(hovers); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.getHover result", json); +- } +- } +- +- factory AnalysisGetHoverResult.fromResponse(Response response) { +- return new AnalysisGetHoverResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["hovers"] = +- hovers.map((HoverInformation value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetHoverResult) { +- return listEqual(hovers, other.hovers, +- (HoverInformation a, HoverInformation b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, hovers.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getImportedElements params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetImportedElementsParams implements RequestParams { +- String _file; +- +- int _offset; +- +- int _length; +- +- /** +- * The file in which import information is being requested. +- */ +- String get file => _file; +- +- /** +- * The file in which import information is being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the region for which import information is being requested. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the region for which import information is being requested. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the region for which import information is being requested. +- */ +- int get length => _length; +- +- /** +- * The length of the region for which import information is being requested. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- AnalysisGetImportedElementsParams(String file, int offset, int length) { +- this.file = file; +- this.offset = offset; +- this.length = length; +- } +- +- factory AnalysisGetImportedElementsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- return new AnalysisGetImportedElementsParams(file, offset, length); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getImportedElements params", json); +- } +- } +- +- factory AnalysisGetImportedElementsParams.fromRequest(Request request) { +- return new AnalysisGetImportedElementsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- result["length"] = length; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.getImportedElements", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetImportedElementsParams) { +- return file == other.file && +- offset == other.offset && +- length == other.length; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getImportedElements result +- * +- * { +- * "elements": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetImportedElementsResult implements ResponseResult { +- List _elements; +- +- /** +- * The information about the elements that are referenced in the specified +- * region of the specified file that come from imported libraries. +- */ +- List get elements => _elements; +- +- /** +- * The information about the elements that are referenced in the specified +- * region of the specified file that come from imported libraries. +- */ +- void set elements(List value) { +- assert(value != null); +- this._elements = value; +- } +- +- AnalysisGetImportedElementsResult(List elements) { +- this.elements = elements; +- } +- +- factory AnalysisGetImportedElementsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List elements; +- if (json.containsKey("elements")) { +- elements = jsonDecoder.decodeList( +- jsonPath + ".elements", +- json["elements"], +- (String jsonPath, Object json) => +- new ImportedElements.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "elements"); +- } +- return new AnalysisGetImportedElementsResult(elements); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getImportedElements result", json); +- } +- } +- +- factory AnalysisGetImportedElementsResult.fromResponse(Response response) { +- return new AnalysisGetImportedElementsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["elements"] = +- elements.map((ImportedElements value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetImportedElementsResult) { +- return listEqual(elements, other.elements, +- (ImportedElements a, ImportedElements b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, elements.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getLibraryDependencies params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetLibraryDependenciesParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.getLibraryDependencies", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetLibraryDependenciesParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 246577680; +- } +-} +- +-/** +- * analysis.getLibraryDependencies result +- * +- * { +- * "libraries": List +- * "packageMap": Map>> +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetLibraryDependenciesResult implements ResponseResult { +- List _libraries; +- +- Map>> _packageMap; +- +- /** +- * A list of the paths of library elements referenced by files in existing +- * analysis roots. +- */ +- List get libraries => _libraries; +- +- /** +- * A list of the paths of library elements referenced by files in existing +- * analysis roots. +- */ +- void set libraries(List value) { +- assert(value != null); +- this._libraries = value; +- } +- +- /** +- * A mapping from context source roots to package maps which map package +- * names to source directories for use in client-side package URI resolution. +- */ +- Map>> get packageMap => _packageMap; +- +- /** +- * A mapping from context source roots to package maps which map package +- * names to source directories for use in client-side package URI resolution. +- */ +- void set packageMap(Map>> value) { +- assert(value != null); +- this._packageMap = value; +- } +- +- AnalysisGetLibraryDependenciesResult(List libraries, +- Map>> packageMap) { +- this.libraries = libraries; +- this.packageMap = packageMap; +- } +- +- factory AnalysisGetLibraryDependenciesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List libraries; +- if (json.containsKey("libraries")) { +- libraries = jsonDecoder.decodeList(jsonPath + ".libraries", +- json["libraries"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "libraries"); +- } +- Map>> packageMap; +- if (json.containsKey("packageMap")) { +- packageMap = jsonDecoder.decodeMap( +- jsonPath + ".packageMap", json["packageMap"], +- valueDecoder: (String jsonPath, Object json) => +- jsonDecoder.decodeMap(jsonPath, json, +- valueDecoder: (String jsonPath, Object json) => jsonDecoder +- .decodeList(jsonPath, json, jsonDecoder.decodeString))); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "packageMap"); +- } +- return new AnalysisGetLibraryDependenciesResult(libraries, packageMap); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getLibraryDependencies result", json); +- } +- } +- +- factory AnalysisGetLibraryDependenciesResult.fromResponse(Response response) { +- return new AnalysisGetLibraryDependenciesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["libraries"] = libraries; +- result["packageMap"] = packageMap; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetLibraryDependenciesResult) { +- return listEqual( +- libraries, other.libraries, (String a, String b) => a == b) && +- mapEqual( +- packageMap, +- other.packageMap, +- (Map> a, Map> b) => +- mapEqual( +- a, +- b, +- (List a, List b) => +- listEqual(a, b, (String a, String b) => a == b))); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, libraries.hashCode); +- hash = JenkinsSmiHash.combine(hash, packageMap.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getNavigation params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetNavigationParams implements RequestParams { +- String _file; +- +- int _offset; +- +- int _length; +- +- /** +- * The file in which navigation information is being requested. +- */ +- String get file => _file; +- +- /** +- * The file in which navigation information is being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the region for which navigation information is being +- * requested. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the region for which navigation information is being +- * requested. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the region for which navigation information is being +- * requested. +- */ +- int get length => _length; +- +- /** +- * The length of the region for which navigation information is being +- * requested. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- AnalysisGetNavigationParams(String file, int offset, int length) { +- this.file = file; +- this.offset = offset; +- this.length = length; +- } +- +- factory AnalysisGetNavigationParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- return new AnalysisGetNavigationParams(file, offset, length); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getNavigation params", json); +- } +- } +- +- factory AnalysisGetNavigationParams.fromRequest(Request request) { +- return new AnalysisGetNavigationParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- result["length"] = length; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.getNavigation", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetNavigationParams) { +- return file == other.file && +- offset == other.offset && +- length == other.length; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getNavigation result +- * +- * { +- * "files": List +- * "targets": List +- * "regions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetNavigationResult implements ResponseResult { +- List _files; +- +- List _targets; +- +- List _regions; +- +- /** +- * A list of the paths of files that are referenced by the navigation +- * targets. +- */ +- List get files => _files; +- +- /** +- * A list of the paths of files that are referenced by the navigation +- * targets. +- */ +- void set files(List value) { +- assert(value != null); +- this._files = value; +- } +- +- /** +- * A list of the navigation targets that are referenced by the navigation +- * regions. +- */ +- List get targets => _targets; +- +- /** +- * A list of the navigation targets that are referenced by the navigation +- * regions. +- */ +- void set targets(List value) { +- assert(value != null); +- this._targets = value; +- } +- +- /** +- * A list of the navigation regions within the requested region of the file. +- */ +- List get regions => _regions; +- +- /** +- * A list of the navigation regions within the requested region of the file. +- */ +- void set regions(List value) { +- assert(value != null); +- this._regions = value; +- } +- +- AnalysisGetNavigationResult(List files, +- List targets, List regions) { +- this.files = files; +- this.targets = targets; +- this.regions = regions; +- } +- +- factory AnalysisGetNavigationResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List files; +- if (json.containsKey("files")) { +- files = jsonDecoder.decodeList( +- jsonPath + ".files", json["files"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "files"); +- } +- List targets; +- if (json.containsKey("targets")) { +- targets = jsonDecoder.decodeList( +- jsonPath + ".targets", +- json["targets"], +- (String jsonPath, Object json) => +- new NavigationTarget.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "targets"); +- } +- List regions; +- if (json.containsKey("regions")) { +- regions = jsonDecoder.decodeList( +- jsonPath + ".regions", +- json["regions"], +- (String jsonPath, Object json) => +- new NavigationRegion.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "regions"); +- } +- return new AnalysisGetNavigationResult(files, targets, regions); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getNavigation result", json); +- } +- } +- +- factory AnalysisGetNavigationResult.fromResponse(Response response) { +- return new AnalysisGetNavigationResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["files"] = files; +- result["targets"] = +- targets.map((NavigationTarget value) => value.toJson()).toList(); +- result["regions"] = +- regions.map((NavigationRegion value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetNavigationResult) { +- return listEqual(files, other.files, (String a, String b) => a == b) && +- listEqual(targets, other.targets, +- (NavigationTarget a, NavigationTarget b) => a == b) && +- listEqual(regions, other.regions, +- (NavigationRegion a, NavigationRegion b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, files.hashCode); +- hash = JenkinsSmiHash.combine(hash, targets.hashCode); +- hash = JenkinsSmiHash.combine(hash, regions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getReachableSources params +- * +- * { +- * "file": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetReachableSourcesParams implements RequestParams { +- String _file; +- +- /** +- * The file for which reachable source information is being requested. +- */ +- String get file => _file; +- +- /** +- * The file for which reachable source information is being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- AnalysisGetReachableSourcesParams(String file) { +- this.file = file; +- } +- +- factory AnalysisGetReachableSourcesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- return new AnalysisGetReachableSourcesParams(file); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getReachableSources params", json); +- } +- } +- +- factory AnalysisGetReachableSourcesParams.fromRequest(Request request) { +- return new AnalysisGetReachableSourcesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.getReachableSources", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetReachableSourcesParams) { +- return file == other.file; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.getReachableSources result +- * +- * { +- * "sources": Map> +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisGetReachableSourcesResult implements ResponseResult { +- Map> _sources; +- +- /** +- * A mapping from source URIs to directly reachable source URIs. For example, +- * a file "foo.dart" that imports "bar.dart" would have the corresponding +- * mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has +- * further imports (or exports) there will be a mapping from the URI +- * "file:///bar.dart" to them. To check if a specific URI is reachable from a +- * given file, clients can check for its presence in the resulting key set. +- */ +- Map> get sources => _sources; +- +- /** +- * A mapping from source URIs to directly reachable source URIs. For example, +- * a file "foo.dart" that imports "bar.dart" would have the corresponding +- * mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has +- * further imports (or exports) there will be a mapping from the URI +- * "file:///bar.dart" to them. To check if a specific URI is reachable from a +- * given file, clients can check for its presence in the resulting key set. +- */ +- void set sources(Map> value) { +- assert(value != null); +- this._sources = value; +- } +- +- AnalysisGetReachableSourcesResult(Map> sources) { +- this.sources = sources; +- } +- +- factory AnalysisGetReachableSourcesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- Map> sources; +- if (json.containsKey("sources")) { +- sources = jsonDecoder.decodeMap(jsonPath + ".sources", json["sources"], +- valueDecoder: (String jsonPath, Object json) => jsonDecoder +- .decodeList(jsonPath, json, jsonDecoder.decodeString)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "sources"); +- } +- return new AnalysisGetReachableSourcesResult(sources); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.getReachableSources result", json); +- } +- } +- +- factory AnalysisGetReachableSourcesResult.fromResponse(Response response) { +- return new AnalysisGetReachableSourcesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["sources"] = sources; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisGetReachableSourcesResult) { +- return mapEqual( +- sources, +- other.sources, +- (List a, List b) => +- listEqual(a, b, (String a, String b) => a == b)); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, sources.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.highlights params +- * +- * { +- * "file": FilePath +- * "regions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisHighlightsParams implements HasToJson { +- String _file; +- +- List _regions; +- +- /** +- * The file containing the highlight regions. +- */ +- String get file => _file; +- +- /** +- * The file containing the highlight regions. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The highlight regions contained in the file. Each highlight region +- * represents a particular syntactic or semantic meaning associated with some +- * range. Note that the highlight regions that are returned can overlap other +- * highlight regions if there is more than one meaning associated with a +- * particular region. +- */ +- List get regions => _regions; +- +- /** +- * The highlight regions contained in the file. Each highlight region +- * represents a particular syntactic or semantic meaning associated with some +- * range. Note that the highlight regions that are returned can overlap other +- * highlight regions if there is more than one meaning associated with a +- * particular region. +- */ +- void set regions(List value) { +- assert(value != null); +- this._regions = value; +- } +- +- AnalysisHighlightsParams(String file, List regions) { +- this.file = file; +- this.regions = regions; +- } +- +- factory AnalysisHighlightsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List regions; +- if (json.containsKey("regions")) { +- regions = jsonDecoder.decodeList( +- jsonPath + ".regions", +- json["regions"], +- (String jsonPath, Object json) => +- new HighlightRegion.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "regions"); +- } +- return new AnalysisHighlightsParams(file, regions); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.highlights params", json); +- } +- } +- +- factory AnalysisHighlightsParams.fromNotification(Notification notification) { +- return new AnalysisHighlightsParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["regions"] = +- regions.map((HighlightRegion value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.highlights", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisHighlightsParams) { +- return file == other.file && +- listEqual(regions, other.regions, +- (HighlightRegion a, HighlightRegion b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, regions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.implemented params +- * +- * { +- * "file": FilePath +- * "classes": List +- * "members": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisImplementedParams implements HasToJson { +- String _file; +- +- List _classes; +- +- List _members; +- +- /** +- * The file with which the implementations are associated. +- */ +- String get file => _file; +- +- /** +- * The file with which the implementations are associated. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The classes defined in the file that are implemented or extended. +- */ +- List get classes => _classes; +- +- /** +- * The classes defined in the file that are implemented or extended. +- */ +- void set classes(List value) { +- assert(value != null); +- this._classes = value; +- } +- +- /** +- * The member defined in the file that are implemented or overridden. +- */ +- List get members => _members; +- +- /** +- * The member defined in the file that are implemented or overridden. +- */ +- void set members(List value) { +- assert(value != null); +- this._members = value; +- } +- +- AnalysisImplementedParams(String file, List classes, +- List members) { +- this.file = file; +- this.classes = classes; +- this.members = members; +- } +- +- factory AnalysisImplementedParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List classes; +- if (json.containsKey("classes")) { +- classes = jsonDecoder.decodeList( +- jsonPath + ".classes", +- json["classes"], +- (String jsonPath, Object json) => +- new ImplementedClass.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "classes"); +- } +- List members; +- if (json.containsKey("members")) { +- members = jsonDecoder.decodeList( +- jsonPath + ".members", +- json["members"], +- (String jsonPath, Object json) => +- new ImplementedMember.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "members"); +- } +- return new AnalysisImplementedParams(file, classes, members); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.implemented params", json); +- } +- } +- +- factory AnalysisImplementedParams.fromNotification( +- Notification notification) { +- return new AnalysisImplementedParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["classes"] = +- classes.map((ImplementedClass value) => value.toJson()).toList(); +- result["members"] = +- members.map((ImplementedMember value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.implemented", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisImplementedParams) { +- return file == other.file && +- listEqual(classes, other.classes, +- (ImplementedClass a, ImplementedClass b) => a == b) && +- listEqual(members, other.members, +- (ImplementedMember a, ImplementedMember b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, classes.hashCode); +- hash = JenkinsSmiHash.combine(hash, members.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.invalidate params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * "delta": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisInvalidateParams implements HasToJson { +- String _file; +- +- int _offset; +- +- int _length; +- +- int _delta; +- +- /** +- * The file whose information has been invalidated. +- */ +- String get file => _file; +- +- /** +- * The file whose information has been invalidated. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the invalidated region. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the invalidated region. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the invalidated region. +- */ +- int get length => _length; +- +- /** +- * The length of the invalidated region. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * The delta to be applied to the offsets in information that follows the +- * invalidated region in order to update it so that it doesn't need to be +- * re-requested. +- */ +- int get delta => _delta; +- +- /** +- * The delta to be applied to the offsets in information that follows the +- * invalidated region in order to update it so that it doesn't need to be +- * re-requested. +- */ +- void set delta(int value) { +- assert(value != null); +- this._delta = value; +- } +- +- AnalysisInvalidateParams(String file, int offset, int length, int delta) { +- this.file = file; +- this.offset = offset; +- this.length = length; +- this.delta = delta; +- } +- +- factory AnalysisInvalidateParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- int delta; +- if (json.containsKey("delta")) { +- delta = jsonDecoder.decodeInt(jsonPath + ".delta", json["delta"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "delta"); +- } +- return new AnalysisInvalidateParams(file, offset, length, delta); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.invalidate params", json); +- } +- } +- +- factory AnalysisInvalidateParams.fromNotification(Notification notification) { +- return new AnalysisInvalidateParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- result["length"] = length; +- result["delta"] = delta; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.invalidate", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisInvalidateParams) { +- return file == other.file && +- offset == other.offset && +- length == other.length && +- delta == other.delta; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, delta.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.navigation params +- * +- * { +- * "file": FilePath +- * "regions": List +- * "targets": List +- * "files": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisNavigationParams implements HasToJson { +- String _file; +- +- List _regions; +- +- List _targets; +- +- List _files; +- +- /** +- * The file containing the navigation regions. +- */ +- String get file => _file; +- +- /** +- * The file containing the navigation regions. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The navigation regions contained in the file. The regions are sorted by +- * their offsets. Each navigation region represents a list of targets +- * associated with some range. The lists will usually contain a single +- * target, but can contain more in the case of a part that is included in +- * multiple libraries or in Dart code that is compiled against multiple +- * versions of a package. Note that the navigation regions that are returned +- * do not overlap other navigation regions. +- */ +- List get regions => _regions; +- +- /** +- * The navigation regions contained in the file. The regions are sorted by +- * their offsets. Each navigation region represents a list of targets +- * associated with some range. The lists will usually contain a single +- * target, but can contain more in the case of a part that is included in +- * multiple libraries or in Dart code that is compiled against multiple +- * versions of a package. Note that the navigation regions that are returned +- * do not overlap other navigation regions. +- */ +- void set regions(List value) { +- assert(value != null); +- this._regions = value; +- } +- +- /** +- * The navigation targets referenced in the file. They are referenced by +- * NavigationRegions by their index in this array. +- */ +- List get targets => _targets; +- +- /** +- * The navigation targets referenced in the file. They are referenced by +- * NavigationRegions by their index in this array. +- */ +- void set targets(List value) { +- assert(value != null); +- this._targets = value; +- } +- +- /** +- * The files containing navigation targets referenced in the file. They are +- * referenced by NavigationTargets by their index in this array. +- */ +- List get files => _files; +- +- /** +- * The files containing navigation targets referenced in the file. They are +- * referenced by NavigationTargets by their index in this array. +- */ +- void set files(List value) { +- assert(value != null); +- this._files = value; +- } +- +- AnalysisNavigationParams(String file, List regions, +- List targets, List files) { +- this.file = file; +- this.regions = regions; +- this.targets = targets; +- this.files = files; +- } +- +- factory AnalysisNavigationParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List regions; +- if (json.containsKey("regions")) { +- regions = jsonDecoder.decodeList( +- jsonPath + ".regions", +- json["regions"], +- (String jsonPath, Object json) => +- new NavigationRegion.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "regions"); +- } +- List targets; +- if (json.containsKey("targets")) { +- targets = jsonDecoder.decodeList( +- jsonPath + ".targets", +- json["targets"], +- (String jsonPath, Object json) => +- new NavigationTarget.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "targets"); +- } +- List files; +- if (json.containsKey("files")) { +- files = jsonDecoder.decodeList( +- jsonPath + ".files", json["files"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "files"); +- } +- return new AnalysisNavigationParams(file, regions, targets, files); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.navigation params", json); +- } +- } +- +- factory AnalysisNavigationParams.fromNotification(Notification notification) { +- return new AnalysisNavigationParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["regions"] = +- regions.map((NavigationRegion value) => value.toJson()).toList(); +- result["targets"] = +- targets.map((NavigationTarget value) => value.toJson()).toList(); +- result["files"] = files; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.navigation", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisNavigationParams) { +- return file == other.file && +- listEqual(regions, other.regions, +- (NavigationRegion a, NavigationRegion b) => a == b) && +- listEqual(targets, other.targets, +- (NavigationTarget a, NavigationTarget b) => a == b) && +- listEqual(files, other.files, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, regions.hashCode); +- hash = JenkinsSmiHash.combine(hash, targets.hashCode); +- hash = JenkinsSmiHash.combine(hash, files.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.occurrences params +- * +- * { +- * "file": FilePath +- * "occurrences": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisOccurrencesParams implements HasToJson { +- String _file; +- +- List _occurrences; +- +- /** +- * The file in which the references occur. +- */ +- String get file => _file; +- +- /** +- * The file in which the references occur. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The occurrences of references to elements within the file. +- */ +- List get occurrences => _occurrences; +- +- /** +- * The occurrences of references to elements within the file. +- */ +- void set occurrences(List value) { +- assert(value != null); +- this._occurrences = value; +- } +- +- AnalysisOccurrencesParams(String file, List occurrences) { +- this.file = file; +- this.occurrences = occurrences; +- } +- +- factory AnalysisOccurrencesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List occurrences; +- if (json.containsKey("occurrences")) { +- occurrences = jsonDecoder.decodeList( +- jsonPath + ".occurrences", +- json["occurrences"], +- (String jsonPath, Object json) => +- new Occurrences.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "occurrences"); +- } +- return new AnalysisOccurrencesParams(file, occurrences); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.occurrences params", json); +- } +- } +- +- factory AnalysisOccurrencesParams.fromNotification( +- Notification notification) { +- return new AnalysisOccurrencesParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["occurrences"] = +- occurrences.map((Occurrences value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.occurrences", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisOccurrencesParams) { +- return file == other.file && +- listEqual(occurrences, other.occurrences, +- (Occurrences a, Occurrences b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, occurrences.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * AnalysisOptions +- * +- * { +- * "enableAsync": optional bool +- * "enableDeferredLoading": optional bool +- * "enableEnums": optional bool +- * "enableNullAwareOperators": optional bool +- * "enableSuperMixins": optional bool +- * "generateDart2jsHints": optional bool +- * "generateHints": optional bool +- * "generateLints": optional bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisOptions implements HasToJson { +- bool _enableAsync; +- +- bool _enableDeferredLoading; +- +- bool _enableEnums; +- +- bool _enableNullAwareOperators; +- +- bool _enableSuperMixins; +- +- bool _generateDart2jsHints; +- +- bool _generateHints; +- +- bool _generateLints; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed async feature. +- */ +- bool get enableAsync => _enableAsync; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed async feature. +- */ +- void set enableAsync(bool value) { +- this._enableAsync = value; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed deferred +- * loading feature. +- */ +- bool get enableDeferredLoading => _enableDeferredLoading; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed deferred +- * loading feature. +- */ +- void set enableDeferredLoading(bool value) { +- this._enableDeferredLoading = value; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed enum feature. +- */ +- bool get enableEnums => _enableEnums; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed enum feature. +- */ +- void set enableEnums(bool value) { +- this._enableEnums = value; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed "null aware +- * operators" feature. +- */ +- bool get enableNullAwareOperators => _enableNullAwareOperators; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed "null aware +- * operators" feature. +- */ +- void set enableNullAwareOperators(bool value) { +- this._enableNullAwareOperators = value; +- } +- +- /** +- * True if the client wants to enable support for the proposed "less +- * restricted mixins" proposal (DEP 34). +- */ +- bool get enableSuperMixins => _enableSuperMixins; +- +- /** +- * True if the client wants to enable support for the proposed "less +- * restricted mixins" proposal (DEP 34). +- */ +- void set enableSuperMixins(bool value) { +- this._enableSuperMixins = value; +- } +- +- /** +- * True if hints that are specific to dart2js should be generated. This +- * option is ignored if generateHints is false. +- */ +- bool get generateDart2jsHints => _generateDart2jsHints; +- +- /** +- * True if hints that are specific to dart2js should be generated. This +- * option is ignored if generateHints is false. +- */ +- void set generateDart2jsHints(bool value) { +- this._generateDart2jsHints = value; +- } +- +- /** +- * True if hints should be generated as part of generating errors and +- * warnings. +- */ +- bool get generateHints => _generateHints; +- +- /** +- * True if hints should be generated as part of generating errors and +- * warnings. +- */ +- void set generateHints(bool value) { +- this._generateHints = value; +- } +- +- /** +- * True if lints should be generated as part of generating errors and +- * warnings. +- */ +- bool get generateLints => _generateLints; +- +- /** +- * True if lints should be generated as part of generating errors and +- * warnings. +- */ +- void set generateLints(bool value) { +- this._generateLints = value; +- } +- +- AnalysisOptions( +- {bool enableAsync, +- bool enableDeferredLoading, +- bool enableEnums, +- bool enableNullAwareOperators, +- bool enableSuperMixins, +- bool generateDart2jsHints, +- bool generateHints, +- bool generateLints}) { +- this.enableAsync = enableAsync; +- this.enableDeferredLoading = enableDeferredLoading; +- this.enableEnums = enableEnums; +- this.enableNullAwareOperators = enableNullAwareOperators; +- this.enableSuperMixins = enableSuperMixins; +- this.generateDart2jsHints = generateDart2jsHints; +- this.generateHints = generateHints; +- this.generateLints = generateLints; +- } +- +- factory AnalysisOptions.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool enableAsync; +- if (json.containsKey("enableAsync")) { +- enableAsync = jsonDecoder.decodeBool( +- jsonPath + ".enableAsync", json["enableAsync"]); +- } +- bool enableDeferredLoading; +- if (json.containsKey("enableDeferredLoading")) { +- enableDeferredLoading = jsonDecoder.decodeBool( +- jsonPath + ".enableDeferredLoading", json["enableDeferredLoading"]); +- } +- bool enableEnums; +- if (json.containsKey("enableEnums")) { +- enableEnums = jsonDecoder.decodeBool( +- jsonPath + ".enableEnums", json["enableEnums"]); +- } +- bool enableNullAwareOperators; +- if (json.containsKey("enableNullAwareOperators")) { +- enableNullAwareOperators = jsonDecoder.decodeBool( +- jsonPath + ".enableNullAwareOperators", +- json["enableNullAwareOperators"]); +- } +- bool enableSuperMixins; +- if (json.containsKey("enableSuperMixins")) { +- enableSuperMixins = jsonDecoder.decodeBool( +- jsonPath + ".enableSuperMixins", json["enableSuperMixins"]); +- } +- bool generateDart2jsHints; +- if (json.containsKey("generateDart2jsHints")) { +- generateDart2jsHints = jsonDecoder.decodeBool( +- jsonPath + ".generateDart2jsHints", json["generateDart2jsHints"]); +- } +- bool generateHints; +- if (json.containsKey("generateHints")) { +- generateHints = jsonDecoder.decodeBool( +- jsonPath + ".generateHints", json["generateHints"]); +- } +- bool generateLints; +- if (json.containsKey("generateLints")) { +- generateLints = jsonDecoder.decodeBool( +- jsonPath + ".generateLints", json["generateLints"]); +- } +- return new AnalysisOptions( +- enableAsync: enableAsync, +- enableDeferredLoading: enableDeferredLoading, +- enableEnums: enableEnums, +- enableNullAwareOperators: enableNullAwareOperators, +- enableSuperMixins: enableSuperMixins, +- generateDart2jsHints: generateDart2jsHints, +- generateHints: generateHints, +- generateLints: generateLints); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "AnalysisOptions", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (enableAsync != null) { +- result["enableAsync"] = enableAsync; +- } +- if (enableDeferredLoading != null) { +- result["enableDeferredLoading"] = enableDeferredLoading; +- } +- if (enableEnums != null) { +- result["enableEnums"] = enableEnums; +- } +- if (enableNullAwareOperators != null) { +- result["enableNullAwareOperators"] = enableNullAwareOperators; +- } +- if (enableSuperMixins != null) { +- result["enableSuperMixins"] = enableSuperMixins; +- } +- if (generateDart2jsHints != null) { +- result["generateDart2jsHints"] = generateDart2jsHints; +- } +- if (generateHints != null) { +- result["generateHints"] = generateHints; +- } +- if (generateLints != null) { +- result["generateLints"] = generateLints; +- } +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisOptions) { +- return enableAsync == other.enableAsync && +- enableDeferredLoading == other.enableDeferredLoading && +- enableEnums == other.enableEnums && +- enableNullAwareOperators == other.enableNullAwareOperators && +- enableSuperMixins == other.enableSuperMixins && +- generateDart2jsHints == other.generateDart2jsHints && +- generateHints == other.generateHints && +- generateLints == other.generateLints; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, enableAsync.hashCode); +- hash = JenkinsSmiHash.combine(hash, enableDeferredLoading.hashCode); +- hash = JenkinsSmiHash.combine(hash, enableEnums.hashCode); +- hash = JenkinsSmiHash.combine(hash, enableNullAwareOperators.hashCode); +- hash = JenkinsSmiHash.combine(hash, enableSuperMixins.hashCode); +- hash = JenkinsSmiHash.combine(hash, generateDart2jsHints.hashCode); +- hash = JenkinsSmiHash.combine(hash, generateHints.hashCode); +- hash = JenkinsSmiHash.combine(hash, generateLints.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.outline params +- * +- * { +- * "file": FilePath +- * "kind": FileKind +- * "libraryName": optional String +- * "outline": Outline +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisOutlineParams implements HasToJson { +- String _file; +- +- FileKind _kind; +- +- String _libraryName; +- +- Outline _outline; +- +- /** +- * The file with which the outline is associated. +- */ +- String get file => _file; +- +- /** +- * The file with which the outline is associated. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The kind of the file. +- */ +- FileKind get kind => _kind; +- +- /** +- * The kind of the file. +- */ +- void set kind(FileKind value) { +- assert(value != null); +- this._kind = value; +- } +- +- /** +- * The name of the library defined by the file using a "library" directive, +- * or referenced by a "part of" directive. If both "library" and "part of" +- * directives are present, then the "library" directive takes precedence. +- * This field will be omitted if the file has neither "library" nor "part of" +- * directives. +- */ +- String get libraryName => _libraryName; +- +- /** +- * The name of the library defined by the file using a "library" directive, +- * or referenced by a "part of" directive. If both "library" and "part of" +- * directives are present, then the "library" directive takes precedence. +- * This field will be omitted if the file has neither "library" nor "part of" +- * directives. +- */ +- void set libraryName(String value) { +- this._libraryName = value; +- } +- +- /** +- * The outline associated with the file. +- */ +- Outline get outline => _outline; +- +- /** +- * The outline associated with the file. +- */ +- void set outline(Outline value) { +- assert(value != null); +- this._outline = value; +- } +- +- AnalysisOutlineParams(String file, FileKind kind, Outline outline, +- {String libraryName}) { +- this.file = file; +- this.kind = kind; +- this.libraryName = libraryName; +- this.outline = outline; +- } +- +- factory AnalysisOutlineParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- FileKind kind; +- if (json.containsKey("kind")) { +- kind = new FileKind.fromJson( +- jsonDecoder, jsonPath + ".kind", json["kind"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "kind"); +- } +- String libraryName; +- if (json.containsKey("libraryName")) { +- libraryName = jsonDecoder.decodeString( +- jsonPath + ".libraryName", json["libraryName"]); +- } +- Outline outline; +- if (json.containsKey("outline")) { +- outline = new Outline.fromJson( +- jsonDecoder, jsonPath + ".outline", json["outline"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "outline"); +- } +- return new AnalysisOutlineParams(file, kind, outline, +- libraryName: libraryName); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.outline params", json); +- } +- } +- +- factory AnalysisOutlineParams.fromNotification(Notification notification) { +- return new AnalysisOutlineParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["kind"] = kind.toJson(); +- if (libraryName != null) { +- result["libraryName"] = libraryName; +- } +- result["outline"] = outline.toJson(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.outline", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisOutlineParams) { +- return file == other.file && +- kind == other.kind && +- libraryName == other.libraryName && +- outline == other.outline; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, kind.hashCode); +- hash = JenkinsSmiHash.combine(hash, libraryName.hashCode); +- hash = JenkinsSmiHash.combine(hash, outline.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.overrides params +- * +- * { +- * "file": FilePath +- * "overrides": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisOverridesParams implements HasToJson { +- String _file; +- +- List _overrides; +- +- /** +- * The file with which the overrides are associated. +- */ +- String get file => _file; +- +- /** +- * The file with which the overrides are associated. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The overrides associated with the file. +- */ +- List get overrides => _overrides; +- +- /** +- * The overrides associated with the file. +- */ +- void set overrides(List value) { +- assert(value != null); +- this._overrides = value; +- } +- +- AnalysisOverridesParams(String file, List overrides) { +- this.file = file; +- this.overrides = overrides; +- } +- +- factory AnalysisOverridesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List overrides; +- if (json.containsKey("overrides")) { +- overrides = jsonDecoder.decodeList( +- jsonPath + ".overrides", +- json["overrides"], +- (String jsonPath, Object json) => +- new Override.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "overrides"); +- } +- return new AnalysisOverridesParams(file, overrides); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.overrides params", json); +- } +- } +- +- factory AnalysisOverridesParams.fromNotification(Notification notification) { +- return new AnalysisOverridesParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["overrides"] = +- overrides.map((Override value) => value.toJson()).toList(); +- return result; +- } +- +- Notification toNotification() { +- return new Notification("analysis.overrides", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisOverridesParams) { +- return file == other.file && +- listEqual( +- overrides, other.overrides, (Override a, Override b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, overrides.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.reanalyze params +- * +- * { +- * "roots": optional List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisReanalyzeParams implements RequestParams { +- List _roots; +- +- /** +- * A list of the analysis roots that are to be re-analyzed. +- */ +- List get roots => _roots; +- +- /** +- * A list of the analysis roots that are to be re-analyzed. +- */ +- void set roots(List value) { +- this._roots = value; +- } +- +- AnalysisReanalyzeParams({List roots}) { +- this.roots = roots; +- } +- +- factory AnalysisReanalyzeParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List roots; +- if (json.containsKey("roots")) { +- roots = jsonDecoder.decodeList( +- jsonPath + ".roots", json["roots"], jsonDecoder.decodeString); +- } +- return new AnalysisReanalyzeParams(roots: roots); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analysis.reanalyze params", json); +- } +- } +- +- factory AnalysisReanalyzeParams.fromRequest(Request request) { +- return new AnalysisReanalyzeParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (roots != null) { +- result["roots"] = roots; +- } +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.reanalyze", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisReanalyzeParams) { +- return listEqual(roots, other.roots, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, roots.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.reanalyze result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisReanalyzeResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisReanalyzeResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 846803925; +- } +-} +- +-/** +- * AnalysisService +- * +- * enum { +- * CLOSING_LABELS +- * FOLDING +- * HIGHLIGHTS +- * IMPLEMENTED +- * INVALIDATE +- * NAVIGATION +- * OCCURRENCES +- * OUTLINE +- * OVERRIDES +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisService implements Enum { +- static const AnalysisService CLOSING_LABELS = +- const AnalysisService._("CLOSING_LABELS"); +- +- static const AnalysisService FOLDING = const AnalysisService._("FOLDING"); +- +- static const AnalysisService HIGHLIGHTS = +- const AnalysisService._("HIGHLIGHTS"); +- +- static const AnalysisService IMPLEMENTED = +- const AnalysisService._("IMPLEMENTED"); +- +- /** +- * This service is not currently implemented and will become a +- * GeneralAnalysisService in a future release. +- */ +- static const AnalysisService INVALIDATE = +- const AnalysisService._("INVALIDATE"); +- +- static const AnalysisService NAVIGATION = +- const AnalysisService._("NAVIGATION"); +- +- static const AnalysisService OCCURRENCES = +- const AnalysisService._("OCCURRENCES"); +- +- static const AnalysisService OUTLINE = const AnalysisService._("OUTLINE"); +- +- static const AnalysisService OVERRIDES = const AnalysisService._("OVERRIDES"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [ +- CLOSING_LABELS, +- FOLDING, +- HIGHLIGHTS, +- IMPLEMENTED, +- INVALIDATE, +- NAVIGATION, +- OCCURRENCES, +- OUTLINE, +- OVERRIDES +- ]; +- +- @override +- final String name; +- +- const AnalysisService._(this.name); +- +- factory AnalysisService(String name) { +- switch (name) { +- case "CLOSING_LABELS": +- return CLOSING_LABELS; +- case "FOLDING": +- return FOLDING; +- case "HIGHLIGHTS": +- return HIGHLIGHTS; +- case "IMPLEMENTED": +- return IMPLEMENTED; +- case "INVALIDATE": +- return INVALIDATE; +- case "NAVIGATION": +- return NAVIGATION; +- case "OCCURRENCES": +- return OCCURRENCES; +- case "OUTLINE": +- return OUTLINE; +- case "OVERRIDES": +- return OVERRIDES; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory AnalysisService.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new AnalysisService(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "AnalysisService", json); +- } +- +- @override +- String toString() => "AnalysisService.$name"; +- +- String toJson() => name; +-} +- +-/** +- * analysis.setAnalysisRoots params +- * +- * { +- * "included": List +- * "excluded": List +- * "packageRoots": optional Map +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetAnalysisRootsParams implements RequestParams { +- List _included; +- +- List _excluded; +- +- Map _packageRoots; +- +- /** +- * A list of the files and directories that should be analyzed. +- */ +- List get included => _included; +- +- /** +- * A list of the files and directories that should be analyzed. +- */ +- void set included(List value) { +- assert(value != null); +- this._included = value; +- } +- +- /** +- * A list of the files and directories within the included directories that +- * should not be analyzed. +- */ +- List get excluded => _excluded; +- +- /** +- * A list of the files and directories within the included directories that +- * should not be analyzed. +- */ +- void set excluded(List value) { +- assert(value != null); +- this._excluded = value; +- } +- +- /** +- * A mapping from source directories to package roots that should override +- * the normal package: URI resolution mechanism. +- * +- * If a package root is a directory, then the analyzer will behave as though +- * the associated source directory in the map contains a special pubspec.yaml +- * file which resolves any package: URI to the corresponding path within that +- * package root directory. The effect is the same as specifying the package +- * root directory as a "--package_root" parameter to the Dart VM when +- * executing any Dart file inside the source directory. +- * +- * If a package root is a file, then the analyzer will behave as though that +- * file is a ".packages" file in the source directory. The effect is the same +- * as specifying the file as a "--packages" parameter to the Dart VM when +- * executing any Dart file inside the source directory. +- * +- * Files in any directories that are not overridden by this mapping have +- * their package: URI's resolved using the normal pubspec.yaml mechanism. If +- * this field is absent, or the empty map is specified, that indicates that +- * the normal pubspec.yaml mechanism should always be used. +- */ +- Map get packageRoots => _packageRoots; +- +- /** +- * A mapping from source directories to package roots that should override +- * the normal package: URI resolution mechanism. +- * +- * If a package root is a directory, then the analyzer will behave as though +- * the associated source directory in the map contains a special pubspec.yaml +- * file which resolves any package: URI to the corresponding path within that +- * package root directory. The effect is the same as specifying the package +- * root directory as a "--package_root" parameter to the Dart VM when +- * executing any Dart file inside the source directory. +- * +- * If a package root is a file, then the analyzer will behave as though that +- * file is a ".packages" file in the source directory. The effect is the same +- * as specifying the file as a "--packages" parameter to the Dart VM when +- * executing any Dart file inside the source directory. +- * +- * Files in any directories that are not overridden by this mapping have +- * their package: URI's resolved using the normal pubspec.yaml mechanism. If +- * this field is absent, or the empty map is specified, that indicates that +- * the normal pubspec.yaml mechanism should always be used. +- */ +- void set packageRoots(Map value) { +- this._packageRoots = value; +- } +- +- AnalysisSetAnalysisRootsParams(List included, List excluded, +- {Map packageRoots}) { +- this.included = included; +- this.excluded = excluded; +- this.packageRoots = packageRoots; +- } +- +- factory AnalysisSetAnalysisRootsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List included; +- if (json.containsKey("included")) { +- included = jsonDecoder.decodeList( +- jsonPath + ".included", json["included"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "included"); +- } +- List excluded; +- if (json.containsKey("excluded")) { +- excluded = jsonDecoder.decodeList( +- jsonPath + ".excluded", json["excluded"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "excluded"); +- } +- Map packageRoots; +- if (json.containsKey("packageRoots")) { +- packageRoots = jsonDecoder.decodeMap( +- jsonPath + ".packageRoots", json["packageRoots"], +- valueDecoder: jsonDecoder.decodeString); +- } +- return new AnalysisSetAnalysisRootsParams(included, excluded, +- packageRoots: packageRoots); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.setAnalysisRoots params", json); +- } +- } +- +- factory AnalysisSetAnalysisRootsParams.fromRequest(Request request) { +- return new AnalysisSetAnalysisRootsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["included"] = included; +- result["excluded"] = excluded; +- if (packageRoots != null) { +- result["packageRoots"] = packageRoots; +- } +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.setAnalysisRoots", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetAnalysisRootsParams) { +- return listEqual( +- included, other.included, (String a, String b) => a == b) && +- listEqual(excluded, other.excluded, (String a, String b) => a == b) && +- mapEqual( +- packageRoots, other.packageRoots, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, included.hashCode); +- hash = JenkinsSmiHash.combine(hash, excluded.hashCode); +- hash = JenkinsSmiHash.combine(hash, packageRoots.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.setAnalysisRoots result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetAnalysisRootsResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetAnalysisRootsResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 866004753; +- } +-} +- +-/** +- * analysis.setGeneralSubscriptions params +- * +- * { +- * "subscriptions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetGeneralSubscriptionsParams implements RequestParams { +- List _subscriptions; +- +- /** +- * A list of the services being subscribed to. +- */ +- List get subscriptions => _subscriptions; +- +- /** +- * A list of the services being subscribed to. +- */ +- void set subscriptions(List value) { +- assert(value != null); +- this._subscriptions = value; +- } +- +- AnalysisSetGeneralSubscriptionsParams( +- List subscriptions) { +- this.subscriptions = subscriptions; +- } +- +- factory AnalysisSetGeneralSubscriptionsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List subscriptions; +- if (json.containsKey("subscriptions")) { +- subscriptions = jsonDecoder.decodeList( +- jsonPath + ".subscriptions", +- json["subscriptions"], +- (String jsonPath, Object json) => +- new GeneralAnalysisService.fromJson( +- jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "subscriptions"); +- } +- return new AnalysisSetGeneralSubscriptionsParams(subscriptions); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.setGeneralSubscriptions params", json); +- } +- } +- +- factory AnalysisSetGeneralSubscriptionsParams.fromRequest(Request request) { +- return new AnalysisSetGeneralSubscriptionsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["subscriptions"] = subscriptions +- .map((GeneralAnalysisService value) => value.toJson()) +- .toList(); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.setGeneralSubscriptions", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetGeneralSubscriptionsParams) { +- return listEqual(subscriptions, other.subscriptions, +- (GeneralAnalysisService a, GeneralAnalysisService b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.setGeneralSubscriptions result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetGeneralSubscriptionsResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetGeneralSubscriptionsResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 386759562; +- } +-} +- +-/** +- * analysis.setPriorityFiles params +- * +- * { +- * "files": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetPriorityFilesParams implements RequestParams { +- List _files; +- +- /** +- * The files that are to be a priority for analysis. +- */ +- List get files => _files; +- +- /** +- * The files that are to be a priority for analysis. +- */ +- void set files(List value) { +- assert(value != null); +- this._files = value; +- } +- +- AnalysisSetPriorityFilesParams(List files) { +- this.files = files; +- } +- +- factory AnalysisSetPriorityFilesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List files; +- if (json.containsKey("files")) { +- files = jsonDecoder.decodeList( +- jsonPath + ".files", json["files"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "files"); +- } +- return new AnalysisSetPriorityFilesParams(files); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.setPriorityFiles params", json); +- } +- } +- +- factory AnalysisSetPriorityFilesParams.fromRequest(Request request) { +- return new AnalysisSetPriorityFilesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["files"] = files; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.setPriorityFiles", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetPriorityFilesParams) { +- return listEqual(files, other.files, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, files.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.setPriorityFiles result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetPriorityFilesResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetPriorityFilesResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 330050055; +- } +-} +- +-/** +- * analysis.setSubscriptions params +- * +- * { +- * "subscriptions": Map> +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetSubscriptionsParams implements RequestParams { +- Map> _subscriptions; +- +- /** +- * A table mapping services to a list of the files being subscribed to the +- * service. +- */ +- Map> get subscriptions => _subscriptions; +- +- /** +- * A table mapping services to a list of the files being subscribed to the +- * service. +- */ +- void set subscriptions(Map> value) { +- assert(value != null); +- this._subscriptions = value; +- } +- +- AnalysisSetSubscriptionsParams( +- Map> subscriptions) { +- this.subscriptions = subscriptions; +- } +- +- factory AnalysisSetSubscriptionsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- Map> subscriptions; +- if (json.containsKey("subscriptions")) { +- subscriptions = jsonDecoder.decodeMap( +- jsonPath + ".subscriptions", json["subscriptions"], +- keyDecoder: (String jsonPath, Object json) => +- new AnalysisService.fromJson(jsonDecoder, jsonPath, json), +- valueDecoder: (String jsonPath, Object json) => jsonDecoder +- .decodeList(jsonPath, json, jsonDecoder.decodeString)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "subscriptions"); +- } +- return new AnalysisSetSubscriptionsParams(subscriptions); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.setSubscriptions params", json); +- } +- } +- +- factory AnalysisSetSubscriptionsParams.fromRequest(Request request) { +- return new AnalysisSetSubscriptionsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["subscriptions"] = mapMap(subscriptions, +- keyCallback: (AnalysisService value) => value.toJson()); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.setSubscriptions", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetSubscriptionsParams) { +- return mapEqual( +- subscriptions, +- other.subscriptions, +- (List a, List b) => +- listEqual(a, b, (String a, String b) => a == b)); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.setSubscriptions result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisSetSubscriptionsResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisSetSubscriptionsResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 218088493; +- } +-} +- +-/** +- * AnalysisStatus +- * +- * { +- * "isAnalyzing": bool +- * "analysisTarget": optional String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisStatus implements HasToJson { +- bool _isAnalyzing; +- +- String _analysisTarget; +- +- /** +- * True if analysis is currently being performed. +- */ +- bool get isAnalyzing => _isAnalyzing; +- +- /** +- * True if analysis is currently being performed. +- */ +- void set isAnalyzing(bool value) { +- assert(value != null); +- this._isAnalyzing = value; +- } +- +- /** +- * The name of the current target of analysis. This field is omitted if +- * analyzing is false. +- */ +- String get analysisTarget => _analysisTarget; +- +- /** +- * The name of the current target of analysis. This field is omitted if +- * analyzing is false. +- */ +- void set analysisTarget(String value) { +- this._analysisTarget = value; +- } +- +- AnalysisStatus(bool isAnalyzing, {String analysisTarget}) { +- this.isAnalyzing = isAnalyzing; +- this.analysisTarget = analysisTarget; +- } +- +- factory AnalysisStatus.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool isAnalyzing; +- if (json.containsKey("isAnalyzing")) { +- isAnalyzing = jsonDecoder.decodeBool( +- jsonPath + ".isAnalyzing", json["isAnalyzing"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isAnalyzing"); +- } +- String analysisTarget; +- if (json.containsKey("analysisTarget")) { +- analysisTarget = jsonDecoder.decodeString( +- jsonPath + ".analysisTarget", json["analysisTarget"]); +- } +- return new AnalysisStatus(isAnalyzing, analysisTarget: analysisTarget); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "AnalysisStatus", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["isAnalyzing"] = isAnalyzing; +- if (analysisTarget != null) { +- result["analysisTarget"] = analysisTarget; +- } +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisStatus) { +- return isAnalyzing == other.isAnalyzing && +- analysisTarget == other.analysisTarget; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, isAnalyzing.hashCode); +- hash = JenkinsSmiHash.combine(hash, analysisTarget.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.updateContent params +- * +- * { +- * "files": Map +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisUpdateContentParams implements RequestParams { +- Map _files; +- +- /** +- * A table mapping the files whose content has changed to a description of +- * the content change. +- */ +- Map get files => _files; +- +- /** +- * A table mapping the files whose content has changed to a description of +- * the content change. +- */ +- void set files(Map value) { +- assert(value != null); +- this._files = value; +- } +- +- AnalysisUpdateContentParams(Map files) { +- this.files = files; +- } +- +- factory AnalysisUpdateContentParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- Map files; +- if (json.containsKey("files")) { +- files = jsonDecoder.decodeMap(jsonPath + ".files", json["files"], +- valueDecoder: (String jsonPath, Object json) => +- jsonDecoder.decodeUnion(jsonPath, json, "type", { +- "add": (String jsonPath, Object json) => +- new AddContentOverlay.fromJson( +- jsonDecoder, jsonPath, json), +- "change": (String jsonPath, Object json) => +- new ChangeContentOverlay.fromJson( +- jsonDecoder, jsonPath, json), +- "remove": (String jsonPath, Object json) => +- new RemoveContentOverlay.fromJson( +- jsonDecoder, jsonPath, json) +- })); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "files"); +- } +- return new AnalysisUpdateContentParams(files); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.updateContent params", json); +- } +- } +- +- factory AnalysisUpdateContentParams.fromRequest(Request request) { +- return new AnalysisUpdateContentParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["files"] = +- mapMap(files, valueCallback: (dynamic value) => value.toJson()); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.updateContent", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisUpdateContentParams) { +- return mapEqual(files, other.files, (dynamic a, dynamic b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, files.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.updateContent result +- * +- * { +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisUpdateContentResult implements ResponseResult { +- AnalysisUpdateContentResult(); +- +- factory AnalysisUpdateContentResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- return new AnalysisUpdateContentResult(); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.updateContent result", json); +- } +- } +- +- factory AnalysisUpdateContentResult.fromResponse(Response response) { +- return new AnalysisUpdateContentResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisUpdateContentResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.updateOptions params +- * +- * { +- * "options": AnalysisOptions +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisUpdateOptionsParams implements RequestParams { +- AnalysisOptions _options; +- +- /** +- * The options that are to be used to control analysis. +- */ +- AnalysisOptions get options => _options; +- +- /** +- * The options that are to be used to control analysis. +- */ +- void set options(AnalysisOptions value) { +- assert(value != null); +- this._options = value; +- } +- +- AnalysisUpdateOptionsParams(AnalysisOptions options) { +- this.options = options; +- } +- +- factory AnalysisUpdateOptionsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- AnalysisOptions options; +- if (json.containsKey("options")) { +- options = new AnalysisOptions.fromJson( +- jsonDecoder, jsonPath + ".options", json["options"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "options"); +- } +- return new AnalysisUpdateOptionsParams(options); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "analysis.updateOptions params", json); +- } +- } +- +- factory AnalysisUpdateOptionsParams.fromRequest(Request request) { +- return new AnalysisUpdateOptionsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["options"] = options.toJson(); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analysis.updateOptions", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalysisUpdateOptionsParams) { +- return options == other.options; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, options.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analysis.updateOptions result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalysisUpdateOptionsResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalysisUpdateOptionsResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 179689467; +- } +-} +- +-/** +- * analytics.enable params +- * +- * { +- * "value": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsEnableParams implements RequestParams { +- bool _value; +- +- /** +- * Enable or disable analytics. +- */ +- bool get value => _value; +- +- /** +- * Enable or disable analytics. +- */ +- void set value(bool value) { +- assert(value != null); +- this._value = value; +- } +- +- AnalyticsEnableParams(bool value) { +- this.value = value; +- } +- +- factory AnalyticsEnableParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool value; +- if (json.containsKey("value")) { +- value = jsonDecoder.decodeBool(jsonPath + ".value", json["value"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "value"); +- } +- return new AnalyticsEnableParams(value); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analytics.enable params", json); +- } +- } +- +- factory AnalyticsEnableParams.fromRequest(Request request) { +- return new AnalyticsEnableParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["value"] = value; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analytics.enable", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsEnableParams) { +- return value == other.value; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, value.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analytics.enable result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsEnableResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsEnableResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 237990792; +- } +-} +- +-/** +- * analytics.isEnabled params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsIsEnabledParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analytics.isEnabled", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsIsEnabledParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 57215544; +- } +-} +- +-/** +- * analytics.isEnabled result +- * +- * { +- * "enabled": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsIsEnabledResult implements ResponseResult { +- bool _enabled; +- +- /** +- * Whether sending analytics is enabled or not. +- */ +- bool get enabled => _enabled; +- +- /** +- * Whether sending analytics is enabled or not. +- */ +- void set enabled(bool value) { +- assert(value != null); +- this._enabled = value; +- } +- +- AnalyticsIsEnabledResult(bool enabled) { +- this.enabled = enabled; +- } +- +- factory AnalyticsIsEnabledResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool enabled; +- if (json.containsKey("enabled")) { +- enabled = +- jsonDecoder.decodeBool(jsonPath + ".enabled", json["enabled"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "enabled"); +- } +- return new AnalyticsIsEnabledResult(enabled); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analytics.isEnabled result", json); +- } +- } +- +- factory AnalyticsIsEnabledResult.fromResponse(Response response) { +- return new AnalyticsIsEnabledResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["enabled"] = enabled; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsIsEnabledResult) { +- return enabled == other.enabled; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, enabled.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analytics.sendEvent params +- * +- * { +- * "action": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsSendEventParams implements RequestParams { +- String _action; +- +- /** +- * The value used to indicate which action was performed. +- */ +- String get action => _action; +- +- /** +- * The value used to indicate which action was performed. +- */ +- void set action(String value) { +- assert(value != null); +- this._action = value; +- } +- +- AnalyticsSendEventParams(String action) { +- this.action = action; +- } +- +- factory AnalyticsSendEventParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String action; +- if (json.containsKey("action")) { +- action = jsonDecoder.decodeString(jsonPath + ".action", json["action"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "action"); +- } +- return new AnalyticsSendEventParams(action); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analytics.sendEvent params", json); +- } +- } +- +- factory AnalyticsSendEventParams.fromRequest(Request request) { +- return new AnalyticsSendEventParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["action"] = action; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analytics.sendEvent", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsSendEventParams) { +- return action == other.action; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, action.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analytics.sendEvent result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsSendEventResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsSendEventResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 227063188; +- } +-} +- +-/** +- * analytics.sendTiming params +- * +- * { +- * "event": String +- * "millis": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsSendTimingParams implements RequestParams { +- String _event; +- +- int _millis; +- +- /** +- * The name of the event. +- */ +- String get event => _event; +- +- /** +- * The name of the event. +- */ +- void set event(String value) { +- assert(value != null); +- this._event = value; +- } +- +- /** +- * The duration of the event in milliseconds. +- */ +- int get millis => _millis; +- +- /** +- * The duration of the event in milliseconds. +- */ +- void set millis(int value) { +- assert(value != null); +- this._millis = value; +- } +- +- AnalyticsSendTimingParams(String event, int millis) { +- this.event = event; +- this.millis = millis; +- } +- +- factory AnalyticsSendTimingParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String event; +- if (json.containsKey("event")) { +- event = jsonDecoder.decodeString(jsonPath + ".event", json["event"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "event"); +- } +- int millis; +- if (json.containsKey("millis")) { +- millis = jsonDecoder.decodeInt(jsonPath + ".millis", json["millis"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "millis"); +- } +- return new AnalyticsSendTimingParams(event, millis); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "analytics.sendTiming params", json); +- } +- } +- +- factory AnalyticsSendTimingParams.fromRequest(Request request) { +- return new AnalyticsSendTimingParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["event"] = event; +- result["millis"] = millis; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "analytics.sendTiming", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsSendTimingParams) { +- return event == other.event && millis == other.millis; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, event.hashCode); +- hash = JenkinsSmiHash.combine(hash, millis.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * analytics.sendTiming result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class AnalyticsSendTimingResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is AnalyticsSendTimingResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 875010924; +- } +-} +- +-/** +- * ClosingLabel +- * +- * { +- * "offset": int +- * "length": int +- * "label": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ClosingLabel implements HasToJson { +- int _offset; +- +- int _length; +- +- String _label; +- +- /** +- * The offset of the construct being labelled. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the construct being labelled. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the whole construct to be labelled. +- */ +- int get length => _length; +- +- /** +- * The length of the whole construct to be labelled. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * The label associated with this range that should be displayed to the user. +- */ +- String get label => _label; +- +- /** +- * The label associated with this range that should be displayed to the user. +- */ +- void set label(String value) { +- assert(value != null); +- this._label = value; +- } +- +- ClosingLabel(int offset, int length, String label) { +- this.offset = offset; +- this.length = length; +- this.label = label; +- } +- +- factory ClosingLabel.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- String label; +- if (json.containsKey("label")) { +- label = jsonDecoder.decodeString(jsonPath + ".label", json["label"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "label"); +- } +- return new ClosingLabel(offset, length, label); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "ClosingLabel", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- result["label"] = label; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ClosingLabel) { +- return offset == other.offset && +- length == other.length && +- label == other.label; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, label.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * completion.getSuggestions params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class CompletionGetSuggestionsParams implements RequestParams { +- String _file; +- +- int _offset; +- +- /** +- * The file containing the point at which suggestions are to be made. +- */ +- String get file => _file; +- +- /** +- * The file containing the point at which suggestions are to be made. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset within the file at which suggestions are to be made. +- */ +- int get offset => _offset; +- +- /** +- * The offset within the file at which suggestions are to be made. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- CompletionGetSuggestionsParams(String file, int offset) { +- this.file = file; +- this.offset = offset; +- } +- +- factory CompletionGetSuggestionsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- return new CompletionGetSuggestionsParams(file, offset); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "completion.getSuggestions params", json); +- } +- } +- +- factory CompletionGetSuggestionsParams.fromRequest(Request request) { +- return new CompletionGetSuggestionsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "completion.getSuggestions", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is CompletionGetSuggestionsParams) { +- return file == other.file && offset == other.offset; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * completion.getSuggestions result +- * +- * { +- * "id": CompletionId +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class CompletionGetSuggestionsResult implements ResponseResult { +- String _id; +- +- /** +- * The identifier used to associate results with this completion request. +- */ +- String get id => _id; +- +- /** +- * The identifier used to associate results with this completion request. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- CompletionGetSuggestionsResult(String id) { +- this.id = id; +- } +- +- factory CompletionGetSuggestionsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- return new CompletionGetSuggestionsResult(id); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "completion.getSuggestions result", json); +- } +- } +- +- factory CompletionGetSuggestionsResult.fromResponse(Response response) { +- return new CompletionGetSuggestionsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is CompletionGetSuggestionsResult) { +- return id == other.id; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * completion.results params +- * +- * { +- * "id": CompletionId +- * "replacementOffset": int +- * "replacementLength": int +- * "results": List +- * "isLast": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class CompletionResultsParams implements HasToJson { +- String _id; +- +- int _replacementOffset; +- +- int _replacementLength; +- +- List _results; +- +- bool _isLast; +- +- /** +- * The id associated with the completion. +- */ +- String get id => _id; +- +- /** +- * The id associated with the completion. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- /** +- * The offset of the start of the text to be replaced. This will be different +- * than the offset used to request the completion suggestions if there was a +- * portion of an identifier before the original offset. In particular, the +- * replacementOffset will be the offset of the beginning of said identifier. +- */ +- int get replacementOffset => _replacementOffset; +- +- /** +- * The offset of the start of the text to be replaced. This will be different +- * than the offset used to request the completion suggestions if there was a +- * portion of an identifier before the original offset. In particular, the +- * replacementOffset will be the offset of the beginning of said identifier. +- */ +- void set replacementOffset(int value) { +- assert(value != null); +- this._replacementOffset = value; +- } +- +- /** +- * The length of the text to be replaced if the remainder of the identifier +- * containing the cursor is to be replaced when the suggestion is applied +- * (that is, the number of characters in the existing identifier). +- */ +- int get replacementLength => _replacementLength; +- +- /** +- * The length of the text to be replaced if the remainder of the identifier +- * containing the cursor is to be replaced when the suggestion is applied +- * (that is, the number of characters in the existing identifier). +- */ +- void set replacementLength(int value) { +- assert(value != null); +- this._replacementLength = value; +- } +- +- /** +- * The completion suggestions being reported. The notification contains all +- * possible completions at the requested cursor position, even those that do +- * not match the characters the user has already typed. This allows the +- * client to respond to further keystrokes from the user without having to +- * make additional requests. +- */ +- List get results => _results; +- +- /** +- * The completion suggestions being reported. The notification contains all +- * possible completions at the requested cursor position, even those that do +- * not match the characters the user has already typed. This allows the +- * client to respond to further keystrokes from the user without having to +- * make additional requests. +- */ +- void set results(List value) { +- assert(value != null); +- this._results = value; +- } +- +- /** +- * True if this is that last set of results that will be returned for the +- * indicated completion. +- */ +- bool get isLast => _isLast; +- +- /** +- * True if this is that last set of results that will be returned for the +- * indicated completion. +- */ +- void set isLast(bool value) { +- assert(value != null); +- this._isLast = value; +- } +- +- CompletionResultsParams(String id, int replacementOffset, +- int replacementLength, List results, bool isLast) { +- this.id = id; +- this.replacementOffset = replacementOffset; +- this.replacementLength = replacementLength; +- this.results = results; +- this.isLast = isLast; +- } +- +- factory CompletionResultsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- int replacementOffset; +- if (json.containsKey("replacementOffset")) { +- replacementOffset = jsonDecoder.decodeInt( +- jsonPath + ".replacementOffset", json["replacementOffset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "replacementOffset"); +- } +- int replacementLength; +- if (json.containsKey("replacementLength")) { +- replacementLength = jsonDecoder.decodeInt( +- jsonPath + ".replacementLength", json["replacementLength"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "replacementLength"); +- } +- List results; +- if (json.containsKey("results")) { +- results = jsonDecoder.decodeList( +- jsonPath + ".results", +- json["results"], +- (String jsonPath, Object json) => +- new CompletionSuggestion.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "results"); +- } +- bool isLast; +- if (json.containsKey("isLast")) { +- isLast = jsonDecoder.decodeBool(jsonPath + ".isLast", json["isLast"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isLast"); +- } +- return new CompletionResultsParams( +- id, replacementOffset, replacementLength, results, isLast); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "completion.results params", json); +- } +- } +- +- factory CompletionResultsParams.fromNotification(Notification notification) { +- return new CompletionResultsParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- result["replacementOffset"] = replacementOffset; +- result["replacementLength"] = replacementLength; +- result["results"] = +- results.map((CompletionSuggestion value) => value.toJson()).toList(); +- result["isLast"] = isLast; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("completion.results", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is CompletionResultsParams) { +- return id == other.id && +- replacementOffset == other.replacementOffset && +- replacementLength == other.replacementLength && +- listEqual(results, other.results, +- (CompletionSuggestion a, CompletionSuggestion b) => a == b) && +- isLast == other.isLast; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- hash = JenkinsSmiHash.combine(hash, replacementOffset.hashCode); +- hash = JenkinsSmiHash.combine(hash, replacementLength.hashCode); +- hash = JenkinsSmiHash.combine(hash, results.hashCode); +- hash = JenkinsSmiHash.combine(hash, isLast.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ContextData +- * +- * { +- * "name": String +- * "explicitFileCount": int +- * "implicitFileCount": int +- * "workItemQueueLength": int +- * "cacheEntryExceptions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ContextData implements HasToJson { +- String _name; +- +- int _explicitFileCount; +- +- int _implicitFileCount; +- +- int _workItemQueueLength; +- +- List _cacheEntryExceptions; +- +- /** +- * The name of the context. +- */ +- String get name => _name; +- +- /** +- * The name of the context. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- /** +- * Explicitly analyzed files. +- */ +- int get explicitFileCount => _explicitFileCount; +- +- /** +- * Explicitly analyzed files. +- */ +- void set explicitFileCount(int value) { +- assert(value != null); +- this._explicitFileCount = value; +- } +- +- /** +- * Implicitly analyzed files. +- */ +- int get implicitFileCount => _implicitFileCount; +- +- /** +- * Implicitly analyzed files. +- */ +- void set implicitFileCount(int value) { +- assert(value != null); +- this._implicitFileCount = value; +- } +- +- /** +- * The number of work items in the queue. +- */ +- int get workItemQueueLength => _workItemQueueLength; +- +- /** +- * The number of work items in the queue. +- */ +- void set workItemQueueLength(int value) { +- assert(value != null); +- this._workItemQueueLength = value; +- } +- +- /** +- * Exceptions associated with cache entries. +- */ +- List get cacheEntryExceptions => _cacheEntryExceptions; +- +- /** +- * Exceptions associated with cache entries. +- */ +- void set cacheEntryExceptions(List value) { +- assert(value != null); +- this._cacheEntryExceptions = value; +- } +- +- ContextData(String name, int explicitFileCount, int implicitFileCount, +- int workItemQueueLength, List cacheEntryExceptions) { +- this.name = name; +- this.explicitFileCount = explicitFileCount; +- this.implicitFileCount = implicitFileCount; +- this.workItemQueueLength = workItemQueueLength; +- this.cacheEntryExceptions = cacheEntryExceptions; +- } +- +- factory ContextData.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- int explicitFileCount; +- if (json.containsKey("explicitFileCount")) { +- explicitFileCount = jsonDecoder.decodeInt( +- jsonPath + ".explicitFileCount", json["explicitFileCount"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "explicitFileCount"); +- } +- int implicitFileCount; +- if (json.containsKey("implicitFileCount")) { +- implicitFileCount = jsonDecoder.decodeInt( +- jsonPath + ".implicitFileCount", json["implicitFileCount"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "implicitFileCount"); +- } +- int workItemQueueLength; +- if (json.containsKey("workItemQueueLength")) { +- workItemQueueLength = jsonDecoder.decodeInt( +- jsonPath + ".workItemQueueLength", json["workItemQueueLength"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "workItemQueueLength"); +- } +- List cacheEntryExceptions; +- if (json.containsKey("cacheEntryExceptions")) { +- cacheEntryExceptions = jsonDecoder.decodeList( +- jsonPath + ".cacheEntryExceptions", +- json["cacheEntryExceptions"], +- jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "cacheEntryExceptions"); +- } +- return new ContextData(name, explicitFileCount, implicitFileCount, +- workItemQueueLength, cacheEntryExceptions); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "ContextData", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["name"] = name; +- result["explicitFileCount"] = explicitFileCount; +- result["implicitFileCount"] = implicitFileCount; +- result["workItemQueueLength"] = workItemQueueLength; +- result["cacheEntryExceptions"] = cacheEntryExceptions; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ContextData) { +- return name == other.name && +- explicitFileCount == other.explicitFileCount && +- implicitFileCount == other.implicitFileCount && +- workItemQueueLength == other.workItemQueueLength && +- listEqual(cacheEntryExceptions, other.cacheEntryExceptions, +- (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode); +- hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode); +- hash = JenkinsSmiHash.combine(hash, workItemQueueLength.hashCode); +- hash = JenkinsSmiHash.combine(hash, cacheEntryExceptions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * convertGetterToMethod feedback +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ConvertGetterToMethodFeedback extends RefactoringFeedback +- implements HasToJson { +- @override +- bool operator ==(other) { +- if (other is ConvertGetterToMethodFeedback) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 616032599; +- } +-} +- +-/** +- * convertGetterToMethod options +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ConvertGetterToMethodOptions extends RefactoringOptions +- implements HasToJson { +- @override +- bool operator ==(other) { +- if (other is ConvertGetterToMethodOptions) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 488848400; +- } +-} +- +-/** +- * convertMethodToGetter feedback +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ConvertMethodToGetterFeedback extends RefactoringFeedback +- implements HasToJson { +- @override +- bool operator ==(other) { +- if (other is ConvertMethodToGetterFeedback) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 165291526; +- } +-} +- +-/** +- * convertMethodToGetter options +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ConvertMethodToGetterOptions extends RefactoringOptions +- implements HasToJson { +- @override +- bool operator ==(other) { +- if (other is ConvertMethodToGetterOptions) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 27952290; +- } +-} +- +-/** +- * diagnostic.getDiagnostics params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class DiagnosticGetDiagnosticsParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "diagnostic.getDiagnostics", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is DiagnosticGetDiagnosticsParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 587526202; +- } +-} +- +-/** +- * diagnostic.getDiagnostics result +- * +- * { +- * "contexts": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class DiagnosticGetDiagnosticsResult implements ResponseResult { +- List _contexts; +- +- /** +- * The list of analysis contexts. +- */ +- List get contexts => _contexts; +- +- /** +- * The list of analysis contexts. +- */ +- void set contexts(List value) { +- assert(value != null); +- this._contexts = value; +- } +- +- DiagnosticGetDiagnosticsResult(List contexts) { +- this.contexts = contexts; +- } +- +- factory DiagnosticGetDiagnosticsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List contexts; +- if (json.containsKey("contexts")) { +- contexts = jsonDecoder.decodeList( +- jsonPath + ".contexts", +- json["contexts"], +- (String jsonPath, Object json) => +- new ContextData.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "contexts"); +- } +- return new DiagnosticGetDiagnosticsResult(contexts); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "diagnostic.getDiagnostics result", json); +- } +- } +- +- factory DiagnosticGetDiagnosticsResult.fromResponse(Response response) { +- return new DiagnosticGetDiagnosticsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["contexts"] = +- contexts.map((ContextData value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is DiagnosticGetDiagnosticsResult) { +- return listEqual( +- contexts, other.contexts, (ContextData a, ContextData b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, contexts.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * diagnostic.getServerPort params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class DiagnosticGetServerPortParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "diagnostic.getServerPort", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is DiagnosticGetServerPortParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 367508704; +- } +-} +- +-/** +- * diagnostic.getServerPort result +- * +- * { +- * "port": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class DiagnosticGetServerPortResult implements ResponseResult { +- int _port; +- +- /** +- * The diagnostic server port. +- */ +- int get port => _port; +- +- /** +- * The diagnostic server port. +- */ +- void set port(int value) { +- assert(value != null); +- this._port = value; +- } +- +- DiagnosticGetServerPortResult(int port) { +- this.port = port; +- } +- +- factory DiagnosticGetServerPortResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int port; +- if (json.containsKey("port")) { +- port = jsonDecoder.decodeInt(jsonPath + ".port", json["port"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "port"); +- } +- return new DiagnosticGetServerPortResult(port); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "diagnostic.getServerPort result", json); +- } +- } +- +- factory DiagnosticGetServerPortResult.fromResponse(Response response) { +- return new DiagnosticGetServerPortResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["port"] = port; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is DiagnosticGetServerPortResult) { +- return port == other.port; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, port.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.format params +- * +- * { +- * "file": FilePath +- * "selectionOffset": int +- * "selectionLength": int +- * "lineLength": optional int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditFormatParams implements RequestParams { +- String _file; +- +- int _selectionOffset; +- +- int _selectionLength; +- +- int _lineLength; +- +- /** +- * The file containing the code to be formatted. +- */ +- String get file => _file; +- +- /** +- * The file containing the code to be formatted. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the current selection in the file. +- */ +- int get selectionOffset => _selectionOffset; +- +- /** +- * The offset of the current selection in the file. +- */ +- void set selectionOffset(int value) { +- assert(value != null); +- this._selectionOffset = value; +- } +- +- /** +- * The length of the current selection in the file. +- */ +- int get selectionLength => _selectionLength; +- +- /** +- * The length of the current selection in the file. +- */ +- void set selectionLength(int value) { +- assert(value != null); +- this._selectionLength = value; +- } +- +- /** +- * The line length to be used by the formatter. +- */ +- int get lineLength => _lineLength; +- +- /** +- * The line length to be used by the formatter. +- */ +- void set lineLength(int value) { +- this._lineLength = value; +- } +- +- EditFormatParams(String file, int selectionOffset, int selectionLength, +- {int lineLength}) { +- this.file = file; +- this.selectionOffset = selectionOffset; +- this.selectionLength = selectionLength; +- this.lineLength = lineLength; +- } +- +- factory EditFormatParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int selectionOffset; +- if (json.containsKey("selectionOffset")) { +- selectionOffset = jsonDecoder.decodeInt( +- jsonPath + ".selectionOffset", json["selectionOffset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "selectionOffset"); +- } +- int selectionLength; +- if (json.containsKey("selectionLength")) { +- selectionLength = jsonDecoder.decodeInt( +- jsonPath + ".selectionLength", json["selectionLength"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "selectionLength"); +- } +- int lineLength; +- if (json.containsKey("lineLength")) { +- lineLength = +- jsonDecoder.decodeInt(jsonPath + ".lineLength", json["lineLength"]); +- } +- return new EditFormatParams(file, selectionOffset, selectionLength, +- lineLength: lineLength); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.format params", json); +- } +- } +- +- factory EditFormatParams.fromRequest(Request request) { +- return new EditFormatParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["selectionOffset"] = selectionOffset; +- result["selectionLength"] = selectionLength; +- if (lineLength != null) { +- result["lineLength"] = lineLength; +- } +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.format", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditFormatParams) { +- return file == other.file && +- selectionOffset == other.selectionOffset && +- selectionLength == other.selectionLength && +- lineLength == other.lineLength; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, selectionOffset.hashCode); +- hash = JenkinsSmiHash.combine(hash, selectionLength.hashCode); +- hash = JenkinsSmiHash.combine(hash, lineLength.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.format result +- * +- * { +- * "edits": List +- * "selectionOffset": int +- * "selectionLength": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditFormatResult implements ResponseResult { +- List _edits; +- +- int _selectionOffset; +- +- int _selectionLength; +- +- /** +- * The edit(s) to be applied in order to format the code. The list will be +- * empty if the code was already formatted (there are no changes). +- */ +- List get edits => _edits; +- +- /** +- * The edit(s) to be applied in order to format the code. The list will be +- * empty if the code was already formatted (there are no changes). +- */ +- void set edits(List value) { +- assert(value != null); +- this._edits = value; +- } +- +- /** +- * The offset of the selection after formatting the code. +- */ +- int get selectionOffset => _selectionOffset; +- +- /** +- * The offset of the selection after formatting the code. +- */ +- void set selectionOffset(int value) { +- assert(value != null); +- this._selectionOffset = value; +- } +- +- /** +- * The length of the selection after formatting the code. +- */ +- int get selectionLength => _selectionLength; +- +- /** +- * The length of the selection after formatting the code. +- */ +- void set selectionLength(int value) { +- assert(value != null); +- this._selectionLength = value; +- } +- +- EditFormatResult( +- List edits, int selectionOffset, int selectionLength) { +- this.edits = edits; +- this.selectionOffset = selectionOffset; +- this.selectionLength = selectionLength; +- } +- +- factory EditFormatResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List edits; +- if (json.containsKey("edits")) { +- edits = jsonDecoder.decodeList( +- jsonPath + ".edits", +- json["edits"], +- (String jsonPath, Object json) => +- new SourceEdit.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edits"); +- } +- int selectionOffset; +- if (json.containsKey("selectionOffset")) { +- selectionOffset = jsonDecoder.decodeInt( +- jsonPath + ".selectionOffset", json["selectionOffset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "selectionOffset"); +- } +- int selectionLength; +- if (json.containsKey("selectionLength")) { +- selectionLength = jsonDecoder.decodeInt( +- jsonPath + ".selectionLength", json["selectionLength"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "selectionLength"); +- } +- return new EditFormatResult(edits, selectionOffset, selectionLength); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.format result", json); +- } +- } +- +- factory EditFormatResult.fromResponse(Response response) { +- return new EditFormatResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["edits"] = edits.map((SourceEdit value) => value.toJson()).toList(); +- result["selectionOffset"] = selectionOffset; +- result["selectionLength"] = selectionLength; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditFormatResult) { +- return listEqual( +- edits, other.edits, (SourceEdit a, SourceEdit b) => a == b) && +- selectionOffset == other.selectionOffset && +- selectionLength == other.selectionLength; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, edits.hashCode); +- hash = JenkinsSmiHash.combine(hash, selectionOffset.hashCode); +- hash = JenkinsSmiHash.combine(hash, selectionLength.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getAssists params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetAssistsParams implements RequestParams { +- String _file; +- +- int _offset; +- +- int _length; +- +- /** +- * The file containing the code for which assists are being requested. +- */ +- String get file => _file; +- +- /** +- * The file containing the code for which assists are being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the code for which assists are being requested. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the code for which assists are being requested. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the code for which assists are being requested. +- */ +- int get length => _length; +- +- /** +- * The length of the code for which assists are being requested. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- EditGetAssistsParams(String file, int offset, int length) { +- this.file = file; +- this.offset = offset; +- this.length = length; +- } +- +- factory EditGetAssistsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- return new EditGetAssistsParams(file, offset, length); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.getAssists params", json); +- } +- } +- +- factory EditGetAssistsParams.fromRequest(Request request) { +- return new EditGetAssistsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- result["length"] = length; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.getAssists", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetAssistsParams) { +- return file == other.file && +- offset == other.offset && +- length == other.length; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getAssists result +- * +- * { +- * "assists": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetAssistsResult implements ResponseResult { +- List _assists; +- +- /** +- * The assists that are available at the given location. +- */ +- List get assists => _assists; +- +- /** +- * The assists that are available at the given location. +- */ +- void set assists(List value) { +- assert(value != null); +- this._assists = value; +- } +- +- EditGetAssistsResult(List assists) { +- this.assists = assists; +- } +- +- factory EditGetAssistsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List assists; +- if (json.containsKey("assists")) { +- assists = jsonDecoder.decodeList( +- jsonPath + ".assists", +- json["assists"], +- (String jsonPath, Object json) => +- new SourceChange.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "assists"); +- } +- return new EditGetAssistsResult(assists); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.getAssists result", json); +- } +- } +- +- factory EditGetAssistsResult.fromResponse(Response response) { +- return new EditGetAssistsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["assists"] = +- assists.map((SourceChange value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetAssistsResult) { +- return listEqual( +- assists, other.assists, (SourceChange a, SourceChange b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, assists.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getAvailableRefactorings params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetAvailableRefactoringsParams implements RequestParams { +- String _file; +- +- int _offset; +- +- int _length; +- +- /** +- * The file containing the code on which the refactoring would be based. +- */ +- String get file => _file; +- +- /** +- * The file containing the code on which the refactoring would be based. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the code on which the refactoring would be based. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the code on which the refactoring would be based. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the code on which the refactoring would be based. +- */ +- int get length => _length; +- +- /** +- * The length of the code on which the refactoring would be based. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- EditGetAvailableRefactoringsParams(String file, int offset, int length) { +- this.file = file; +- this.offset = offset; +- this.length = length; +- } +- +- factory EditGetAvailableRefactoringsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- return new EditGetAvailableRefactoringsParams(file, offset, length); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.getAvailableRefactorings params", json); +- } +- } +- +- factory EditGetAvailableRefactoringsParams.fromRequest(Request request) { +- return new EditGetAvailableRefactoringsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- result["length"] = length; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.getAvailableRefactorings", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetAvailableRefactoringsParams) { +- return file == other.file && +- offset == other.offset && +- length == other.length; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getAvailableRefactorings result +- * +- * { +- * "kinds": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetAvailableRefactoringsResult implements ResponseResult { +- List _kinds; +- +- /** +- * The kinds of refactorings that are valid for the given selection. +- */ +- List get kinds => _kinds; +- +- /** +- * The kinds of refactorings that are valid for the given selection. +- */ +- void set kinds(List value) { +- assert(value != null); +- this._kinds = value; +- } +- +- EditGetAvailableRefactoringsResult(List kinds) { +- this.kinds = kinds; +- } +- +- factory EditGetAvailableRefactoringsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List kinds; +- if (json.containsKey("kinds")) { +- kinds = jsonDecoder.decodeList( +- jsonPath + ".kinds", +- json["kinds"], +- (String jsonPath, Object json) => +- new RefactoringKind.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "kinds"); +- } +- return new EditGetAvailableRefactoringsResult(kinds); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.getAvailableRefactorings result", json); +- } +- } +- +- factory EditGetAvailableRefactoringsResult.fromResponse(Response response) { +- return new EditGetAvailableRefactoringsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["kinds"] = +- kinds.map((RefactoringKind value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetAvailableRefactoringsResult) { +- return listEqual( +- kinds, other.kinds, (RefactoringKind a, RefactoringKind b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, kinds.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getFixes params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetFixesParams implements RequestParams { +- String _file; +- +- int _offset; +- +- /** +- * The file containing the errors for which fixes are being requested. +- */ +- String get file => _file; +- +- /** +- * The file containing the errors for which fixes are being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset used to select the errors for which fixes will be returned. +- */ +- int get offset => _offset; +- +- /** +- * The offset used to select the errors for which fixes will be returned. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- EditGetFixesParams(String file, int offset) { +- this.file = file; +- this.offset = offset; +- } +- +- factory EditGetFixesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- return new EditGetFixesParams(file, offset); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.getFixes params", json); +- } +- } +- +- factory EditGetFixesParams.fromRequest(Request request) { +- return new EditGetFixesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.getFixes", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetFixesParams) { +- return file == other.file && offset == other.offset; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getFixes result +- * +- * { +- * "fixes": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetFixesResult implements ResponseResult { +- List _fixes; +- +- /** +- * The fixes that are available for the errors at the given offset. +- */ +- List get fixes => _fixes; +- +- /** +- * The fixes that are available for the errors at the given offset. +- */ +- void set fixes(List value) { +- assert(value != null); +- this._fixes = value; +- } +- +- EditGetFixesResult(List fixes) { +- this.fixes = fixes; +- } +- +- factory EditGetFixesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List fixes; +- if (json.containsKey("fixes")) { +- fixes = jsonDecoder.decodeList( +- jsonPath + ".fixes", +- json["fixes"], +- (String jsonPath, Object json) => +- new AnalysisErrorFixes.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "fixes"); +- } +- return new EditGetFixesResult(fixes); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.getFixes result", json); +- } +- } +- +- factory EditGetFixesResult.fromResponse(Response response) { +- return new EditGetFixesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["fixes"] = +- fixes.map((AnalysisErrorFixes value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetFixesResult) { +- return listEqual(fixes, other.fixes, +- (AnalysisErrorFixes a, AnalysisErrorFixes b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, fixes.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getPostfixCompletion params +- * +- * { +- * "file": FilePath +- * "key": String +- * "offset": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetPostfixCompletionParams implements RequestParams { +- String _file; +- +- String _key; +- +- int _offset; +- +- /** +- * The file containing the postfix template to be expanded. +- */ +- String get file => _file; +- +- /** +- * The file containing the postfix template to be expanded. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The unique name that identifies the template in use. +- */ +- String get key => _key; +- +- /** +- * The unique name that identifies the template in use. +- */ +- void set key(String value) { +- assert(value != null); +- this._key = value; +- } +- +- /** +- * The offset used to identify the code to which the template will be +- * applied. +- */ +- int get offset => _offset; +- +- /** +- * The offset used to identify the code to which the template will be +- * applied. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- EditGetPostfixCompletionParams(String file, String key, int offset) { +- this.file = file; +- this.key = key; +- this.offset = offset; +- } +- +- factory EditGetPostfixCompletionParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- String key; +- if (json.containsKey("key")) { +- key = jsonDecoder.decodeString(jsonPath + ".key", json["key"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "key"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- return new EditGetPostfixCompletionParams(file, key, offset); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.getPostfixCompletion params", json); +- } +- } +- +- factory EditGetPostfixCompletionParams.fromRequest(Request request) { +- return new EditGetPostfixCompletionParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["key"] = key; +- result["offset"] = offset; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.getPostfixCompletion", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetPostfixCompletionParams) { +- return file == other.file && key == other.key && offset == other.offset; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, key.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getPostfixCompletion result +- * +- * { +- * "change": SourceChange +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetPostfixCompletionResult implements ResponseResult { +- SourceChange _change; +- +- /** +- * The change to be applied in order to complete the statement. +- */ +- SourceChange get change => _change; +- +- /** +- * The change to be applied in order to complete the statement. +- */ +- void set change(SourceChange value) { +- assert(value != null); +- this._change = value; +- } +- +- EditGetPostfixCompletionResult(SourceChange change) { +- this.change = change; +- } +- +- factory EditGetPostfixCompletionResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- SourceChange change; +- if (json.containsKey("change")) { +- change = new SourceChange.fromJson( +- jsonDecoder, jsonPath + ".change", json["change"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "change"); +- } +- return new EditGetPostfixCompletionResult(change); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.getPostfixCompletion result", json); +- } +- } +- +- factory EditGetPostfixCompletionResult.fromResponse(Response response) { +- return new EditGetPostfixCompletionResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["change"] = change.toJson(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetPostfixCompletionResult) { +- return change == other.change; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, change.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getRefactoring params +- * +- * { +- * "kind": RefactoringKind +- * "file": FilePath +- * "offset": int +- * "length": int +- * "validateOnly": bool +- * "options": optional RefactoringOptions +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetRefactoringParams implements RequestParams { +- RefactoringKind _kind; +- +- String _file; +- +- int _offset; +- +- int _length; +- +- bool _validateOnly; +- +- RefactoringOptions _options; +- +- /** +- * The kind of refactoring to be performed. +- */ +- RefactoringKind get kind => _kind; +- +- /** +- * The kind of refactoring to be performed. +- */ +- void set kind(RefactoringKind value) { +- assert(value != null); +- this._kind = value; +- } +- +- /** +- * The file containing the code involved in the refactoring. +- */ +- String get file => _file; +- +- /** +- * The file containing the code involved in the refactoring. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the region involved in the refactoring. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the region involved in the refactoring. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the region involved in the refactoring. +- */ +- int get length => _length; +- +- /** +- * The length of the region involved in the refactoring. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * True if the client is only requesting that the values of the options be +- * validated and no change be generated. +- */ +- bool get validateOnly => _validateOnly; +- +- /** +- * True if the client is only requesting that the values of the options be +- * validated and no change be generated. +- */ +- void set validateOnly(bool value) { +- assert(value != null); +- this._validateOnly = value; +- } +- +- /** +- * Data used to provide values provided by the user. The structure of the +- * data is dependent on the kind of refactoring being performed. The data +- * that is expected is documented in the section titled Refactorings, labeled +- * as "Options". This field can be omitted if the refactoring does not +- * require any options or if the values of those options are not known. +- */ +- RefactoringOptions get options => _options; +- +- /** +- * Data used to provide values provided by the user. The structure of the +- * data is dependent on the kind of refactoring being performed. The data +- * that is expected is documented in the section titled Refactorings, labeled +- * as "Options". This field can be omitted if the refactoring does not +- * require any options or if the values of those options are not known. +- */ +- void set options(RefactoringOptions value) { +- this._options = value; +- } +- +- EditGetRefactoringParams(RefactoringKind kind, String file, int offset, +- int length, bool validateOnly, +- {RefactoringOptions options}) { +- this.kind = kind; +- this.file = file; +- this.offset = offset; +- this.length = length; +- this.validateOnly = validateOnly; +- this.options = options; +- } +- +- factory EditGetRefactoringParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- RefactoringKind kind; +- if (json.containsKey("kind")) { +- kind = new RefactoringKind.fromJson( +- jsonDecoder, jsonPath + ".kind", json["kind"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "kind"); +- } +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- bool validateOnly; +- if (json.containsKey("validateOnly")) { +- validateOnly = jsonDecoder.decodeBool( +- jsonPath + ".validateOnly", json["validateOnly"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "validateOnly"); +- } +- RefactoringOptions options; +- if (json.containsKey("options")) { +- options = new RefactoringOptions.fromJson( +- jsonDecoder, jsonPath + ".options", json["options"], kind); +- } +- return new EditGetRefactoringParams( +- kind, file, offset, length, validateOnly, +- options: options); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.getRefactoring params", json); +- } +- } +- +- factory EditGetRefactoringParams.fromRequest(Request request) { +- var params = new EditGetRefactoringParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- REQUEST_ID_REFACTORING_KINDS[request.id] = params.kind; +- return params; +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["kind"] = kind.toJson(); +- result["file"] = file; +- result["offset"] = offset; +- result["length"] = length; +- result["validateOnly"] = validateOnly; +- if (options != null) { +- result["options"] = options.toJson(); +- } +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.getRefactoring", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetRefactoringParams) { +- return kind == other.kind && +- file == other.file && +- offset == other.offset && +- length == other.length && +- validateOnly == other.validateOnly && +- options == other.options; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, kind.hashCode); +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, validateOnly.hashCode); +- hash = JenkinsSmiHash.combine(hash, options.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getRefactoring result +- * +- * { +- * "initialProblems": List +- * "optionsProblems": List +- * "finalProblems": List +- * "feedback": optional RefactoringFeedback +- * "change": optional SourceChange +- * "potentialEdits": optional List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetRefactoringResult implements ResponseResult { +- List _initialProblems; +- +- List _optionsProblems; +- +- List _finalProblems; +- +- RefactoringFeedback _feedback; +- +- SourceChange _change; +- +- List _potentialEdits; +- +- /** +- * The initial status of the refactoring, i.e. problems related to the +- * context in which the refactoring is requested. The array will be empty if +- * there are no known problems. +- */ +- List get initialProblems => _initialProblems; +- +- /** +- * The initial status of the refactoring, i.e. problems related to the +- * context in which the refactoring is requested. The array will be empty if +- * there are no known problems. +- */ +- void set initialProblems(List value) { +- assert(value != null); +- this._initialProblems = value; +- } +- +- /** +- * The options validation status, i.e. problems in the given options, such as +- * light-weight validation of a new name, flags compatibility, etc. The array +- * will be empty if there are no known problems. +- */ +- List get optionsProblems => _optionsProblems; +- +- /** +- * The options validation status, i.e. problems in the given options, such as +- * light-weight validation of a new name, flags compatibility, etc. The array +- * will be empty if there are no known problems. +- */ +- void set optionsProblems(List value) { +- assert(value != null); +- this._optionsProblems = value; +- } +- +- /** +- * The final status of the refactoring, i.e. problems identified in the +- * result of a full, potentially expensive validation and / or change +- * creation. The array will be empty if there are no known problems. +- */ +- List get finalProblems => _finalProblems; +- +- /** +- * The final status of the refactoring, i.e. problems identified in the +- * result of a full, potentially expensive validation and / or change +- * creation. The array will be empty if there are no known problems. +- */ +- void set finalProblems(List value) { +- assert(value != null); +- this._finalProblems = value; +- } +- +- /** +- * Data used to provide feedback to the user. The structure of the data is +- * dependent on the kind of refactoring being created. The data that is +- * returned is documented in the section titled Refactorings, labeled as +- * "Feedback". +- */ +- RefactoringFeedback get feedback => _feedback; +- +- /** +- * Data used to provide feedback to the user. The structure of the data is +- * dependent on the kind of refactoring being created. The data that is +- * returned is documented in the section titled Refactorings, labeled as +- * "Feedback". +- */ +- void set feedback(RefactoringFeedback value) { +- this._feedback = value; +- } +- +- /** +- * The changes that are to be applied to affect the refactoring. This field +- * will be omitted if there are problems that prevent a set of changes from +- * being computed, such as having no options specified for a refactoring that +- * requires them, or if only validation was requested. +- */ +- SourceChange get change => _change; +- +- /** +- * The changes that are to be applied to affect the refactoring. This field +- * will be omitted if there are problems that prevent a set of changes from +- * being computed, such as having no options specified for a refactoring that +- * requires them, or if only validation was requested. +- */ +- void set change(SourceChange value) { +- this._change = value; +- } +- +- /** +- * The ids of source edits that are not known to be valid. An edit is not +- * known to be valid if there was insufficient type information for the +- * server to be able to determine whether or not the code needs to be +- * modified, such as when a member is being renamed and there is a reference +- * to a member from an unknown type. This field will be omitted if the change +- * field is omitted or if there are no potential edits for the refactoring. +- */ +- List get potentialEdits => _potentialEdits; +- +- /** +- * The ids of source edits that are not known to be valid. An edit is not +- * known to be valid if there was insufficient type information for the +- * server to be able to determine whether or not the code needs to be +- * modified, such as when a member is being renamed and there is a reference +- * to a member from an unknown type. This field will be omitted if the change +- * field is omitted or if there are no potential edits for the refactoring. +- */ +- void set potentialEdits(List value) { +- this._potentialEdits = value; +- } +- +- EditGetRefactoringResult( +- List initialProblems, +- List optionsProblems, +- List finalProblems, +- {RefactoringFeedback feedback, +- SourceChange change, +- List potentialEdits}) { +- this.initialProblems = initialProblems; +- this.optionsProblems = optionsProblems; +- this.finalProblems = finalProblems; +- this.feedback = feedback; +- this.change = change; +- this.potentialEdits = potentialEdits; +- } +- +- factory EditGetRefactoringResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List initialProblems; +- if (json.containsKey("initialProblems")) { +- initialProblems = jsonDecoder.decodeList( +- jsonPath + ".initialProblems", +- json["initialProblems"], +- (String jsonPath, Object json) => +- new RefactoringProblem.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "initialProblems"); +- } +- List optionsProblems; +- if (json.containsKey("optionsProblems")) { +- optionsProblems = jsonDecoder.decodeList( +- jsonPath + ".optionsProblems", +- json["optionsProblems"], +- (String jsonPath, Object json) => +- new RefactoringProblem.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "optionsProblems"); +- } +- List finalProblems; +- if (json.containsKey("finalProblems")) { +- finalProblems = jsonDecoder.decodeList( +- jsonPath + ".finalProblems", +- json["finalProblems"], +- (String jsonPath, Object json) => +- new RefactoringProblem.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "finalProblems"); +- } +- RefactoringFeedback feedback; +- if (json.containsKey("feedback")) { +- feedback = new RefactoringFeedback.fromJson( +- jsonDecoder, jsonPath + ".feedback", json["feedback"], json); +- } +- SourceChange change; +- if (json.containsKey("change")) { +- change = new SourceChange.fromJson( +- jsonDecoder, jsonPath + ".change", json["change"]); +- } +- List potentialEdits; +- if (json.containsKey("potentialEdits")) { +- potentialEdits = jsonDecoder.decodeList(jsonPath + ".potentialEdits", +- json["potentialEdits"], jsonDecoder.decodeString); +- } +- return new EditGetRefactoringResult( +- initialProblems, optionsProblems, finalProblems, +- feedback: feedback, change: change, potentialEdits: potentialEdits); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.getRefactoring result", json); +- } +- } +- +- factory EditGetRefactoringResult.fromResponse(Response response) { +- return new EditGetRefactoringResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["initialProblems"] = initialProblems +- .map((RefactoringProblem value) => value.toJson()) +- .toList(); +- result["optionsProblems"] = optionsProblems +- .map((RefactoringProblem value) => value.toJson()) +- .toList(); +- result["finalProblems"] = finalProblems +- .map((RefactoringProblem value) => value.toJson()) +- .toList(); +- if (feedback != null) { +- result["feedback"] = feedback.toJson(); +- } +- if (change != null) { +- result["change"] = change.toJson(); +- } +- if (potentialEdits != null) { +- result["potentialEdits"] = potentialEdits; +- } +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetRefactoringResult) { +- return listEqual(initialProblems, other.initialProblems, +- (RefactoringProblem a, RefactoringProblem b) => a == b) && +- listEqual(optionsProblems, other.optionsProblems, +- (RefactoringProblem a, RefactoringProblem b) => a == b) && +- listEqual(finalProblems, other.finalProblems, +- (RefactoringProblem a, RefactoringProblem b) => a == b) && +- feedback == other.feedback && +- change == other.change && +- listEqual(potentialEdits, other.potentialEdits, +- (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, initialProblems.hashCode); +- hash = JenkinsSmiHash.combine(hash, optionsProblems.hashCode); +- hash = JenkinsSmiHash.combine(hash, finalProblems.hashCode); +- hash = JenkinsSmiHash.combine(hash, feedback.hashCode); +- hash = JenkinsSmiHash.combine(hash, change.hashCode); +- hash = JenkinsSmiHash.combine(hash, potentialEdits.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getStatementCompletion params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetStatementCompletionParams implements RequestParams { +- String _file; +- +- int _offset; +- +- /** +- * The file containing the statement to be completed. +- */ +- String get file => _file; +- +- /** +- * The file containing the statement to be completed. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset used to identify the statement to be completed. +- */ +- int get offset => _offset; +- +- /** +- * The offset used to identify the statement to be completed. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- EditGetStatementCompletionParams(String file, int offset) { +- this.file = file; +- this.offset = offset; +- } +- +- factory EditGetStatementCompletionParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- return new EditGetStatementCompletionParams(file, offset); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.getStatementCompletion params", json); +- } +- } +- +- factory EditGetStatementCompletionParams.fromRequest(Request request) { +- return new EditGetStatementCompletionParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.getStatementCompletion", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetStatementCompletionParams) { +- return file == other.file && offset == other.offset; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.getStatementCompletion result +- * +- * { +- * "change": SourceChange +- * "whitespaceOnly": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditGetStatementCompletionResult implements ResponseResult { +- SourceChange _change; +- +- bool _whitespaceOnly; +- +- /** +- * The change to be applied in order to complete the statement. +- */ +- SourceChange get change => _change; +- +- /** +- * The change to be applied in order to complete the statement. +- */ +- void set change(SourceChange value) { +- assert(value != null); +- this._change = value; +- } +- +- /** +- * Will be true if the change contains nothing but whitespace characters, or +- * is empty. +- */ +- bool get whitespaceOnly => _whitespaceOnly; +- +- /** +- * Will be true if the change contains nothing but whitespace characters, or +- * is empty. +- */ +- void set whitespaceOnly(bool value) { +- assert(value != null); +- this._whitespaceOnly = value; +- } +- +- EditGetStatementCompletionResult(SourceChange change, bool whitespaceOnly) { +- this.change = change; +- this.whitespaceOnly = whitespaceOnly; +- } +- +- factory EditGetStatementCompletionResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- SourceChange change; +- if (json.containsKey("change")) { +- change = new SourceChange.fromJson( +- jsonDecoder, jsonPath + ".change", json["change"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "change"); +- } +- bool whitespaceOnly; +- if (json.containsKey("whitespaceOnly")) { +- whitespaceOnly = jsonDecoder.decodeBool( +- jsonPath + ".whitespaceOnly", json["whitespaceOnly"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "whitespaceOnly"); +- } +- return new EditGetStatementCompletionResult(change, whitespaceOnly); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.getStatementCompletion result", json); +- } +- } +- +- factory EditGetStatementCompletionResult.fromResponse(Response response) { +- return new EditGetStatementCompletionResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["change"] = change.toJson(); +- result["whitespaceOnly"] = whitespaceOnly; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditGetStatementCompletionResult) { +- return change == other.change && whitespaceOnly == other.whitespaceOnly; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, change.hashCode); +- hash = JenkinsSmiHash.combine(hash, whitespaceOnly.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.importElements params +- * +- * { +- * "file": FilePath +- * "elements": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditImportElementsParams implements RequestParams { +- String _file; +- +- List _elements; +- +- /** +- * The file in which the specified elements are to be made accessible. +- */ +- String get file => _file; +- +- /** +- * The file in which the specified elements are to be made accessible. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The elements to be made accessible in the specified file. +- */ +- List get elements => _elements; +- +- /** +- * The elements to be made accessible in the specified file. +- */ +- void set elements(List value) { +- assert(value != null); +- this._elements = value; +- } +- +- EditImportElementsParams(String file, List elements) { +- this.file = file; +- this.elements = elements; +- } +- +- factory EditImportElementsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- List elements; +- if (json.containsKey("elements")) { +- elements = jsonDecoder.decodeList( +- jsonPath + ".elements", +- json["elements"], +- (String jsonPath, Object json) => +- new ImportedElements.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "elements"); +- } +- return new EditImportElementsParams(file, elements); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json); +- } +- } +- +- factory EditImportElementsParams.fromRequest(Request request) { +- return new EditImportElementsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["elements"] = +- elements.map((ImportedElements value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.importElements", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditImportElementsParams) { +- return file == other.file && +- listEqual(elements, other.elements, +- (ImportedElements a, ImportedElements b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, elements.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.importElements result +- * +- * { +- * "edit": SourceFileEdit +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditImportElementsResult implements ResponseResult { +- SourceFileEdit _edit; +- +- /** +- * The edits to be applied in order to make the specified elements +- * accessible. The file to be edited will be the defining compilation unit of +- * the library containing the file specified in the request, which can be +- * different than the file specified in the request if the specified file is +- * a part file. +- */ +- SourceFileEdit get edit => _edit; +- +- /** +- * The edits to be applied in order to make the specified elements +- * accessible. The file to be edited will be the defining compilation unit of +- * the library containing the file specified in the request, which can be +- * different than the file specified in the request if the specified file is +- * a part file. +- */ +- void set edit(SourceFileEdit value) { +- assert(value != null); +- this._edit = value; +- } +- +- EditImportElementsResult(SourceFileEdit edit) { +- this.edit = edit; +- } +- +- factory EditImportElementsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- SourceFileEdit edit; +- if (json.containsKey("edit")) { +- edit = new SourceFileEdit.fromJson( +- jsonDecoder, jsonPath + ".edit", json["edit"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit"); +- } +- return new EditImportElementsResult(edit); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.importElements result", json); +- } +- } +- +- factory EditImportElementsResult.fromResponse(Response response) { +- return new EditImportElementsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["edit"] = edit.toJson(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditImportElementsResult) { +- return edit == other.edit; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, edit.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.isPostfixCompletionApplicable params +- * +- * { +- * "file": FilePath +- * "key": String +- * "offset": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditIsPostfixCompletionApplicableParams implements RequestParams { +- String _file; +- +- String _key; +- +- int _offset; +- +- /** +- * The file containing the postfix template to be expanded. +- */ +- String get file => _file; +- +- /** +- * The file containing the postfix template to be expanded. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The unique name that identifies the template in use. +- */ +- String get key => _key; +- +- /** +- * The unique name that identifies the template in use. +- */ +- void set key(String value) { +- assert(value != null); +- this._key = value; +- } +- +- /** +- * The offset used to identify the code to which the template will be +- * applied. +- */ +- int get offset => _offset; +- +- /** +- * The offset used to identify the code to which the template will be +- * applied. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- EditIsPostfixCompletionApplicableParams(String file, String key, int offset) { +- this.file = file; +- this.key = key; +- this.offset = offset; +- } +- +- factory EditIsPostfixCompletionApplicableParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- String key; +- if (json.containsKey("key")) { +- key = jsonDecoder.decodeString(jsonPath + ".key", json["key"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "key"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- return new EditIsPostfixCompletionApplicableParams(file, key, offset); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.isPostfixCompletionApplicable params", json); +- } +- } +- +- factory EditIsPostfixCompletionApplicableParams.fromRequest(Request request) { +- return new EditIsPostfixCompletionApplicableParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["key"] = key; +- result["offset"] = offset; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.isPostfixCompletionApplicable", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditIsPostfixCompletionApplicableParams) { +- return file == other.file && key == other.key && offset == other.offset; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, key.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.isPostfixCompletionApplicable result +- * +- * { +- * "value": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditIsPostfixCompletionApplicableResult implements ResponseResult { +- bool _value; +- +- /** +- * True if the template can be expanded at the given location. +- */ +- bool get value => _value; +- +- /** +- * True if the template can be expanded at the given location. +- */ +- void set value(bool value) { +- assert(value != null); +- this._value = value; +- } +- +- EditIsPostfixCompletionApplicableResult(bool value) { +- this.value = value; +- } +- +- factory EditIsPostfixCompletionApplicableResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool value; +- if (json.containsKey("value")) { +- value = jsonDecoder.decodeBool(jsonPath + ".value", json["value"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "value"); +- } +- return new EditIsPostfixCompletionApplicableResult(value); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.isPostfixCompletionApplicable result", json); +- } +- } +- +- factory EditIsPostfixCompletionApplicableResult.fromResponse( +- Response response) { +- return new EditIsPostfixCompletionApplicableResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["value"] = value; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditIsPostfixCompletionApplicableResult) { +- return value == other.value; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, value.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.listPostfixCompletionTemplates params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditListPostfixCompletionTemplatesParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.listPostfixCompletionTemplates", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is EditListPostfixCompletionTemplatesParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 690713107; +- } +-} +- +-/** +- * edit.listPostfixCompletionTemplates result +- * +- * { +- * "templates": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditListPostfixCompletionTemplatesResult implements ResponseResult { +- List _templates; +- +- /** +- * The list of available templates. +- */ +- List get templates => _templates; +- +- /** +- * The list of available templates. +- */ +- void set templates(List value) { +- assert(value != null); +- this._templates = value; +- } +- +- EditListPostfixCompletionTemplatesResult( +- List templates) { +- this.templates = templates; +- } +- +- factory EditListPostfixCompletionTemplatesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List templates; +- if (json.containsKey("templates")) { +- templates = jsonDecoder.decodeList( +- jsonPath + ".templates", +- json["templates"], +- (String jsonPath, Object json) => +- new PostfixTemplateDescriptor.fromJson( +- jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "templates"); +- } +- return new EditListPostfixCompletionTemplatesResult(templates); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.listPostfixCompletionTemplates result", json); +- } +- } +- +- factory EditListPostfixCompletionTemplatesResult.fromResponse( +- Response response) { +- return new EditListPostfixCompletionTemplatesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["templates"] = templates +- .map((PostfixTemplateDescriptor value) => value.toJson()) +- .toList(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditListPostfixCompletionTemplatesResult) { +- return listEqual(templates, other.templates, +- (PostfixTemplateDescriptor a, PostfixTemplateDescriptor b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, templates.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.organizeDirectives params +- * +- * { +- * "file": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditOrganizeDirectivesParams implements RequestParams { +- String _file; +- +- /** +- * The Dart file to organize directives in. +- */ +- String get file => _file; +- +- /** +- * The Dart file to organize directives in. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- EditOrganizeDirectivesParams(String file) { +- this.file = file; +- } +- +- factory EditOrganizeDirectivesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- return new EditOrganizeDirectivesParams(file); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.organizeDirectives params", json); +- } +- } +- +- factory EditOrganizeDirectivesParams.fromRequest(Request request) { +- return new EditOrganizeDirectivesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.organizeDirectives", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditOrganizeDirectivesParams) { +- return file == other.file; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.organizeDirectives result +- * +- * { +- * "edit": SourceFileEdit +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditOrganizeDirectivesResult implements ResponseResult { +- SourceFileEdit _edit; +- +- /** +- * The file edit that is to be applied to the given file to effect the +- * organizing. +- */ +- SourceFileEdit get edit => _edit; +- +- /** +- * The file edit that is to be applied to the given file to effect the +- * organizing. +- */ +- void set edit(SourceFileEdit value) { +- assert(value != null); +- this._edit = value; +- } +- +- EditOrganizeDirectivesResult(SourceFileEdit edit) { +- this.edit = edit; +- } +- +- factory EditOrganizeDirectivesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- SourceFileEdit edit; +- if (json.containsKey("edit")) { +- edit = new SourceFileEdit.fromJson( +- jsonDecoder, jsonPath + ".edit", json["edit"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit"); +- } +- return new EditOrganizeDirectivesResult(edit); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "edit.organizeDirectives result", json); +- } +- } +- +- factory EditOrganizeDirectivesResult.fromResponse(Response response) { +- return new EditOrganizeDirectivesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["edit"] = edit.toJson(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditOrganizeDirectivesResult) { +- return edit == other.edit; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, edit.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.sortMembers params +- * +- * { +- * "file": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditSortMembersParams implements RequestParams { +- String _file; +- +- /** +- * The Dart file to sort. +- */ +- String get file => _file; +- +- /** +- * The Dart file to sort. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- EditSortMembersParams(String file) { +- this.file = file; +- } +- +- factory EditSortMembersParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- return new EditSortMembersParams(file); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.sortMembers params", json); +- } +- } +- +- factory EditSortMembersParams.fromRequest(Request request) { +- return new EditSortMembersParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "edit.sortMembers", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditSortMembersParams) { +- return file == other.file; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * edit.sortMembers result +- * +- * { +- * "edit": SourceFileEdit +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class EditSortMembersResult implements ResponseResult { +- SourceFileEdit _edit; +- +- /** +- * The file edit that is to be applied to the given file to effect the +- * sorting. +- */ +- SourceFileEdit get edit => _edit; +- +- /** +- * The file edit that is to be applied to the given file to effect the +- * sorting. +- */ +- void set edit(SourceFileEdit value) { +- assert(value != null); +- this._edit = value; +- } +- +- EditSortMembersResult(SourceFileEdit edit) { +- this.edit = edit; +- } +- +- factory EditSortMembersResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- SourceFileEdit edit; +- if (json.containsKey("edit")) { +- edit = new SourceFileEdit.fromJson( +- jsonDecoder, jsonPath + ".edit", json["edit"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit"); +- } +- return new EditSortMembersResult(edit); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "edit.sortMembers result", json); +- } +- } +- +- factory EditSortMembersResult.fromResponse(Response response) { +- return new EditSortMembersResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["edit"] = edit.toJson(); +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is EditSortMembersResult) { +- return edit == other.edit; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, edit.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ExecutableFile +- * +- * { +- * "file": FilePath +- * "kind": ExecutableKind +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutableFile implements HasToJson { +- String _file; +- +- ExecutableKind _kind; +- +- /** +- * The path of the executable file. +- */ +- String get file => _file; +- +- /** +- * The path of the executable file. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The kind of the executable file. +- */ +- ExecutableKind get kind => _kind; +- +- /** +- * The kind of the executable file. +- */ +- void set kind(ExecutableKind value) { +- assert(value != null); +- this._kind = value; +- } +- +- ExecutableFile(String file, ExecutableKind kind) { +- this.file = file; +- this.kind = kind; +- } +- +- factory ExecutableFile.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- ExecutableKind kind; +- if (json.containsKey("kind")) { +- kind = new ExecutableKind.fromJson( +- jsonDecoder, jsonPath + ".kind", json["kind"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "kind"); +- } +- return new ExecutableFile(file, kind); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "ExecutableFile", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["kind"] = kind.toJson(); +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutableFile) { +- return file == other.file && kind == other.kind; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, kind.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ExecutableKind +- * +- * enum { +- * CLIENT +- * EITHER +- * NOT_EXECUTABLE +- * SERVER +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutableKind implements Enum { +- static const ExecutableKind CLIENT = const ExecutableKind._("CLIENT"); +- +- static const ExecutableKind EITHER = const ExecutableKind._("EITHER"); +- +- static const ExecutableKind NOT_EXECUTABLE = +- const ExecutableKind._("NOT_EXECUTABLE"); +- +- static const ExecutableKind SERVER = const ExecutableKind._("SERVER"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [ +- CLIENT, +- EITHER, +- NOT_EXECUTABLE, +- SERVER +- ]; +- +- @override +- final String name; +- +- const ExecutableKind._(this.name); +- +- factory ExecutableKind(String name) { +- switch (name) { +- case "CLIENT": +- return CLIENT; +- case "EITHER": +- return EITHER; +- case "NOT_EXECUTABLE": +- return NOT_EXECUTABLE; +- case "SERVER": +- return SERVER; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory ExecutableKind.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new ExecutableKind(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "ExecutableKind", json); +- } +- +- @override +- String toString() => "ExecutableKind.$name"; +- +- String toJson() => name; +-} +- +-/** +- * execution.createContext params +- * +- * { +- * "contextRoot": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionCreateContextParams implements RequestParams { +- String _contextRoot; +- +- /** +- * The path of the Dart or HTML file that will be launched, or the path of +- * the directory containing the file. +- */ +- String get contextRoot => _contextRoot; +- +- /** +- * The path of the Dart or HTML file that will be launched, or the path of +- * the directory containing the file. +- */ +- void set contextRoot(String value) { +- assert(value != null); +- this._contextRoot = value; +- } +- +- ExecutionCreateContextParams(String contextRoot) { +- this.contextRoot = contextRoot; +- } +- +- factory ExecutionCreateContextParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String contextRoot; +- if (json.containsKey("contextRoot")) { +- contextRoot = jsonDecoder.decodeString( +- jsonPath + ".contextRoot", json["contextRoot"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "contextRoot"); +- } +- return new ExecutionCreateContextParams(contextRoot); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "execution.createContext params", json); +- } +- } +- +- factory ExecutionCreateContextParams.fromRequest(Request request) { +- return new ExecutionCreateContextParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["contextRoot"] = contextRoot; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "execution.createContext", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionCreateContextParams) { +- return contextRoot == other.contextRoot; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, contextRoot.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * execution.createContext result +- * +- * { +- * "id": ExecutionContextId +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionCreateContextResult implements ResponseResult { +- String _id; +- +- /** +- * The identifier used to refer to the execution context that was created. +- */ +- String get id => _id; +- +- /** +- * The identifier used to refer to the execution context that was created. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- ExecutionCreateContextResult(String id) { +- this.id = id; +- } +- +- factory ExecutionCreateContextResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- return new ExecutionCreateContextResult(id); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "execution.createContext result", json); +- } +- } +- +- factory ExecutionCreateContextResult.fromResponse(Response response) { +- return new ExecutionCreateContextResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionCreateContextResult) { +- return id == other.id; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * execution.deleteContext params +- * +- * { +- * "id": ExecutionContextId +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionDeleteContextParams implements RequestParams { +- String _id; +- +- /** +- * The identifier of the execution context that is to be deleted. +- */ +- String get id => _id; +- +- /** +- * The identifier of the execution context that is to be deleted. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- ExecutionDeleteContextParams(String id) { +- this.id = id; +- } +- +- factory ExecutionDeleteContextParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- return new ExecutionDeleteContextParams(id); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "execution.deleteContext params", json); +- } +- } +- +- factory ExecutionDeleteContextParams.fromRequest(Request request) { +- return new ExecutionDeleteContextParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "execution.deleteContext", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionDeleteContextParams) { +- return id == other.id; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * execution.deleteContext result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionDeleteContextResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is ExecutionDeleteContextResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 479954425; +- } +-} +- +-/** +- * execution.launchData params +- * +- * { +- * "file": FilePath +- * "kind": optional ExecutableKind +- * "referencedFiles": optional List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionLaunchDataParams implements HasToJson { +- String _file; +- +- ExecutableKind _kind; +- +- List _referencedFiles; +- +- /** +- * The file for which launch data is being provided. This will either be a +- * Dart library or an HTML file. +- */ +- String get file => _file; +- +- /** +- * The file for which launch data is being provided. This will either be a +- * Dart library or an HTML file. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The kind of the executable file. This field is omitted if the file is not +- * a Dart file. +- */ +- ExecutableKind get kind => _kind; +- +- /** +- * The kind of the executable file. This field is omitted if the file is not +- * a Dart file. +- */ +- void set kind(ExecutableKind value) { +- this._kind = value; +- } +- +- /** +- * A list of the Dart files that are referenced by the file. This field is +- * omitted if the file is not an HTML file. +- */ +- List get referencedFiles => _referencedFiles; +- +- /** +- * A list of the Dart files that are referenced by the file. This field is +- * omitted if the file is not an HTML file. +- */ +- void set referencedFiles(List value) { +- this._referencedFiles = value; +- } +- +- ExecutionLaunchDataParams(String file, +- {ExecutableKind kind, List referencedFiles}) { +- this.file = file; +- this.kind = kind; +- this.referencedFiles = referencedFiles; +- } +- +- factory ExecutionLaunchDataParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- ExecutableKind kind; +- if (json.containsKey("kind")) { +- kind = new ExecutableKind.fromJson( +- jsonDecoder, jsonPath + ".kind", json["kind"]); +- } +- List referencedFiles; +- if (json.containsKey("referencedFiles")) { +- referencedFiles = jsonDecoder.decodeList(jsonPath + ".referencedFiles", +- json["referencedFiles"], jsonDecoder.decodeString); +- } +- return new ExecutionLaunchDataParams(file, +- kind: kind, referencedFiles: referencedFiles); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "execution.launchData params", json); +- } +- } +- +- factory ExecutionLaunchDataParams.fromNotification( +- Notification notification) { +- return new ExecutionLaunchDataParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- if (kind != null) { +- result["kind"] = kind.toJson(); +- } +- if (referencedFiles != null) { +- result["referencedFiles"] = referencedFiles; +- } +- return result; +- } +- +- Notification toNotification() { +- return new Notification("execution.launchData", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionLaunchDataParams) { +- return file == other.file && +- kind == other.kind && +- listEqual(referencedFiles, other.referencedFiles, +- (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, kind.hashCode); +- hash = JenkinsSmiHash.combine(hash, referencedFiles.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * execution.mapUri params +- * +- * { +- * "id": ExecutionContextId +- * "file": optional FilePath +- * "uri": optional String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionMapUriParams implements RequestParams { +- String _id; +- +- String _file; +- +- String _uri; +- +- /** +- * The identifier of the execution context in which the URI is to be mapped. +- */ +- String get id => _id; +- +- /** +- * The identifier of the execution context in which the URI is to be mapped. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- /** +- * The path of the file to be mapped into a URI. +- */ +- String get file => _file; +- +- /** +- * The path of the file to be mapped into a URI. +- */ +- void set file(String value) { +- this._file = value; +- } +- +- /** +- * The URI to be mapped into a file path. +- */ +- String get uri => _uri; +- +- /** +- * The URI to be mapped into a file path. +- */ +- void set uri(String value) { +- this._uri = value; +- } +- +- ExecutionMapUriParams(String id, {String file, String uri}) { +- this.id = id; +- this.file = file; +- this.uri = uri; +- } +- +- factory ExecutionMapUriParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } +- String uri; +- if (json.containsKey("uri")) { +- uri = jsonDecoder.decodeString(jsonPath + ".uri", json["uri"]); +- } +- return new ExecutionMapUriParams(id, file: file, uri: uri); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "execution.mapUri params", json); +- } +- } +- +- factory ExecutionMapUriParams.fromRequest(Request request) { +- return new ExecutionMapUriParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- if (file != null) { +- result["file"] = file; +- } +- if (uri != null) { +- result["uri"] = uri; +- } +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "execution.mapUri", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionMapUriParams) { +- return id == other.id && file == other.file && uri == other.uri; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, uri.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * execution.mapUri result +- * +- * { +- * "file": optional FilePath +- * "uri": optional String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionMapUriResult implements ResponseResult { +- String _file; +- +- String _uri; +- +- /** +- * The file to which the URI was mapped. This field is omitted if the uri +- * field was not given in the request. +- */ +- String get file => _file; +- +- /** +- * The file to which the URI was mapped. This field is omitted if the uri +- * field was not given in the request. +- */ +- void set file(String value) { +- this._file = value; +- } +- +- /** +- * The URI to which the file path was mapped. This field is omitted if the +- * file field was not given in the request. +- */ +- String get uri => _uri; +- +- /** +- * The URI to which the file path was mapped. This field is omitted if the +- * file field was not given in the request. +- */ +- void set uri(String value) { +- this._uri = value; +- } +- +- ExecutionMapUriResult({String file, String uri}) { +- this.file = file; +- this.uri = uri; +- } +- +- factory ExecutionMapUriResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } +- String uri; +- if (json.containsKey("uri")) { +- uri = jsonDecoder.decodeString(jsonPath + ".uri", json["uri"]); +- } +- return new ExecutionMapUriResult(file: file, uri: uri); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "execution.mapUri result", json); +- } +- } +- +- factory ExecutionMapUriResult.fromResponse(Response response) { +- return new ExecutionMapUriResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (file != null) { +- result["file"] = file; +- } +- if (uri != null) { +- result["uri"] = uri; +- } +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionMapUriResult) { +- return file == other.file && uri == other.uri; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, uri.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ExecutionService +- * +- * enum { +- * LAUNCH_DATA +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionService implements Enum { +- static const ExecutionService LAUNCH_DATA = +- const ExecutionService._("LAUNCH_DATA"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [ +- LAUNCH_DATA +- ]; +- +- @override +- final String name; +- +- const ExecutionService._(this.name); +- +- factory ExecutionService(String name) { +- switch (name) { +- case "LAUNCH_DATA": +- return LAUNCH_DATA; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory ExecutionService.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new ExecutionService(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "ExecutionService", json); +- } +- +- @override +- String toString() => "ExecutionService.$name"; +- +- String toJson() => name; +-} +- +-/** +- * execution.setSubscriptions params +- * +- * { +- * "subscriptions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionSetSubscriptionsParams implements RequestParams { +- List _subscriptions; +- +- /** +- * A list of the services being subscribed to. +- */ +- List get subscriptions => _subscriptions; +- +- /** +- * A list of the services being subscribed to. +- */ +- void set subscriptions(List value) { +- assert(value != null); +- this._subscriptions = value; +- } +- +- ExecutionSetSubscriptionsParams(List subscriptions) { +- this.subscriptions = subscriptions; +- } +- +- factory ExecutionSetSubscriptionsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List subscriptions; +- if (json.containsKey("subscriptions")) { +- subscriptions = jsonDecoder.decodeList( +- jsonPath + ".subscriptions", +- json["subscriptions"], +- (String jsonPath, Object json) => +- new ExecutionService.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "subscriptions"); +- } +- return new ExecutionSetSubscriptionsParams(subscriptions); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "execution.setSubscriptions params", json); +- } +- } +- +- factory ExecutionSetSubscriptionsParams.fromRequest(Request request) { +- return new ExecutionSetSubscriptionsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["subscriptions"] = +- subscriptions.map((ExecutionService value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "execution.setSubscriptions", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExecutionSetSubscriptionsParams) { +- return listEqual(subscriptions, other.subscriptions, +- (ExecutionService a, ExecutionService b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * execution.setSubscriptions result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExecutionSetSubscriptionsResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is ExecutionSetSubscriptionsResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 287678780; +- } +-} +- +-/** +- * extractLocalVariable feedback +- * +- * { +- * "coveringExpressionOffsets": optional List +- * "coveringExpressionLengths": optional List +- * "names": List +- * "offsets": List +- * "lengths": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExtractLocalVariableFeedback extends RefactoringFeedback { +- List _coveringExpressionOffsets; +- +- List _coveringExpressionLengths; +- +- List _names; +- +- List _offsets; +- +- List _lengths; +- +- /** +- * The offsets of the expressions that cover the specified selection, from +- * the down most to the up most. +- */ +- List get coveringExpressionOffsets => _coveringExpressionOffsets; +- +- /** +- * The offsets of the expressions that cover the specified selection, from +- * the down most to the up most. +- */ +- void set coveringExpressionOffsets(List value) { +- this._coveringExpressionOffsets = value; +- } +- +- /** +- * The lengths of the expressions that cover the specified selection, from +- * the down most to the up most. +- */ +- List get coveringExpressionLengths => _coveringExpressionLengths; +- +- /** +- * The lengths of the expressions that cover the specified selection, from +- * the down most to the up most. +- */ +- void set coveringExpressionLengths(List value) { +- this._coveringExpressionLengths = value; +- } +- +- /** +- * The proposed names for the local variable. +- */ +- List get names => _names; +- +- /** +- * The proposed names for the local variable. +- */ +- void set names(List value) { +- assert(value != null); +- this._names = value; +- } +- +- /** +- * The offsets of the expressions that would be replaced by a reference to +- * the variable. +- */ +- List get offsets => _offsets; +- +- /** +- * The offsets of the expressions that would be replaced by a reference to +- * the variable. +- */ +- void set offsets(List value) { +- assert(value != null); +- this._offsets = value; +- } +- +- /** +- * The lengths of the expressions that would be replaced by a reference to +- * the variable. The lengths correspond to the offsets. In other words, for a +- * given expression, if the offset of that expression is offsets[i], then the +- * length of that expression is lengths[i]. +- */ +- List get lengths => _lengths; +- +- /** +- * The lengths of the expressions that would be replaced by a reference to +- * the variable. The lengths correspond to the offsets. In other words, for a +- * given expression, if the offset of that expression is offsets[i], then the +- * length of that expression is lengths[i]. +- */ +- void set lengths(List value) { +- assert(value != null); +- this._lengths = value; +- } +- +- ExtractLocalVariableFeedback( +- List names, List offsets, List lengths, +- {List coveringExpressionOffsets, +- List coveringExpressionLengths}) { +- this.coveringExpressionOffsets = coveringExpressionOffsets; +- this.coveringExpressionLengths = coveringExpressionLengths; +- this.names = names; +- this.offsets = offsets; +- this.lengths = lengths; +- } +- +- factory ExtractLocalVariableFeedback.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List coveringExpressionOffsets; +- if (json.containsKey("coveringExpressionOffsets")) { +- coveringExpressionOffsets = jsonDecoder.decodeList( +- jsonPath + ".coveringExpressionOffsets", +- json["coveringExpressionOffsets"], +- jsonDecoder.decodeInt); +- } +- List coveringExpressionLengths; +- if (json.containsKey("coveringExpressionLengths")) { +- coveringExpressionLengths = jsonDecoder.decodeList( +- jsonPath + ".coveringExpressionLengths", +- json["coveringExpressionLengths"], +- jsonDecoder.decodeInt); +- } +- List names; +- if (json.containsKey("names")) { +- names = jsonDecoder.decodeList( +- jsonPath + ".names", json["names"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "names"); +- } +- List offsets; +- if (json.containsKey("offsets")) { +- offsets = jsonDecoder.decodeList( +- jsonPath + ".offsets", json["offsets"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offsets"); +- } +- List lengths; +- if (json.containsKey("lengths")) { +- lengths = jsonDecoder.decodeList( +- jsonPath + ".lengths", json["lengths"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "lengths"); +- } +- return new ExtractLocalVariableFeedback(names, offsets, lengths, +- coveringExpressionOffsets: coveringExpressionOffsets, +- coveringExpressionLengths: coveringExpressionLengths); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "extractLocalVariable feedback", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (coveringExpressionOffsets != null) { +- result["coveringExpressionOffsets"] = coveringExpressionOffsets; +- } +- if (coveringExpressionLengths != null) { +- result["coveringExpressionLengths"] = coveringExpressionLengths; +- } +- result["names"] = names; +- result["offsets"] = offsets; +- result["lengths"] = lengths; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExtractLocalVariableFeedback) { +- return listEqual(coveringExpressionOffsets, +- other.coveringExpressionOffsets, (int a, int b) => a == b) && +- listEqual(coveringExpressionLengths, other.coveringExpressionLengths, +- (int a, int b) => a == b) && +- listEqual(names, other.names, (String a, String b) => a == b) && +- listEqual(offsets, other.offsets, (int a, int b) => a == b) && +- listEqual(lengths, other.lengths, (int a, int b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, coveringExpressionOffsets.hashCode); +- hash = JenkinsSmiHash.combine(hash, coveringExpressionLengths.hashCode); +- hash = JenkinsSmiHash.combine(hash, names.hashCode); +- hash = JenkinsSmiHash.combine(hash, offsets.hashCode); +- hash = JenkinsSmiHash.combine(hash, lengths.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * extractLocalVariable options +- * +- * { +- * "name": String +- * "extractAll": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExtractLocalVariableOptions extends RefactoringOptions { +- String _name; +- +- bool _extractAll; +- +- /** +- * The name that the local variable should be given. +- */ +- String get name => _name; +- +- /** +- * The name that the local variable should be given. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- /** +- * True if all occurrences of the expression within the scope in which the +- * variable will be defined should be replaced by a reference to the local +- * variable. The expression used to initiate the refactoring will always be +- * replaced. +- */ +- bool get extractAll => _extractAll; +- +- /** +- * True if all occurrences of the expression within the scope in which the +- * variable will be defined should be replaced by a reference to the local +- * variable. The expression used to initiate the refactoring will always be +- * replaced. +- */ +- void set extractAll(bool value) { +- assert(value != null); +- this._extractAll = value; +- } +- +- ExtractLocalVariableOptions(String name, bool extractAll) { +- this.name = name; +- this.extractAll = extractAll; +- } +- +- factory ExtractLocalVariableOptions.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- bool extractAll; +- if (json.containsKey("extractAll")) { +- extractAll = jsonDecoder.decodeBool( +- jsonPath + ".extractAll", json["extractAll"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "extractAll"); +- } +- return new ExtractLocalVariableOptions(name, extractAll); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "extractLocalVariable options", json); +- } +- } +- +- factory ExtractLocalVariableOptions.fromRefactoringParams( +- EditGetRefactoringParams refactoringParams, Request request) { +- return new ExtractLocalVariableOptions.fromJson( +- new RequestDecoder(request), "options", refactoringParams.options); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["name"] = name; +- result["extractAll"] = extractAll; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExtractLocalVariableOptions) { +- return name == other.name && extractAll == other.extractAll; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- hash = JenkinsSmiHash.combine(hash, extractAll.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * extractMethod feedback +- * +- * { +- * "offset": int +- * "length": int +- * "returnType": String +- * "names": List +- * "canCreateGetter": bool +- * "parameters": List +- * "offsets": List +- * "lengths": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExtractMethodFeedback extends RefactoringFeedback { +- int _offset; +- +- int _length; +- +- String _returnType; +- +- List _names; +- +- bool _canCreateGetter; +- +- List _parameters; +- +- List _offsets; +- +- List _lengths; +- +- /** +- * The offset to the beginning of the expression or statements that will be +- * extracted. +- */ +- int get offset => _offset; +- +- /** +- * The offset to the beginning of the expression or statements that will be +- * extracted. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the expression or statements that will be extracted. +- */ +- int get length => _length; +- +- /** +- * The length of the expression or statements that will be extracted. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * The proposed return type for the method. If the returned element does not +- * have a declared return type, this field will contain an empty string. +- */ +- String get returnType => _returnType; +- +- /** +- * The proposed return type for the method. If the returned element does not +- * have a declared return type, this field will contain an empty string. +- */ +- void set returnType(String value) { +- assert(value != null); +- this._returnType = value; +- } +- +- /** +- * The proposed names for the method. +- */ +- List get names => _names; +- +- /** +- * The proposed names for the method. +- */ +- void set names(List value) { +- assert(value != null); +- this._names = value; +- } +- +- /** +- * True if a getter could be created rather than a method. +- */ +- bool get canCreateGetter => _canCreateGetter; +- +- /** +- * True if a getter could be created rather than a method. +- */ +- void set canCreateGetter(bool value) { +- assert(value != null); +- this._canCreateGetter = value; +- } +- +- /** +- * The proposed parameters for the method. +- */ +- List get parameters => _parameters; +- +- /** +- * The proposed parameters for the method. +- */ +- void set parameters(List value) { +- assert(value != null); +- this._parameters = value; +- } +- +- /** +- * The offsets of the expressions or statements that would be replaced by an +- * invocation of the method. +- */ +- List get offsets => _offsets; +- +- /** +- * The offsets of the expressions or statements that would be replaced by an +- * invocation of the method. +- */ +- void set offsets(List value) { +- assert(value != null); +- this._offsets = value; +- } +- +- /** +- * The lengths of the expressions or statements that would be replaced by an +- * invocation of the method. The lengths correspond to the offsets. In other +- * words, for a given expression (or block of statements), if the offset of +- * that expression is offsets[i], then the length of that expression is +- * lengths[i]. +- */ +- List get lengths => _lengths; +- +- /** +- * The lengths of the expressions or statements that would be replaced by an +- * invocation of the method. The lengths correspond to the offsets. In other +- * words, for a given expression (or block of statements), if the offset of +- * that expression is offsets[i], then the length of that expression is +- * lengths[i]. +- */ +- void set lengths(List value) { +- assert(value != null); +- this._lengths = value; +- } +- +- ExtractMethodFeedback( +- int offset, +- int length, +- String returnType, +- List names, +- bool canCreateGetter, +- List parameters, +- List offsets, +- List lengths) { +- this.offset = offset; +- this.length = length; +- this.returnType = returnType; +- this.names = names; +- this.canCreateGetter = canCreateGetter; +- this.parameters = parameters; +- this.offsets = offsets; +- this.lengths = lengths; +- } +- +- factory ExtractMethodFeedback.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- String returnType; +- if (json.containsKey("returnType")) { +- returnType = jsonDecoder.decodeString( +- jsonPath + ".returnType", json["returnType"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "returnType"); +- } +- List names; +- if (json.containsKey("names")) { +- names = jsonDecoder.decodeList( +- jsonPath + ".names", json["names"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "names"); +- } +- bool canCreateGetter; +- if (json.containsKey("canCreateGetter")) { +- canCreateGetter = jsonDecoder.decodeBool( +- jsonPath + ".canCreateGetter", json["canCreateGetter"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "canCreateGetter"); +- } +- List parameters; +- if (json.containsKey("parameters")) { +- parameters = jsonDecoder.decodeList( +- jsonPath + ".parameters", +- json["parameters"], +- (String jsonPath, Object json) => +- new RefactoringMethodParameter.fromJson( +- jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "parameters"); +- } +- List offsets; +- if (json.containsKey("offsets")) { +- offsets = jsonDecoder.decodeList( +- jsonPath + ".offsets", json["offsets"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offsets"); +- } +- List lengths; +- if (json.containsKey("lengths")) { +- lengths = jsonDecoder.decodeList( +- jsonPath + ".lengths", json["lengths"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "lengths"); +- } +- return new ExtractMethodFeedback(offset, length, returnType, names, +- canCreateGetter, parameters, offsets, lengths); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "extractMethod feedback", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- result["returnType"] = returnType; +- result["names"] = names; +- result["canCreateGetter"] = canCreateGetter; +- result["parameters"] = parameters +- .map((RefactoringMethodParameter value) => value.toJson()) +- .toList(); +- result["offsets"] = offsets; +- result["lengths"] = lengths; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExtractMethodFeedback) { +- return offset == other.offset && +- length == other.length && +- returnType == other.returnType && +- listEqual(names, other.names, (String a, String b) => a == b) && +- canCreateGetter == other.canCreateGetter && +- listEqual( +- parameters, +- other.parameters, +- (RefactoringMethodParameter a, RefactoringMethodParameter b) => +- a == b) && +- listEqual(offsets, other.offsets, (int a, int b) => a == b) && +- listEqual(lengths, other.lengths, (int a, int b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, returnType.hashCode); +- hash = JenkinsSmiHash.combine(hash, names.hashCode); +- hash = JenkinsSmiHash.combine(hash, canCreateGetter.hashCode); +- hash = JenkinsSmiHash.combine(hash, parameters.hashCode); +- hash = JenkinsSmiHash.combine(hash, offsets.hashCode); +- hash = JenkinsSmiHash.combine(hash, lengths.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * extractMethod options +- * +- * { +- * "returnType": String +- * "createGetter": bool +- * "name": String +- * "parameters": List +- * "extractAll": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ExtractMethodOptions extends RefactoringOptions { +- String _returnType; +- +- bool _createGetter; +- +- String _name; +- +- List _parameters; +- +- bool _extractAll; +- +- /** +- * The return type that should be defined for the method. +- */ +- String get returnType => _returnType; +- +- /** +- * The return type that should be defined for the method. +- */ +- void set returnType(String value) { +- assert(value != null); +- this._returnType = value; +- } +- +- /** +- * True if a getter should be created rather than a method. It is an error if +- * this field is true and the list of parameters is non-empty. +- */ +- bool get createGetter => _createGetter; +- +- /** +- * True if a getter should be created rather than a method. It is an error if +- * this field is true and the list of parameters is non-empty. +- */ +- void set createGetter(bool value) { +- assert(value != null); +- this._createGetter = value; +- } +- +- /** +- * The name that the method should be given. +- */ +- String get name => _name; +- +- /** +- * The name that the method should be given. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- /** +- * The parameters that should be defined for the method. +- * +- * It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL +- * parameter. It is an error if a REQUIRED or POSITIONAL parameter follows a +- * NAMED parameter. +- * +- * - To change the order and/or update proposed parameters, add parameters +- * with the same identifiers as proposed. +- * - To add new parameters, omit their identifier. +- * - To remove some parameters, omit them in this list. +- */ +- List get parameters => _parameters; +- +- /** +- * The parameters that should be defined for the method. +- * +- * It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL +- * parameter. It is an error if a REQUIRED or POSITIONAL parameter follows a +- * NAMED parameter. +- * +- * - To change the order and/or update proposed parameters, add parameters +- * with the same identifiers as proposed. +- * - To add new parameters, omit their identifier. +- * - To remove some parameters, omit them in this list. +- */ +- void set parameters(List value) { +- assert(value != null); +- this._parameters = value; +- } +- +- /** +- * True if all occurrences of the expression or statements should be replaced +- * by an invocation of the method. The expression or statements used to +- * initiate the refactoring will always be replaced. +- */ +- bool get extractAll => _extractAll; +- +- /** +- * True if all occurrences of the expression or statements should be replaced +- * by an invocation of the method. The expression or statements used to +- * initiate the refactoring will always be replaced. +- */ +- void set extractAll(bool value) { +- assert(value != null); +- this._extractAll = value; +- } +- +- ExtractMethodOptions(String returnType, bool createGetter, String name, +- List parameters, bool extractAll) { +- this.returnType = returnType; +- this.createGetter = createGetter; +- this.name = name; +- this.parameters = parameters; +- this.extractAll = extractAll; +- } +- +- factory ExtractMethodOptions.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String returnType; +- if (json.containsKey("returnType")) { +- returnType = jsonDecoder.decodeString( +- jsonPath + ".returnType", json["returnType"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "returnType"); +- } +- bool createGetter; +- if (json.containsKey("createGetter")) { +- createGetter = jsonDecoder.decodeBool( +- jsonPath + ".createGetter", json["createGetter"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "createGetter"); +- } +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- List parameters; +- if (json.containsKey("parameters")) { +- parameters = jsonDecoder.decodeList( +- jsonPath + ".parameters", +- json["parameters"], +- (String jsonPath, Object json) => +- new RefactoringMethodParameter.fromJson( +- jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "parameters"); +- } +- bool extractAll; +- if (json.containsKey("extractAll")) { +- extractAll = jsonDecoder.decodeBool( +- jsonPath + ".extractAll", json["extractAll"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "extractAll"); +- } +- return new ExtractMethodOptions( +- returnType, createGetter, name, parameters, extractAll); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "extractMethod options", json); +- } +- } +- +- factory ExtractMethodOptions.fromRefactoringParams( +- EditGetRefactoringParams refactoringParams, Request request) { +- return new ExtractMethodOptions.fromJson( +- new RequestDecoder(request), "options", refactoringParams.options); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["returnType"] = returnType; +- result["createGetter"] = createGetter; +- result["name"] = name; +- result["parameters"] = parameters +- .map((RefactoringMethodParameter value) => value.toJson()) +- .toList(); +- result["extractAll"] = extractAll; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ExtractMethodOptions) { +- return returnType == other.returnType && +- createGetter == other.createGetter && +- name == other.name && +- listEqual( +- parameters, +- other.parameters, +- (RefactoringMethodParameter a, RefactoringMethodParameter b) => +- a == b) && +- extractAll == other.extractAll; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, returnType.hashCode); +- hash = JenkinsSmiHash.combine(hash, createGetter.hashCode); +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- hash = JenkinsSmiHash.combine(hash, parameters.hashCode); +- hash = JenkinsSmiHash.combine(hash, extractAll.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * FileKind +- * +- * enum { +- * LIBRARY +- * PART +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class FileKind implements Enum { +- static const FileKind LIBRARY = const FileKind._("LIBRARY"); +- +- static const FileKind PART = const FileKind._("PART"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [LIBRARY, PART]; +- +- @override +- final String name; +- +- const FileKind._(this.name); +- +- factory FileKind(String name) { +- switch (name) { +- case "LIBRARY": +- return LIBRARY; +- case "PART": +- return PART; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory FileKind.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new FileKind(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "FileKind", json); +- } +- +- @override +- String toString() => "FileKind.$name"; +- +- String toJson() => name; +-} +- +-/** +- * GeneralAnalysisService +- * +- * enum { +- * ANALYZED_FILES +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class GeneralAnalysisService implements Enum { +- static const GeneralAnalysisService ANALYZED_FILES = +- const GeneralAnalysisService._("ANALYZED_FILES"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = +- const [ANALYZED_FILES]; +- +- @override +- final String name; +- +- const GeneralAnalysisService._(this.name); +- +- factory GeneralAnalysisService(String name) { +- switch (name) { +- case "ANALYZED_FILES": +- return ANALYZED_FILES; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory GeneralAnalysisService.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new GeneralAnalysisService(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "GeneralAnalysisService", json); +- } +- +- @override +- String toString() => "GeneralAnalysisService.$name"; +- +- String toJson() => name; +-} +- +-/** +- * HoverInformation +- * +- * { +- * "offset": int +- * "length": int +- * "containingLibraryPath": optional String +- * "containingLibraryName": optional String +- * "containingClassDescription": optional String +- * "dartdoc": optional String +- * "elementDescription": optional String +- * "elementKind": optional String +- * "isDeprecated": optional bool +- * "parameter": optional String +- * "propagatedType": optional String +- * "staticType": optional String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class HoverInformation implements HasToJson { +- int _offset; +- +- int _length; +- +- String _containingLibraryPath; +- +- String _containingLibraryName; +- +- String _containingClassDescription; +- +- String _dartdoc; +- +- String _elementDescription; +- +- String _elementKind; +- +- bool _isDeprecated; +- +- String _parameter; +- +- String _propagatedType; +- +- String _staticType; +- +- /** +- * The offset of the range of characters that encompasses the cursor position +- * and has the same hover information as the cursor position. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the range of characters that encompasses the cursor position +- * and has the same hover information as the cursor position. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the range of characters that encompasses the cursor position +- * and has the same hover information as the cursor position. +- */ +- int get length => _length; +- +- /** +- * The length of the range of characters that encompasses the cursor position +- * and has the same hover information as the cursor position. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * The path to the defining compilation unit of the library in which the +- * referenced element is declared. This data is omitted if there is no +- * referenced element, or if the element is declared inside an HTML file. +- */ +- String get containingLibraryPath => _containingLibraryPath; +- +- /** +- * The path to the defining compilation unit of the library in which the +- * referenced element is declared. This data is omitted if there is no +- * referenced element, or if the element is declared inside an HTML file. +- */ +- void set containingLibraryPath(String value) { +- this._containingLibraryPath = value; +- } +- +- /** +- * The name of the library in which the referenced element is declared. This +- * data is omitted if there is no referenced element, or if the element is +- * declared inside an HTML file. +- */ +- String get containingLibraryName => _containingLibraryName; +- +- /** +- * The name of the library in which the referenced element is declared. This +- * data is omitted if there is no referenced element, or if the element is +- * declared inside an HTML file. +- */ +- void set containingLibraryName(String value) { +- this._containingLibraryName = value; +- } +- +- /** +- * A human-readable description of the class declaring the element being +- * referenced. This data is omitted if there is no referenced element, or if +- * the element is not a class member. +- */ +- String get containingClassDescription => _containingClassDescription; +- +- /** +- * A human-readable description of the class declaring the element being +- * referenced. This data is omitted if there is no referenced element, or if +- * the element is not a class member. +- */ +- void set containingClassDescription(String value) { +- this._containingClassDescription = value; +- } +- +- /** +- * The dartdoc associated with the referenced element. Other than the removal +- * of the comment delimiters, including leading asterisks in the case of a +- * block comment, the dartdoc is unprocessed markdown. This data is omitted +- * if there is no referenced element, or if the element has no dartdoc. +- */ +- String get dartdoc => _dartdoc; +- +- /** +- * The dartdoc associated with the referenced element. Other than the removal +- * of the comment delimiters, including leading asterisks in the case of a +- * block comment, the dartdoc is unprocessed markdown. This data is omitted +- * if there is no referenced element, or if the element has no dartdoc. +- */ +- void set dartdoc(String value) { +- this._dartdoc = value; +- } +- +- /** +- * A human-readable description of the element being referenced. This data is +- * omitted if there is no referenced element. +- */ +- String get elementDescription => _elementDescription; +- +- /** +- * A human-readable description of the element being referenced. This data is +- * omitted if there is no referenced element. +- */ +- void set elementDescription(String value) { +- this._elementDescription = value; +- } +- +- /** +- * A human-readable description of the kind of element being referenced (such +- * as "class" or "function type alias"). This data is omitted if there is no +- * referenced element. +- */ +- String get elementKind => _elementKind; +- +- /** +- * A human-readable description of the kind of element being referenced (such +- * as "class" or "function type alias"). This data is omitted if there is no +- * referenced element. +- */ +- void set elementKind(String value) { +- this._elementKind = value; +- } +- +- /** +- * True if the referenced element is deprecated. +- */ +- bool get isDeprecated => _isDeprecated; +- +- /** +- * True if the referenced element is deprecated. +- */ +- void set isDeprecated(bool value) { +- this._isDeprecated = value; +- } +- +- /** +- * A human-readable description of the parameter corresponding to the +- * expression being hovered over. This data is omitted if the location is not +- * in an argument to a function. +- */ +- String get parameter => _parameter; +- +- /** +- * A human-readable description of the parameter corresponding to the +- * expression being hovered over. This data is omitted if the location is not +- * in an argument to a function. +- */ +- void set parameter(String value) { +- this._parameter = value; +- } +- +- /** +- * The name of the propagated type of the expression. This data is omitted if +- * the location does not correspond to an expression or if there is no +- * propagated type information. +- */ +- String get propagatedType => _propagatedType; +- +- /** +- * The name of the propagated type of the expression. This data is omitted if +- * the location does not correspond to an expression or if there is no +- * propagated type information. +- */ +- void set propagatedType(String value) { +- this._propagatedType = value; +- } +- +- /** +- * The name of the static type of the expression. This data is omitted if the +- * location does not correspond to an expression. +- */ +- String get staticType => _staticType; +- +- /** +- * The name of the static type of the expression. This data is omitted if the +- * location does not correspond to an expression. +- */ +- void set staticType(String value) { +- this._staticType = value; +- } +- +- HoverInformation(int offset, int length, +- {String containingLibraryPath, +- String containingLibraryName, +- String containingClassDescription, +- String dartdoc, +- String elementDescription, +- String elementKind, +- bool isDeprecated, +- String parameter, +- String propagatedType, +- String staticType}) { +- this.offset = offset; +- this.length = length; +- this.containingLibraryPath = containingLibraryPath; +- this.containingLibraryName = containingLibraryName; +- this.containingClassDescription = containingClassDescription; +- this.dartdoc = dartdoc; +- this.elementDescription = elementDescription; +- this.elementKind = elementKind; +- this.isDeprecated = isDeprecated; +- this.parameter = parameter; +- this.propagatedType = propagatedType; +- this.staticType = staticType; +- } +- +- factory HoverInformation.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- String containingLibraryPath; +- if (json.containsKey("containingLibraryPath")) { +- containingLibraryPath = jsonDecoder.decodeString( +- jsonPath + ".containingLibraryPath", json["containingLibraryPath"]); +- } +- String containingLibraryName; +- if (json.containsKey("containingLibraryName")) { +- containingLibraryName = jsonDecoder.decodeString( +- jsonPath + ".containingLibraryName", json["containingLibraryName"]); +- } +- String containingClassDescription; +- if (json.containsKey("containingClassDescription")) { +- containingClassDescription = jsonDecoder.decodeString( +- jsonPath + ".containingClassDescription", +- json["containingClassDescription"]); +- } +- String dartdoc; +- if (json.containsKey("dartdoc")) { +- dartdoc = +- jsonDecoder.decodeString(jsonPath + ".dartdoc", json["dartdoc"]); +- } +- String elementDescription; +- if (json.containsKey("elementDescription")) { +- elementDescription = jsonDecoder.decodeString( +- jsonPath + ".elementDescription", json["elementDescription"]); +- } +- String elementKind; +- if (json.containsKey("elementKind")) { +- elementKind = jsonDecoder.decodeString( +- jsonPath + ".elementKind", json["elementKind"]); +- } +- bool isDeprecated; +- if (json.containsKey("isDeprecated")) { +- isDeprecated = jsonDecoder.decodeBool( +- jsonPath + ".isDeprecated", json["isDeprecated"]); +- } +- String parameter; +- if (json.containsKey("parameter")) { +- parameter = jsonDecoder.decodeString( +- jsonPath + ".parameter", json["parameter"]); +- } +- String propagatedType; +- if (json.containsKey("propagatedType")) { +- propagatedType = jsonDecoder.decodeString( +- jsonPath + ".propagatedType", json["propagatedType"]); +- } +- String staticType; +- if (json.containsKey("staticType")) { +- staticType = jsonDecoder.decodeString( +- jsonPath + ".staticType", json["staticType"]); +- } +- return new HoverInformation(offset, length, +- containingLibraryPath: containingLibraryPath, +- containingLibraryName: containingLibraryName, +- containingClassDescription: containingClassDescription, +- dartdoc: dartdoc, +- elementDescription: elementDescription, +- elementKind: elementKind, +- isDeprecated: isDeprecated, +- parameter: parameter, +- propagatedType: propagatedType, +- staticType: staticType); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "HoverInformation", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- if (containingLibraryPath != null) { +- result["containingLibraryPath"] = containingLibraryPath; +- } +- if (containingLibraryName != null) { +- result["containingLibraryName"] = containingLibraryName; +- } +- if (containingClassDescription != null) { +- result["containingClassDescription"] = containingClassDescription; +- } +- if (dartdoc != null) { +- result["dartdoc"] = dartdoc; +- } +- if (elementDescription != null) { +- result["elementDescription"] = elementDescription; +- } +- if (elementKind != null) { +- result["elementKind"] = elementKind; +- } +- if (isDeprecated != null) { +- result["isDeprecated"] = isDeprecated; +- } +- if (parameter != null) { +- result["parameter"] = parameter; +- } +- if (propagatedType != null) { +- result["propagatedType"] = propagatedType; +- } +- if (staticType != null) { +- result["staticType"] = staticType; +- } +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is HoverInformation) { +- return offset == other.offset && +- length == other.length && +- containingLibraryPath == other.containingLibraryPath && +- containingLibraryName == other.containingLibraryName && +- containingClassDescription == other.containingClassDescription && +- dartdoc == other.dartdoc && +- elementDescription == other.elementDescription && +- elementKind == other.elementKind && +- isDeprecated == other.isDeprecated && +- parameter == other.parameter && +- propagatedType == other.propagatedType && +- staticType == other.staticType; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, containingLibraryPath.hashCode); +- hash = JenkinsSmiHash.combine(hash, containingLibraryName.hashCode); +- hash = JenkinsSmiHash.combine(hash, containingClassDescription.hashCode); +- hash = JenkinsSmiHash.combine(hash, dartdoc.hashCode); +- hash = JenkinsSmiHash.combine(hash, elementDescription.hashCode); +- hash = JenkinsSmiHash.combine(hash, elementKind.hashCode); +- hash = JenkinsSmiHash.combine(hash, isDeprecated.hashCode); +- hash = JenkinsSmiHash.combine(hash, parameter.hashCode); +- hash = JenkinsSmiHash.combine(hash, propagatedType.hashCode); +- hash = JenkinsSmiHash.combine(hash, staticType.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ImplementedClass +- * +- * { +- * "offset": int +- * "length": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ImplementedClass implements HasToJson { +- int _offset; +- +- int _length; +- +- /** +- * The offset of the name of the implemented class. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the name of the implemented class. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the name of the implemented class. +- */ +- int get length => _length; +- +- /** +- * The length of the name of the implemented class. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- ImplementedClass(int offset, int length) { +- this.offset = offset; +- this.length = length; +- } +- +- factory ImplementedClass.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- return new ImplementedClass(offset, length); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "ImplementedClass", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ImplementedClass) { +- return offset == other.offset && length == other.length; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ImplementedMember +- * +- * { +- * "offset": int +- * "length": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ImplementedMember implements HasToJson { +- int _offset; +- +- int _length; +- +- /** +- * The offset of the name of the implemented member. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the name of the implemented member. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the name of the implemented member. +- */ +- int get length => _length; +- +- /** +- * The length of the name of the implemented member. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- ImplementedMember(int offset, int length) { +- this.offset = offset; +- this.length = length; +- } +- +- factory ImplementedMember.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- return new ImplementedMember(offset, length); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "ImplementedMember", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ImplementedMember) { +- return offset == other.offset && length == other.length; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ImportedElements +- * +- * { +- * "path": FilePath +- * "prefix": String +- * "elements": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ImportedElements implements HasToJson { +- String _path; +- +- String _prefix; +- +- List _elements; +- +- /** +- * The absolute and normalized path of the file containing the library. +- */ +- String get path => _path; +- +- /** +- * The absolute and normalized path of the file containing the library. +- */ +- void set path(String value) { +- assert(value != null); +- this._path = value; +- } +- +- /** +- * The prefix that was used when importing the library into the original +- * source. +- */ +- String get prefix => _prefix; +- +- /** +- * The prefix that was used when importing the library into the original +- * source. +- */ +- void set prefix(String value) { +- assert(value != null); +- this._prefix = value; +- } +- +- /** +- * The names of the elements imported from the library. +- */ +- List get elements => _elements; +- +- /** +- * The names of the elements imported from the library. +- */ +- void set elements(List value) { +- assert(value != null); +- this._elements = value; +- } +- +- ImportedElements(String path, String prefix, List elements) { +- this.path = path; +- this.prefix = prefix; +- this.elements = elements; +- } +- +- factory ImportedElements.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String path; +- if (json.containsKey("path")) { +- path = jsonDecoder.decodeString(jsonPath + ".path", json["path"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "path"); +- } +- String prefix; +- if (json.containsKey("prefix")) { +- prefix = jsonDecoder.decodeString(jsonPath + ".prefix", json["prefix"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "prefix"); +- } +- List elements; +- if (json.containsKey("elements")) { +- elements = jsonDecoder.decodeList( +- jsonPath + ".elements", json["elements"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "elements"); +- } +- return new ImportedElements(path, prefix, elements); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "ImportedElements", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["path"] = path; +- result["prefix"] = prefix; +- result["elements"] = elements; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ImportedElements) { +- return path == other.path && +- prefix == other.prefix && +- listEqual(elements, other.elements, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, path.hashCode); +- hash = JenkinsSmiHash.combine(hash, prefix.hashCode); +- hash = JenkinsSmiHash.combine(hash, elements.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * inlineLocalVariable feedback +- * +- * { +- * "name": String +- * "occurrences": int +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class InlineLocalVariableFeedback extends RefactoringFeedback { +- String _name; +- +- int _occurrences; +- +- /** +- * The name of the variable being inlined. +- */ +- String get name => _name; +- +- /** +- * The name of the variable being inlined. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- /** +- * The number of times the variable occurs. +- */ +- int get occurrences => _occurrences; +- +- /** +- * The number of times the variable occurs. +- */ +- void set occurrences(int value) { +- assert(value != null); +- this._occurrences = value; +- } +- +- InlineLocalVariableFeedback(String name, int occurrences) { +- this.name = name; +- this.occurrences = occurrences; +- } +- +- factory InlineLocalVariableFeedback.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- int occurrences; +- if (json.containsKey("occurrences")) { +- occurrences = jsonDecoder.decodeInt( +- jsonPath + ".occurrences", json["occurrences"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "occurrences"); +- } +- return new InlineLocalVariableFeedback(name, occurrences); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "inlineLocalVariable feedback", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["name"] = name; +- result["occurrences"] = occurrences; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is InlineLocalVariableFeedback) { +- return name == other.name && occurrences == other.occurrences; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- hash = JenkinsSmiHash.combine(hash, occurrences.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * inlineLocalVariable options +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class InlineLocalVariableOptions extends RefactoringOptions +- implements HasToJson { +- @override +- bool operator ==(other) { +- if (other is InlineLocalVariableOptions) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 540364977; +- } +-} +- +-/** +- * inlineMethod feedback +- * +- * { +- * "className": optional String +- * "methodName": String +- * "isDeclaration": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class InlineMethodFeedback extends RefactoringFeedback { +- String _className; +- +- String _methodName; +- +- bool _isDeclaration; +- +- /** +- * The name of the class enclosing the method being inlined. If not a class +- * member is being inlined, this field will be absent. +- */ +- String get className => _className; +- +- /** +- * The name of the class enclosing the method being inlined. If not a class +- * member is being inlined, this field will be absent. +- */ +- void set className(String value) { +- this._className = value; +- } +- +- /** +- * The name of the method (or function) being inlined. +- */ +- String get methodName => _methodName; +- +- /** +- * The name of the method (or function) being inlined. +- */ +- void set methodName(String value) { +- assert(value != null); +- this._methodName = value; +- } +- +- /** +- * True if the declaration of the method is selected. So all references +- * should be inlined. +- */ +- bool get isDeclaration => _isDeclaration; +- +- /** +- * True if the declaration of the method is selected. So all references +- * should be inlined. +- */ +- void set isDeclaration(bool value) { +- assert(value != null); +- this._isDeclaration = value; +- } +- +- InlineMethodFeedback(String methodName, bool isDeclaration, +- {String className}) { +- this.className = className; +- this.methodName = methodName; +- this.isDeclaration = isDeclaration; +- } +- +- factory InlineMethodFeedback.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String className; +- if (json.containsKey("className")) { +- className = jsonDecoder.decodeString( +- jsonPath + ".className", json["className"]); +- } +- String methodName; +- if (json.containsKey("methodName")) { +- methodName = jsonDecoder.decodeString( +- jsonPath + ".methodName", json["methodName"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "methodName"); +- } +- bool isDeclaration; +- if (json.containsKey("isDeclaration")) { +- isDeclaration = jsonDecoder.decodeBool( +- jsonPath + ".isDeclaration", json["isDeclaration"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isDeclaration"); +- } +- return new InlineMethodFeedback(methodName, isDeclaration, +- className: className); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "inlineMethod feedback", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (className != null) { +- result["className"] = className; +- } +- result["methodName"] = methodName; +- result["isDeclaration"] = isDeclaration; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is InlineMethodFeedback) { +- return className == other.className && +- methodName == other.methodName && +- isDeclaration == other.isDeclaration; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, className.hashCode); +- hash = JenkinsSmiHash.combine(hash, methodName.hashCode); +- hash = JenkinsSmiHash.combine(hash, isDeclaration.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * inlineMethod options +- * +- * { +- * "deleteSource": bool +- * "inlineAll": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class InlineMethodOptions extends RefactoringOptions { +- bool _deleteSource; +- +- bool _inlineAll; +- +- /** +- * True if the method being inlined should be removed. It is an error if this +- * field is true and inlineAll is false. +- */ +- bool get deleteSource => _deleteSource; +- +- /** +- * True if the method being inlined should be removed. It is an error if this +- * field is true and inlineAll is false. +- */ +- void set deleteSource(bool value) { +- assert(value != null); +- this._deleteSource = value; +- } +- +- /** +- * True if all invocations of the method should be inlined, or false if only +- * the invocation site used to create this refactoring should be inlined. +- */ +- bool get inlineAll => _inlineAll; +- +- /** +- * True if all invocations of the method should be inlined, or false if only +- * the invocation site used to create this refactoring should be inlined. +- */ +- void set inlineAll(bool value) { +- assert(value != null); +- this._inlineAll = value; +- } +- +- InlineMethodOptions(bool deleteSource, bool inlineAll) { +- this.deleteSource = deleteSource; +- this.inlineAll = inlineAll; +- } +- +- factory InlineMethodOptions.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool deleteSource; +- if (json.containsKey("deleteSource")) { +- deleteSource = jsonDecoder.decodeBool( +- jsonPath + ".deleteSource", json["deleteSource"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "deleteSource"); +- } +- bool inlineAll; +- if (json.containsKey("inlineAll")) { +- inlineAll = +- jsonDecoder.decodeBool(jsonPath + ".inlineAll", json["inlineAll"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "inlineAll"); +- } +- return new InlineMethodOptions(deleteSource, inlineAll); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "inlineMethod options", json); +- } +- } +- +- factory InlineMethodOptions.fromRefactoringParams( +- EditGetRefactoringParams refactoringParams, Request request) { +- return new InlineMethodOptions.fromJson( +- new RequestDecoder(request), "options", refactoringParams.options); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["deleteSource"] = deleteSource; +- result["inlineAll"] = inlineAll; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is InlineMethodOptions) { +- return deleteSource == other.deleteSource && inlineAll == other.inlineAll; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, deleteSource.hashCode); +- hash = JenkinsSmiHash.combine(hash, inlineAll.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * kythe.getKytheEntries params +- * +- * { +- * "file": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class KytheGetKytheEntriesParams implements RequestParams { +- String _file; +- +- /** +- * The file containing the code for which the Kythe Entry objects are being +- * requested. +- */ +- String get file => _file; +- +- /** +- * The file containing the code for which the Kythe Entry objects are being +- * requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- KytheGetKytheEntriesParams(String file) { +- this.file = file; +- } +- +- factory KytheGetKytheEntriesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- return new KytheGetKytheEntriesParams(file); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "kythe.getKytheEntries params", json); +- } +- } +- +- factory KytheGetKytheEntriesParams.fromRequest(Request request) { +- return new KytheGetKytheEntriesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "kythe.getKytheEntries", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is KytheGetKytheEntriesParams) { +- return file == other.file; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * kythe.getKytheEntries result +- * +- * { +- * "entries": List +- * "files": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class KytheGetKytheEntriesResult implements ResponseResult { +- List _entries; +- +- List _files; +- +- /** +- * The list of KytheEntry objects for the queried file. +- */ +- List get entries => _entries; +- +- /** +- * The list of KytheEntry objects for the queried file. +- */ +- void set entries(List value) { +- assert(value != null); +- this._entries = value; +- } +- +- /** +- * The set of files paths that were required, but not in the file system, to +- * give a complete and accurate Kythe graph for the file. This could be due +- * to a referenced file that does not exist or generated files not being +- * generated or passed before the call to "getKytheEntries". +- */ +- List get files => _files; +- +- /** +- * The set of files paths that were required, but not in the file system, to +- * give a complete and accurate Kythe graph for the file. This could be due +- * to a referenced file that does not exist or generated files not being +- * generated or passed before the call to "getKytheEntries". +- */ +- void set files(List value) { +- assert(value != null); +- this._files = value; +- } +- +- KytheGetKytheEntriesResult(List entries, List files) { +- this.entries = entries; +- this.files = files; +- } +- +- factory KytheGetKytheEntriesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List entries; +- if (json.containsKey("entries")) { +- entries = jsonDecoder.decodeList( +- jsonPath + ".entries", +- json["entries"], +- (String jsonPath, Object json) => +- new KytheEntry.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "entries"); +- } +- List files; +- if (json.containsKey("files")) { +- files = jsonDecoder.decodeList( +- jsonPath + ".files", json["files"], jsonDecoder.decodeString); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "files"); +- } +- return new KytheGetKytheEntriesResult(entries, files); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "kythe.getKytheEntries result", json); +- } +- } +- +- factory KytheGetKytheEntriesResult.fromResponse(Response response) { +- return new KytheGetKytheEntriesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["entries"] = +- entries.map((KytheEntry value) => value.toJson()).toList(); +- result["files"] = files; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is KytheGetKytheEntriesResult) { +- return listEqual( +- entries, other.entries, (KytheEntry a, KytheEntry b) => a == b) && +- listEqual(files, other.files, (String a, String b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, entries.hashCode); +- hash = JenkinsSmiHash.combine(hash, files.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * moveFile feedback +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class MoveFileFeedback extends RefactoringFeedback implements HasToJson { +- @override +- bool operator ==(other) { +- if (other is MoveFileFeedback) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 438975893; +- } +-} +- +-/** +- * moveFile options +- * +- * { +- * "newFile": FilePath +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class MoveFileOptions extends RefactoringOptions { +- String _newFile; +- +- /** +- * The new file path to which the given file is being moved. +- */ +- String get newFile => _newFile; +- +- /** +- * The new file path to which the given file is being moved. +- */ +- void set newFile(String value) { +- assert(value != null); +- this._newFile = value; +- } +- +- MoveFileOptions(String newFile) { +- this.newFile = newFile; +- } +- +- factory MoveFileOptions.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String newFile; +- if (json.containsKey("newFile")) { +- newFile = +- jsonDecoder.decodeString(jsonPath + ".newFile", json["newFile"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "newFile"); +- } +- return new MoveFileOptions(newFile); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "moveFile options", json); +- } +- } +- +- factory MoveFileOptions.fromRefactoringParams( +- EditGetRefactoringParams refactoringParams, Request request) { +- return new MoveFileOptions.fromJson( +- new RequestDecoder(request), "options", refactoringParams.options); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["newFile"] = newFile; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is MoveFileOptions) { +- return newFile == other.newFile; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, newFile.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * OverriddenMember +- * +- * { +- * "element": Element +- * "className": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class OverriddenMember implements HasToJson { +- Element _element; +- +- String _className; +- +- /** +- * The element that is being overridden. +- */ +- Element get element => _element; +- +- /** +- * The element that is being overridden. +- */ +- void set element(Element value) { +- assert(value != null); +- this._element = value; +- } +- +- /** +- * The name of the class in which the member is defined. +- */ +- String get className => _className; +- +- /** +- * The name of the class in which the member is defined. +- */ +- void set className(String value) { +- assert(value != null); +- this._className = value; +- } +- +- OverriddenMember(Element element, String className) { +- this.element = element; +- this.className = className; +- } +- +- factory OverriddenMember.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- Element element; +- if (json.containsKey("element")) { +- element = new Element.fromJson( +- jsonDecoder, jsonPath + ".element", json["element"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "element"); +- } +- String className; +- if (json.containsKey("className")) { +- className = jsonDecoder.decodeString( +- jsonPath + ".className", json["className"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "className"); +- } +- return new OverriddenMember(element, className); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "OverriddenMember", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["element"] = element.toJson(); +- result["className"] = className; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is OverriddenMember) { +- return element == other.element && className == other.className; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, element.hashCode); +- hash = JenkinsSmiHash.combine(hash, className.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * Override +- * +- * { +- * "offset": int +- * "length": int +- * "superclassMember": optional OverriddenMember +- * "interfaceMembers": optional List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class Override implements HasToJson { +- int _offset; +- +- int _length; +- +- OverriddenMember _superclassMember; +- +- List _interfaceMembers; +- +- /** +- * The offset of the name of the overriding member. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the name of the overriding member. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the name of the overriding member. +- */ +- int get length => _length; +- +- /** +- * The length of the name of the overriding member. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * The member inherited from a superclass that is overridden by the +- * overriding member. The field is omitted if there is no superclass member, +- * in which case there must be at least one interface member. +- */ +- OverriddenMember get superclassMember => _superclassMember; +- +- /** +- * The member inherited from a superclass that is overridden by the +- * overriding member. The field is omitted if there is no superclass member, +- * in which case there must be at least one interface member. +- */ +- void set superclassMember(OverriddenMember value) { +- this._superclassMember = value; +- } +- +- /** +- * The members inherited from interfaces that are overridden by the +- * overriding member. The field is omitted if there are no interface members, +- * in which case there must be a superclass member. +- */ +- List get interfaceMembers => _interfaceMembers; +- +- /** +- * The members inherited from interfaces that are overridden by the +- * overriding member. The field is omitted if there are no interface members, +- * in which case there must be a superclass member. +- */ +- void set interfaceMembers(List value) { +- this._interfaceMembers = value; +- } +- +- Override(int offset, int length, +- {OverriddenMember superclassMember, +- List interfaceMembers}) { +- this.offset = offset; +- this.length = length; +- this.superclassMember = superclassMember; +- this.interfaceMembers = interfaceMembers; +- } +- +- factory Override.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- OverriddenMember superclassMember; +- if (json.containsKey("superclassMember")) { +- superclassMember = new OverriddenMember.fromJson(jsonDecoder, +- jsonPath + ".superclassMember", json["superclassMember"]); +- } +- List interfaceMembers; +- if (json.containsKey("interfaceMembers")) { +- interfaceMembers = jsonDecoder.decodeList( +- jsonPath + ".interfaceMembers", +- json["interfaceMembers"], +- (String jsonPath, Object json) => +- new OverriddenMember.fromJson(jsonDecoder, jsonPath, json)); +- } +- return new Override(offset, length, +- superclassMember: superclassMember, +- interfaceMembers: interfaceMembers); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "Override", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- if (superclassMember != null) { +- result["superclassMember"] = superclassMember.toJson(); +- } +- if (interfaceMembers != null) { +- result["interfaceMembers"] = interfaceMembers +- .map((OverriddenMember value) => value.toJson()) +- .toList(); +- } +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is Override) { +- return offset == other.offset && +- length == other.length && +- superclassMember == other.superclassMember && +- listEqual(interfaceMembers, other.interfaceMembers, +- (OverriddenMember a, OverriddenMember b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, superclassMember.hashCode); +- hash = JenkinsSmiHash.combine(hash, interfaceMembers.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * PostfixTemplateDescriptor +- * +- * { +- * "name": String +- * "key": String +- * "example": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class PostfixTemplateDescriptor implements HasToJson { +- String _name; +- +- String _key; +- +- String _example; +- +- /** +- * The template name, shown in the UI. +- */ +- String get name => _name; +- +- /** +- * The template name, shown in the UI. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- /** +- * The unique template key, not shown in the UI. +- */ +- String get key => _key; +- +- /** +- * The unique template key, not shown in the UI. +- */ +- void set key(String value) { +- assert(value != null); +- this._key = value; +- } +- +- /** +- * A short example of the transformation performed when the template is +- * applied. +- */ +- String get example => _example; +- +- /** +- * A short example of the transformation performed when the template is +- * applied. +- */ +- void set example(String value) { +- assert(value != null); +- this._example = value; +- } +- +- PostfixTemplateDescriptor(String name, String key, String example) { +- this.name = name; +- this.key = key; +- this.example = example; +- } +- +- factory PostfixTemplateDescriptor.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- String key; +- if (json.containsKey("key")) { +- key = jsonDecoder.decodeString(jsonPath + ".key", json["key"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "key"); +- } +- String example; +- if (json.containsKey("example")) { +- example = +- jsonDecoder.decodeString(jsonPath + ".example", json["example"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "example"); +- } +- return new PostfixTemplateDescriptor(name, key, example); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "PostfixTemplateDescriptor", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["name"] = name; +- result["key"] = key; +- result["example"] = example; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is PostfixTemplateDescriptor) { +- return name == other.name && key == other.key && example == other.example; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- hash = JenkinsSmiHash.combine(hash, key.hashCode); +- hash = JenkinsSmiHash.combine(hash, example.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * PubStatus +- * +- * { +- * "isListingPackageDirs": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class PubStatus implements HasToJson { +- bool _isListingPackageDirs; +- +- /** +- * True if the server is currently running pub to produce a list of package +- * directories. +- */ +- bool get isListingPackageDirs => _isListingPackageDirs; +- +- /** +- * True if the server is currently running pub to produce a list of package +- * directories. +- */ +- void set isListingPackageDirs(bool value) { +- assert(value != null); +- this._isListingPackageDirs = value; +- } +- +- PubStatus(bool isListingPackageDirs) { +- this.isListingPackageDirs = isListingPackageDirs; +- } +- +- factory PubStatus.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool isListingPackageDirs; +- if (json.containsKey("isListingPackageDirs")) { +- isListingPackageDirs = jsonDecoder.decodeBool( +- jsonPath + ".isListingPackageDirs", json["isListingPackageDirs"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isListingPackageDirs"); +- } +- return new PubStatus(isListingPackageDirs); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "PubStatus", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["isListingPackageDirs"] = isListingPackageDirs; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is PubStatus) { +- return isListingPackageDirs == other.isListingPackageDirs; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, isListingPackageDirs.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * RefactoringFeedback +- * +- * { +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RefactoringFeedback implements HasToJson { +- RefactoringFeedback(); +- +- factory RefactoringFeedback.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json, Map responseJson) { +- return refactoringFeedbackFromJson( +- jsonDecoder, jsonPath, json, responseJson); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is RefactoringFeedback) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * RefactoringOptions +- * +- * { +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RefactoringOptions implements HasToJson { +- RefactoringOptions(); +- +- factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, String jsonPath, +- Object json, RefactoringKind kind) { +- return refactoringOptionsFromJson(jsonDecoder, jsonPath, json, kind); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is RefactoringOptions) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * rename feedback +- * +- * { +- * "offset": int +- * "length": int +- * "elementKindName": String +- * "oldName": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RenameFeedback extends RefactoringFeedback { +- int _offset; +- +- int _length; +- +- String _elementKindName; +- +- String _oldName; +- +- /** +- * The offset to the beginning of the name selected to be renamed. +- */ +- int get offset => _offset; +- +- /** +- * The offset to the beginning of the name selected to be renamed. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * The length of the name selected to be renamed. +- */ +- int get length => _length; +- +- /** +- * The length of the name selected to be renamed. +- */ +- void set length(int value) { +- assert(value != null); +- this._length = value; +- } +- +- /** +- * The human-readable description of the kind of element being renamed (such +- * as "class" or "function type alias"). +- */ +- String get elementKindName => _elementKindName; +- +- /** +- * The human-readable description of the kind of element being renamed (such +- * as "class" or "function type alias"). +- */ +- void set elementKindName(String value) { +- assert(value != null); +- this._elementKindName = value; +- } +- +- /** +- * The old name of the element before the refactoring. +- */ +- String get oldName => _oldName; +- +- /** +- * The old name of the element before the refactoring. +- */ +- void set oldName(String value) { +- assert(value != null); +- this._oldName = value; +- } +- +- RenameFeedback( +- int offset, int length, String elementKindName, String oldName) { +- this.offset = offset; +- this.length = length; +- this.elementKindName = elementKindName; +- this.oldName = oldName; +- } +- +- factory RenameFeedback.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- int length; +- if (json.containsKey("length")) { +- length = jsonDecoder.decodeInt(jsonPath + ".length", json["length"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "length"); +- } +- String elementKindName; +- if (json.containsKey("elementKindName")) { +- elementKindName = jsonDecoder.decodeString( +- jsonPath + ".elementKindName", json["elementKindName"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "elementKindName"); +- } +- String oldName; +- if (json.containsKey("oldName")) { +- oldName = +- jsonDecoder.decodeString(jsonPath + ".oldName", json["oldName"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "oldName"); +- } +- return new RenameFeedback(offset, length, elementKindName, oldName); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "rename feedback", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["offset"] = offset; +- result["length"] = length; +- result["elementKindName"] = elementKindName; +- result["oldName"] = oldName; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is RenameFeedback) { +- return offset == other.offset && +- length == other.length && +- elementKindName == other.elementKindName && +- oldName == other.oldName; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, length.hashCode); +- hash = JenkinsSmiHash.combine(hash, elementKindName.hashCode); +- hash = JenkinsSmiHash.combine(hash, oldName.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * rename options +- * +- * { +- * "newName": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RenameOptions extends RefactoringOptions { +- String _newName; +- +- /** +- * The name that the element should have after the refactoring. +- */ +- String get newName => _newName; +- +- /** +- * The name that the element should have after the refactoring. +- */ +- void set newName(String value) { +- assert(value != null); +- this._newName = value; +- } +- +- RenameOptions(String newName) { +- this.newName = newName; +- } +- +- factory RenameOptions.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String newName; +- if (json.containsKey("newName")) { +- newName = +- jsonDecoder.decodeString(jsonPath + ".newName", json["newName"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "newName"); +- } +- return new RenameOptions(newName); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "rename options", json); +- } +- } +- +- factory RenameOptions.fromRefactoringParams( +- EditGetRefactoringParams refactoringParams, Request request) { +- return new RenameOptions.fromJson( +- new RequestDecoder(request), "options", refactoringParams.options); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["newName"] = newName; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is RenameOptions) { +- return newName == other.newName; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, newName.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * RequestError +- * +- * { +- * "code": RequestErrorCode +- * "message": String +- * "stackTrace": optional String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RequestError implements HasToJson { +- RequestErrorCode _code; +- +- String _message; +- +- String _stackTrace; +- +- /** +- * A code that uniquely identifies the error that occurred. +- */ +- RequestErrorCode get code => _code; +- +- /** +- * A code that uniquely identifies the error that occurred. +- */ +- void set code(RequestErrorCode value) { +- assert(value != null); +- this._code = value; +- } +- +- /** +- * A short description of the error. +- */ +- String get message => _message; +- +- /** +- * A short description of the error. +- */ +- void set message(String value) { +- assert(value != null); +- this._message = value; +- } +- +- /** +- * The stack trace associated with processing the request, used for debugging +- * the server. +- */ +- String get stackTrace => _stackTrace; +- +- /** +- * The stack trace associated with processing the request, used for debugging +- * the server. +- */ +- void set stackTrace(String value) { +- this._stackTrace = value; +- } +- +- RequestError(RequestErrorCode code, String message, {String stackTrace}) { +- this.code = code; +- this.message = message; +- this.stackTrace = stackTrace; +- } +- +- factory RequestError.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- RequestErrorCode code; +- if (json.containsKey("code")) { +- code = new RequestErrorCode.fromJson( +- jsonDecoder, jsonPath + ".code", json["code"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "code"); +- } +- String message; +- if (json.containsKey("message")) { +- message = +- jsonDecoder.decodeString(jsonPath + ".message", json["message"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "message"); +- } +- String stackTrace; +- if (json.containsKey("stackTrace")) { +- stackTrace = jsonDecoder.decodeString( +- jsonPath + ".stackTrace", json["stackTrace"]); +- } +- return new RequestError(code, message, stackTrace: stackTrace); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "RequestError", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["code"] = code.toJson(); +- result["message"] = message; +- if (stackTrace != null) { +- result["stackTrace"] = stackTrace; +- } +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is RequestError) { +- return code == other.code && +- message == other.message && +- stackTrace == other.stackTrace; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, code.hashCode); +- hash = JenkinsSmiHash.combine(hash, message.hashCode); +- hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * RequestErrorCode +- * +- * enum { +- * CONTENT_MODIFIED +- * DEBUG_PORT_COULD_NOT_BE_OPENED +- * FILE_NOT_ANALYZED +- * FORMAT_INVALID_FILE +- * FORMAT_WITH_ERRORS +- * GET_ERRORS_INVALID_FILE +- * GET_IMPORTED_ELEMENTS_INVALID_FILE +- * GET_KYTHE_ENTRIES_INVALID_FILE +- * GET_NAVIGATION_INVALID_FILE +- * GET_REACHABLE_SOURCES_INVALID_FILE +- * IMPORT_ELEMENTS_INVALID_FILE +- * INVALID_ANALYSIS_ROOT +- * INVALID_EXECUTION_CONTEXT +- * INVALID_FILE_PATH_FORMAT +- * INVALID_OVERLAY_CHANGE +- * INVALID_PARAMETER +- * INVALID_REQUEST +- * ORGANIZE_DIRECTIVES_ERROR +- * REFACTORING_REQUEST_CANCELLED +- * SERVER_ALREADY_STARTED +- * SERVER_ERROR +- * SORT_MEMBERS_INVALID_FILE +- * SORT_MEMBERS_PARSE_ERRORS +- * UNANALYZED_PRIORITY_FILES +- * UNKNOWN_REQUEST +- * UNKNOWN_SOURCE +- * UNSUPPORTED_FEATURE +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class RequestErrorCode implements Enum { +- /** +- * An "analysis.getErrors" or "analysis.getNavigation" request could not be +- * satisfied because the content of the file changed before the requested +- * results could be computed. +- */ +- static const RequestErrorCode CONTENT_MODIFIED = +- const RequestErrorCode._("CONTENT_MODIFIED"); +- +- /** +- * The server was unable to open a port for the diagnostic server. +- */ +- static const RequestErrorCode DEBUG_PORT_COULD_NOT_BE_OPENED = +- const RequestErrorCode._("DEBUG_PORT_COULD_NOT_BE_OPENED"); +- +- /** +- * A request specified a FilePath which does not match a file in an analysis +- * root, or the requested operation is not available for the file. +- */ +- static const RequestErrorCode FILE_NOT_ANALYZED = +- const RequestErrorCode._("FILE_NOT_ANALYZED"); +- +- /** +- * An "edit.format" request specified a FilePath which does not match a Dart +- * file in an analysis root. +- */ +- static const RequestErrorCode FORMAT_INVALID_FILE = +- const RequestErrorCode._("FORMAT_INVALID_FILE"); +- +- /** +- * An "edit.format" request specified a file that contains syntax errors. +- */ +- static const RequestErrorCode FORMAT_WITH_ERRORS = +- const RequestErrorCode._("FORMAT_WITH_ERRORS"); +- +- /** +- * An "analysis.getErrors" request specified a FilePath which does not match +- * a file currently subject to analysis. +- */ +- static const RequestErrorCode GET_ERRORS_INVALID_FILE = +- const RequestErrorCode._("GET_ERRORS_INVALID_FILE"); +- +- /** +- * An "analysis.getImportedElements" request specified a FilePath that does +- * not match a file currently subject to analysis. +- */ +- static const RequestErrorCode GET_IMPORTED_ELEMENTS_INVALID_FILE = +- const RequestErrorCode._("GET_IMPORTED_ELEMENTS_INVALID_FILE"); +- +- /** +- * An "analysis.getKytheEntries" request specified a FilePath that does not +- * match a file that is currently subject to analysis. +- */ +- static const RequestErrorCode GET_KYTHE_ENTRIES_INVALID_FILE = +- const RequestErrorCode._("GET_KYTHE_ENTRIES_INVALID_FILE"); +- +- /** +- * An "analysis.getNavigation" request specified a FilePath which does not +- * match a file currently subject to analysis. +- */ +- static const RequestErrorCode GET_NAVIGATION_INVALID_FILE = +- const RequestErrorCode._("GET_NAVIGATION_INVALID_FILE"); +- +- /** +- * An "analysis.getReachableSources" request specified a FilePath which does +- * not match a file currently subject to analysis. +- */ +- static const RequestErrorCode GET_REACHABLE_SOURCES_INVALID_FILE = +- const RequestErrorCode._("GET_REACHABLE_SOURCES_INVALID_FILE"); +- +- /** +- * An "edit.importElements" request specified a FilePath that does not match +- * a file currently subject to analysis. +- */ +- static const RequestErrorCode IMPORT_ELEMENTS_INVALID_FILE = +- const RequestErrorCode._("IMPORT_ELEMENTS_INVALID_FILE"); +- +- /** +- * A path passed as an argument to a request (such as analysis.reanalyze) is +- * required to be an analysis root, but isn't. +- */ +- static const RequestErrorCode INVALID_ANALYSIS_ROOT = +- const RequestErrorCode._("INVALID_ANALYSIS_ROOT"); +- +- /** +- * The context root used to create an execution context does not exist. +- */ +- static const RequestErrorCode INVALID_EXECUTION_CONTEXT = +- const RequestErrorCode._("INVALID_EXECUTION_CONTEXT"); +- +- /** +- * The format of the given file path is invalid, e.g. is not absolute and +- * normalized. +- */ +- static const RequestErrorCode INVALID_FILE_PATH_FORMAT = +- const RequestErrorCode._("INVALID_FILE_PATH_FORMAT"); +- +- /** +- * An "analysis.updateContent" request contained a ChangeContentOverlay +- * object which can't be applied, due to an edit having an offset or length +- * that is out of range. +- */ +- static const RequestErrorCode INVALID_OVERLAY_CHANGE = +- const RequestErrorCode._("INVALID_OVERLAY_CHANGE"); +- +- /** +- * One of the method parameters was invalid. +- */ +- static const RequestErrorCode INVALID_PARAMETER = +- const RequestErrorCode._("INVALID_PARAMETER"); +- +- /** +- * A malformed request was received. +- */ +- static const RequestErrorCode INVALID_REQUEST = +- const RequestErrorCode._("INVALID_REQUEST"); +- +- /** +- * An "edit.organizeDirectives" request specified a Dart file that cannot be +- * analyzed. The reason is described in the message. +- */ +- static const RequestErrorCode ORGANIZE_DIRECTIVES_ERROR = +- const RequestErrorCode._("ORGANIZE_DIRECTIVES_ERROR"); +- +- /** +- * Another refactoring request was received during processing of this one. +- */ +- static const RequestErrorCode REFACTORING_REQUEST_CANCELLED = +- const RequestErrorCode._("REFACTORING_REQUEST_CANCELLED"); +- +- /** +- * The analysis server has already been started (and hence won't accept new +- * connections). +- * +- * This error is included for future expansion; at present the analysis +- * server can only speak to one client at a time so this error will never +- * occur. +- */ +- static const RequestErrorCode SERVER_ALREADY_STARTED = +- const RequestErrorCode._("SERVER_ALREADY_STARTED"); +- +- /** +- * An internal error occurred in the analysis server. Also see the +- * server.error notification. +- */ +- static const RequestErrorCode SERVER_ERROR = +- const RequestErrorCode._("SERVER_ERROR"); +- +- /** +- * An "edit.sortMembers" request specified a FilePath which does not match a +- * Dart file in an analysis root. +- */ +- static const RequestErrorCode SORT_MEMBERS_INVALID_FILE = +- const RequestErrorCode._("SORT_MEMBERS_INVALID_FILE"); +- +- /** +- * An "edit.sortMembers" request specified a Dart file that has scan or parse +- * errors. +- */ +- static const RequestErrorCode SORT_MEMBERS_PARSE_ERRORS = +- const RequestErrorCode._("SORT_MEMBERS_PARSE_ERRORS"); +- +- /** +- * An "analysis.setPriorityFiles" request includes one or more files that are +- * not being analyzed. +- * +- * This is a legacy error; it will be removed before the API reaches version +- * 1.0. +- */ +- static const RequestErrorCode UNANALYZED_PRIORITY_FILES = +- const RequestErrorCode._("UNANALYZED_PRIORITY_FILES"); +- +- /** +- * A request was received which the analysis server does not recognize, or +- * cannot handle in its current configuration. +- */ +- static const RequestErrorCode UNKNOWN_REQUEST = +- const RequestErrorCode._("UNKNOWN_REQUEST"); +- +- /** +- * The analysis server was requested to perform an action on a source that +- * does not exist. +- */ +- static const RequestErrorCode UNKNOWN_SOURCE = +- const RequestErrorCode._("UNKNOWN_SOURCE"); +- +- /** +- * The analysis server was requested to perform an action which is not +- * supported. +- * +- * This is a legacy error; it will be removed before the API reaches version +- * 1.0. +- */ +- static const RequestErrorCode UNSUPPORTED_FEATURE = +- const RequestErrorCode._("UNSUPPORTED_FEATURE"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [ +- CONTENT_MODIFIED, +- DEBUG_PORT_COULD_NOT_BE_OPENED, +- FILE_NOT_ANALYZED, +- FORMAT_INVALID_FILE, +- FORMAT_WITH_ERRORS, +- GET_ERRORS_INVALID_FILE, +- GET_IMPORTED_ELEMENTS_INVALID_FILE, +- GET_KYTHE_ENTRIES_INVALID_FILE, +- GET_NAVIGATION_INVALID_FILE, +- GET_REACHABLE_SOURCES_INVALID_FILE, +- IMPORT_ELEMENTS_INVALID_FILE, +- INVALID_ANALYSIS_ROOT, +- INVALID_EXECUTION_CONTEXT, +- INVALID_FILE_PATH_FORMAT, +- INVALID_OVERLAY_CHANGE, +- INVALID_PARAMETER, +- INVALID_REQUEST, +- ORGANIZE_DIRECTIVES_ERROR, +- REFACTORING_REQUEST_CANCELLED, +- SERVER_ALREADY_STARTED, +- SERVER_ERROR, +- SORT_MEMBERS_INVALID_FILE, +- SORT_MEMBERS_PARSE_ERRORS, +- UNANALYZED_PRIORITY_FILES, +- UNKNOWN_REQUEST, +- UNKNOWN_SOURCE, +- UNSUPPORTED_FEATURE +- ]; +- +- @override +- final String name; +- +- const RequestErrorCode._(this.name); +- +- factory RequestErrorCode(String name) { +- switch (name) { +- case "CONTENT_MODIFIED": +- return CONTENT_MODIFIED; +- case "DEBUG_PORT_COULD_NOT_BE_OPENED": +- return DEBUG_PORT_COULD_NOT_BE_OPENED; +- case "FILE_NOT_ANALYZED": +- return FILE_NOT_ANALYZED; +- case "FORMAT_INVALID_FILE": +- return FORMAT_INVALID_FILE; +- case "FORMAT_WITH_ERRORS": +- return FORMAT_WITH_ERRORS; +- case "GET_ERRORS_INVALID_FILE": +- return GET_ERRORS_INVALID_FILE; +- case "GET_IMPORTED_ELEMENTS_INVALID_FILE": +- return GET_IMPORTED_ELEMENTS_INVALID_FILE; +- case "GET_KYTHE_ENTRIES_INVALID_FILE": +- return GET_KYTHE_ENTRIES_INVALID_FILE; +- case "GET_NAVIGATION_INVALID_FILE": +- return GET_NAVIGATION_INVALID_FILE; +- case "GET_REACHABLE_SOURCES_INVALID_FILE": +- return GET_REACHABLE_SOURCES_INVALID_FILE; +- case "IMPORT_ELEMENTS_INVALID_FILE": +- return IMPORT_ELEMENTS_INVALID_FILE; +- case "INVALID_ANALYSIS_ROOT": +- return INVALID_ANALYSIS_ROOT; +- case "INVALID_EXECUTION_CONTEXT": +- return INVALID_EXECUTION_CONTEXT; +- case "INVALID_FILE_PATH_FORMAT": +- return INVALID_FILE_PATH_FORMAT; +- case "INVALID_OVERLAY_CHANGE": +- return INVALID_OVERLAY_CHANGE; +- case "INVALID_PARAMETER": +- return INVALID_PARAMETER; +- case "INVALID_REQUEST": +- return INVALID_REQUEST; +- case "ORGANIZE_DIRECTIVES_ERROR": +- return ORGANIZE_DIRECTIVES_ERROR; +- case "REFACTORING_REQUEST_CANCELLED": +- return REFACTORING_REQUEST_CANCELLED; +- case "SERVER_ALREADY_STARTED": +- return SERVER_ALREADY_STARTED; +- case "SERVER_ERROR": +- return SERVER_ERROR; +- case "SORT_MEMBERS_INVALID_FILE": +- return SORT_MEMBERS_INVALID_FILE; +- case "SORT_MEMBERS_PARSE_ERRORS": +- return SORT_MEMBERS_PARSE_ERRORS; +- case "UNANALYZED_PRIORITY_FILES": +- return UNANALYZED_PRIORITY_FILES; +- case "UNKNOWN_REQUEST": +- return UNKNOWN_REQUEST; +- case "UNKNOWN_SOURCE": +- return UNKNOWN_SOURCE; +- case "UNSUPPORTED_FEATURE": +- return UNSUPPORTED_FEATURE; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory RequestErrorCode.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new RequestErrorCode(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "RequestErrorCode", json); +- } +- +- @override +- String toString() => "RequestErrorCode.$name"; +- +- String toJson() => name; +-} +- +-/** +- * search.findElementReferences params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "includePotential": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindElementReferencesParams implements RequestParams { +- String _file; +- +- int _offset; +- +- bool _includePotential; +- +- /** +- * The file containing the declaration of or reference to the element used to +- * define the search. +- */ +- String get file => _file; +- +- /** +- * The file containing the declaration of or reference to the element used to +- * define the search. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset within the file of the declaration of or reference to the +- * element. +- */ +- int get offset => _offset; +- +- /** +- * The offset within the file of the declaration of or reference to the +- * element. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * True if potential matches are to be included in the results. +- */ +- bool get includePotential => _includePotential; +- +- /** +- * True if potential matches are to be included in the results. +- */ +- void set includePotential(bool value) { +- assert(value != null); +- this._includePotential = value; +- } +- +- SearchFindElementReferencesParams( +- String file, int offset, bool includePotential) { +- this.file = file; +- this.offset = offset; +- this.includePotential = includePotential; +- } +- +- factory SearchFindElementReferencesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- bool includePotential; +- if (json.containsKey("includePotential")) { +- includePotential = jsonDecoder.decodeBool( +- jsonPath + ".includePotential", json["includePotential"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "includePotential"); +- } +- return new SearchFindElementReferencesParams( +- file, offset, includePotential); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findElementReferences params", json); +- } +- } +- +- factory SearchFindElementReferencesParams.fromRequest(Request request) { +- return new SearchFindElementReferencesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- result["includePotential"] = includePotential; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "search.findElementReferences", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindElementReferencesParams) { +- return file == other.file && +- offset == other.offset && +- includePotential == other.includePotential; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, includePotential.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findElementReferences result +- * +- * { +- * "id": optional SearchId +- * "element": optional Element +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindElementReferencesResult implements ResponseResult { +- String _id; +- +- Element _element; +- +- /** +- * The identifier used to associate results with this search request. +- * +- * If no element was found at the given location, this field will be absent, +- * and no results will be reported via the search.results notification. +- */ +- String get id => _id; +- +- /** +- * The identifier used to associate results with this search request. +- * +- * If no element was found at the given location, this field will be absent, +- * and no results will be reported via the search.results notification. +- */ +- void set id(String value) { +- this._id = value; +- } +- +- /** +- * The element referenced or defined at the given offset and whose references +- * will be returned in the search results. +- * +- * If no element was found at the given location, this field will be absent. +- */ +- Element get element => _element; +- +- /** +- * The element referenced or defined at the given offset and whose references +- * will be returned in the search results. +- * +- * If no element was found at the given location, this field will be absent. +- */ +- void set element(Element value) { +- this._element = value; +- } +- +- SearchFindElementReferencesResult({String id, Element element}) { +- this.id = id; +- this.element = element; +- } +- +- factory SearchFindElementReferencesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } +- Element element; +- if (json.containsKey("element")) { +- element = new Element.fromJson( +- jsonDecoder, jsonPath + ".element", json["element"]); +- } +- return new SearchFindElementReferencesResult(id: id, element: element); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findElementReferences result", json); +- } +- } +- +- factory SearchFindElementReferencesResult.fromResponse(Response response) { +- return new SearchFindElementReferencesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (id != null) { +- result["id"] = id; +- } +- if (element != null) { +- result["element"] = element.toJson(); +- } +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindElementReferencesResult) { +- return id == other.id && element == other.element; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- hash = JenkinsSmiHash.combine(hash, element.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findMemberDeclarations params +- * +- * { +- * "name": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindMemberDeclarationsParams implements RequestParams { +- String _name; +- +- /** +- * The name of the declarations to be found. +- */ +- String get name => _name; +- +- /** +- * The name of the declarations to be found. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- SearchFindMemberDeclarationsParams(String name) { +- this.name = name; +- } +- +- factory SearchFindMemberDeclarationsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- return new SearchFindMemberDeclarationsParams(name); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findMemberDeclarations params", json); +- } +- } +- +- factory SearchFindMemberDeclarationsParams.fromRequest(Request request) { +- return new SearchFindMemberDeclarationsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["name"] = name; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "search.findMemberDeclarations", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindMemberDeclarationsParams) { +- return name == other.name; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findMemberDeclarations result +- * +- * { +- * "id": SearchId +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindMemberDeclarationsResult implements ResponseResult { +- String _id; +- +- /** +- * The identifier used to associate results with this search request. +- */ +- String get id => _id; +- +- /** +- * The identifier used to associate results with this search request. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- SearchFindMemberDeclarationsResult(String id) { +- this.id = id; +- } +- +- factory SearchFindMemberDeclarationsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- return new SearchFindMemberDeclarationsResult(id); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findMemberDeclarations result", json); +- } +- } +- +- factory SearchFindMemberDeclarationsResult.fromResponse(Response response) { +- return new SearchFindMemberDeclarationsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindMemberDeclarationsResult) { +- return id == other.id; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findMemberReferences params +- * +- * { +- * "name": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindMemberReferencesParams implements RequestParams { +- String _name; +- +- /** +- * The name of the references to be found. +- */ +- String get name => _name; +- +- /** +- * The name of the references to be found. +- */ +- void set name(String value) { +- assert(value != null); +- this._name = value; +- } +- +- SearchFindMemberReferencesParams(String name) { +- this.name = name; +- } +- +- factory SearchFindMemberReferencesParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String name; +- if (json.containsKey("name")) { +- name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "name"); +- } +- return new SearchFindMemberReferencesParams(name); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findMemberReferences params", json); +- } +- } +- +- factory SearchFindMemberReferencesParams.fromRequest(Request request) { +- return new SearchFindMemberReferencesParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["name"] = name; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "search.findMemberReferences", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindMemberReferencesParams) { +- return name == other.name; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, name.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findMemberReferences result +- * +- * { +- * "id": SearchId +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindMemberReferencesResult implements ResponseResult { +- String _id; +- +- /** +- * The identifier used to associate results with this search request. +- */ +- String get id => _id; +- +- /** +- * The identifier used to associate results with this search request. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- SearchFindMemberReferencesResult(String id) { +- this.id = id; +- } +- +- factory SearchFindMemberReferencesResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- return new SearchFindMemberReferencesResult(id); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findMemberReferences result", json); +- } +- } +- +- factory SearchFindMemberReferencesResult.fromResponse(Response response) { +- return new SearchFindMemberReferencesResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindMemberReferencesResult) { +- return id == other.id; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findTopLevelDeclarations params +- * +- * { +- * "pattern": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindTopLevelDeclarationsParams implements RequestParams { +- String _pattern; +- +- /** +- * The regular expression used to match the names of the declarations to be +- * found. +- */ +- String get pattern => _pattern; +- +- /** +- * The regular expression used to match the names of the declarations to be +- * found. +- */ +- void set pattern(String value) { +- assert(value != null); +- this._pattern = value; +- } +- +- SearchFindTopLevelDeclarationsParams(String pattern) { +- this.pattern = pattern; +- } +- +- factory SearchFindTopLevelDeclarationsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String pattern; +- if (json.containsKey("pattern")) { +- pattern = +- jsonDecoder.decodeString(jsonPath + ".pattern", json["pattern"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "pattern"); +- } +- return new SearchFindTopLevelDeclarationsParams(pattern); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findTopLevelDeclarations params", json); +- } +- } +- +- factory SearchFindTopLevelDeclarationsParams.fromRequest(Request request) { +- return new SearchFindTopLevelDeclarationsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["pattern"] = pattern; +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "search.findTopLevelDeclarations", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindTopLevelDeclarationsParams) { +- return pattern == other.pattern; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, pattern.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.findTopLevelDeclarations result +- * +- * { +- * "id": SearchId +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchFindTopLevelDeclarationsResult implements ResponseResult { +- String _id; +- +- /** +- * The identifier used to associate results with this search request. +- */ +- String get id => _id; +- +- /** +- * The identifier used to associate results with this search request. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- SearchFindTopLevelDeclarationsResult(String id) { +- this.id = id; +- } +- +- factory SearchFindTopLevelDeclarationsResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- return new SearchFindTopLevelDeclarationsResult(id); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.findTopLevelDeclarations result", json); +- } +- } +- +- factory SearchFindTopLevelDeclarationsResult.fromResponse(Response response) { +- return new SearchFindTopLevelDeclarationsResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchFindTopLevelDeclarationsResult) { +- return id == other.id; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.getTypeHierarchy params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "superOnly": optional bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchGetTypeHierarchyParams implements RequestParams { +- String _file; +- +- int _offset; +- +- bool _superOnly; +- +- /** +- * The file containing the declaration or reference to the type for which a +- * hierarchy is being requested. +- */ +- String get file => _file; +- +- /** +- * The file containing the declaration or reference to the type for which a +- * hierarchy is being requested. +- */ +- void set file(String value) { +- assert(value != null); +- this._file = value; +- } +- +- /** +- * The offset of the name of the type within the file. +- */ +- int get offset => _offset; +- +- /** +- * The offset of the name of the type within the file. +- */ +- void set offset(int value) { +- assert(value != null); +- this._offset = value; +- } +- +- /** +- * True if the client is only requesting superclasses and interfaces +- * hierarchy. +- */ +- bool get superOnly => _superOnly; +- +- /** +- * True if the client is only requesting superclasses and interfaces +- * hierarchy. +- */ +- void set superOnly(bool value) { +- this._superOnly = value; +- } +- +- SearchGetTypeHierarchyParams(String file, int offset, {bool superOnly}) { +- this.file = file; +- this.offset = offset; +- this.superOnly = superOnly; +- } +- +- factory SearchGetTypeHierarchyParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String file; +- if (json.containsKey("file")) { +- file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "file"); +- } +- int offset; +- if (json.containsKey("offset")) { +- offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "offset"); +- } +- bool superOnly; +- if (json.containsKey("superOnly")) { +- superOnly = +- jsonDecoder.decodeBool(jsonPath + ".superOnly", json["superOnly"]); +- } +- return new SearchGetTypeHierarchyParams(file, offset, +- superOnly: superOnly); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.getTypeHierarchy params", json); +- } +- } +- +- factory SearchGetTypeHierarchyParams.fromRequest(Request request) { +- return new SearchGetTypeHierarchyParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["file"] = file; +- result["offset"] = offset; +- if (superOnly != null) { +- result["superOnly"] = superOnly; +- } +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "search.getTypeHierarchy", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchGetTypeHierarchyParams) { +- return file == other.file && +- offset == other.offset && +- superOnly == other.superOnly; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, file.hashCode); +- hash = JenkinsSmiHash.combine(hash, offset.hashCode); +- hash = JenkinsSmiHash.combine(hash, superOnly.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * search.getTypeHierarchy result +- * +- * { +- * "hierarchyItems": optional List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchGetTypeHierarchyResult implements ResponseResult { +- List _hierarchyItems; +- +- /** +- * A list of the types in the requested hierarchy. The first element of the +- * list is the item representing the type for which the hierarchy was +- * requested. The index of other elements of the list is unspecified, but +- * correspond to the integers used to reference supertype and subtype items +- * within the items. +- * +- * This field will be absent if the code at the given file and offset does +- * not represent a type, or if the file has not been sufficiently analyzed to +- * allow a type hierarchy to be produced. +- */ +- List get hierarchyItems => _hierarchyItems; +- +- /** +- * A list of the types in the requested hierarchy. The first element of the +- * list is the item representing the type for which the hierarchy was +- * requested. The index of other elements of the list is unspecified, but +- * correspond to the integers used to reference supertype and subtype items +- * within the items. +- * +- * This field will be absent if the code at the given file and offset does +- * not represent a type, or if the file has not been sufficiently analyzed to +- * allow a type hierarchy to be produced. +- */ +- void set hierarchyItems(List value) { +- this._hierarchyItems = value; +- } +- +- SearchGetTypeHierarchyResult({List hierarchyItems}) { +- this.hierarchyItems = hierarchyItems; +- } +- +- factory SearchGetTypeHierarchyResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List hierarchyItems; +- if (json.containsKey("hierarchyItems")) { +- hierarchyItems = jsonDecoder.decodeList( +- jsonPath + ".hierarchyItems", +- json["hierarchyItems"], +- (String jsonPath, Object json) => +- new TypeHierarchyItem.fromJson(jsonDecoder, jsonPath, json)); +- } +- return new SearchGetTypeHierarchyResult(hierarchyItems: hierarchyItems); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "search.getTypeHierarchy result", json); +- } +- } +- +- factory SearchGetTypeHierarchyResult.fromResponse(Response response) { +- return new SearchGetTypeHierarchyResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (hierarchyItems != null) { +- result["hierarchyItems"] = hierarchyItems +- .map((TypeHierarchyItem value) => value.toJson()) +- .toList(); +- } +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchGetTypeHierarchyResult) { +- return listEqual(hierarchyItems, other.hierarchyItems, +- (TypeHierarchyItem a, TypeHierarchyItem b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, hierarchyItems.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * SearchResult +- * +- * { +- * "location": Location +- * "kind": SearchResultKind +- * "isPotential": bool +- * "path": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchResult implements HasToJson { +- Location _location; +- +- SearchResultKind _kind; +- +- bool _isPotential; +- +- List _path; +- +- /** +- * The location of the code that matched the search criteria. +- */ +- Location get location => _location; +- +- /** +- * The location of the code that matched the search criteria. +- */ +- void set location(Location value) { +- assert(value != null); +- this._location = value; +- } +- +- /** +- * The kind of element that was found or the kind of reference that was +- * found. +- */ +- SearchResultKind get kind => _kind; +- +- /** +- * The kind of element that was found or the kind of reference that was +- * found. +- */ +- void set kind(SearchResultKind value) { +- assert(value != null); +- this._kind = value; +- } +- +- /** +- * True if the result is a potential match but cannot be confirmed to be a +- * match. For example, if all references to a method m defined in some class +- * were requested, and a reference to a method m from an unknown class were +- * found, it would be marked as being a potential match. +- */ +- bool get isPotential => _isPotential; +- +- /** +- * True if the result is a potential match but cannot be confirmed to be a +- * match. For example, if all references to a method m defined in some class +- * were requested, and a reference to a method m from an unknown class were +- * found, it would be marked as being a potential match. +- */ +- void set isPotential(bool value) { +- assert(value != null); +- this._isPotential = value; +- } +- +- /** +- * The elements that contain the result, starting with the most immediately +- * enclosing ancestor and ending with the library. +- */ +- List get path => _path; +- +- /** +- * The elements that contain the result, starting with the most immediately +- * enclosing ancestor and ending with the library. +- */ +- void set path(List value) { +- assert(value != null); +- this._path = value; +- } +- +- SearchResult(Location location, SearchResultKind kind, bool isPotential, +- List path) { +- this.location = location; +- this.kind = kind; +- this.isPotential = isPotential; +- this.path = path; +- } +- +- factory SearchResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- Location location; +- if (json.containsKey("location")) { +- location = new Location.fromJson( +- jsonDecoder, jsonPath + ".location", json["location"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "location"); +- } +- SearchResultKind kind; +- if (json.containsKey("kind")) { +- kind = new SearchResultKind.fromJson( +- jsonDecoder, jsonPath + ".kind", json["kind"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "kind"); +- } +- bool isPotential; +- if (json.containsKey("isPotential")) { +- isPotential = jsonDecoder.decodeBool( +- jsonPath + ".isPotential", json["isPotential"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isPotential"); +- } +- List path; +- if (json.containsKey("path")) { +- path = jsonDecoder.decodeList( +- jsonPath + ".path", +- json["path"], +- (String jsonPath, Object json) => +- new Element.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "path"); +- } +- return new SearchResult(location, kind, isPotential, path); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "SearchResult", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["location"] = location.toJson(); +- result["kind"] = kind.toJson(); +- result["isPotential"] = isPotential; +- result["path"] = path.map((Element value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchResult) { +- return location == other.location && +- kind == other.kind && +- isPotential == other.isPotential && +- listEqual(path, other.path, (Element a, Element b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, location.hashCode); +- hash = JenkinsSmiHash.combine(hash, kind.hashCode); +- hash = JenkinsSmiHash.combine(hash, isPotential.hashCode); +- hash = JenkinsSmiHash.combine(hash, path.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * SearchResultKind +- * +- * enum { +- * DECLARATION +- * INVOCATION +- * READ +- * READ_WRITE +- * REFERENCE +- * UNKNOWN +- * WRITE +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchResultKind implements Enum { +- /** +- * The declaration of an element. +- */ +- static const SearchResultKind DECLARATION = +- const SearchResultKind._("DECLARATION"); +- +- /** +- * The invocation of a function or method. +- */ +- static const SearchResultKind INVOCATION = +- const SearchResultKind._("INVOCATION"); +- +- /** +- * A reference to a field, parameter or variable where it is being read. +- */ +- static const SearchResultKind READ = const SearchResultKind._("READ"); +- +- /** +- * A reference to a field, parameter or variable where it is being read and +- * written. +- */ +- static const SearchResultKind READ_WRITE = +- const SearchResultKind._("READ_WRITE"); +- +- /** +- * A reference to an element. +- */ +- static const SearchResultKind REFERENCE = +- const SearchResultKind._("REFERENCE"); +- +- /** +- * Some other kind of search result. +- */ +- static const SearchResultKind UNKNOWN = const SearchResultKind._("UNKNOWN"); +- +- /** +- * A reference to a field, parameter or variable where it is being written. +- */ +- static const SearchResultKind WRITE = const SearchResultKind._("WRITE"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [ +- DECLARATION, +- INVOCATION, +- READ, +- READ_WRITE, +- REFERENCE, +- UNKNOWN, +- WRITE +- ]; +- +- @override +- final String name; +- +- const SearchResultKind._(this.name); +- +- factory SearchResultKind(String name) { +- switch (name) { +- case "DECLARATION": +- return DECLARATION; +- case "INVOCATION": +- return INVOCATION; +- case "READ": +- return READ; +- case "READ_WRITE": +- return READ_WRITE; +- case "REFERENCE": +- return REFERENCE; +- case "UNKNOWN": +- return UNKNOWN; +- case "WRITE": +- return WRITE; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory SearchResultKind.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new SearchResultKind(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "SearchResultKind", json); +- } +- +- @override +- String toString() => "SearchResultKind.$name"; +- +- String toJson() => name; +-} +- +-/** +- * search.results params +- * +- * { +- * "id": SearchId +- * "results": List +- * "isLast": bool +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class SearchResultsParams implements HasToJson { +- String _id; +- +- List _results; +- +- bool _isLast; +- +- /** +- * The id associated with the search. +- */ +- String get id => _id; +- +- /** +- * The id associated with the search. +- */ +- void set id(String value) { +- assert(value != null); +- this._id = value; +- } +- +- /** +- * The search results being reported. +- */ +- List get results => _results; +- +- /** +- * The search results being reported. +- */ +- void set results(List value) { +- assert(value != null); +- this._results = value; +- } +- +- /** +- * True if this is that last set of results that will be returned for the +- * indicated search. +- */ +- bool get isLast => _isLast; +- +- /** +- * True if this is that last set of results that will be returned for the +- * indicated search. +- */ +- void set isLast(bool value) { +- assert(value != null); +- this._isLast = value; +- } +- +- SearchResultsParams(String id, List results, bool isLast) { +- this.id = id; +- this.results = results; +- this.isLast = isLast; +- } +- +- factory SearchResultsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String id; +- if (json.containsKey("id")) { +- id = jsonDecoder.decodeString(jsonPath + ".id", json["id"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "id"); +- } +- List results; +- if (json.containsKey("results")) { +- results = jsonDecoder.decodeList( +- jsonPath + ".results", +- json["results"], +- (String jsonPath, Object json) => +- new SearchResult.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "results"); +- } +- bool isLast; +- if (json.containsKey("isLast")) { +- isLast = jsonDecoder.decodeBool(jsonPath + ".isLast", json["isLast"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isLast"); +- } +- return new SearchResultsParams(id, results, isLast); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "search.results params", json); +- } +- } +- +- factory SearchResultsParams.fromNotification(Notification notification) { +- return new SearchResultsParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["id"] = id; +- result["results"] = +- results.map((SearchResult value) => value.toJson()).toList(); +- result["isLast"] = isLast; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("search.results", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is SearchResultsParams) { +- return id == other.id && +- listEqual(results, other.results, +- (SearchResult a, SearchResult b) => a == b) && +- isLast == other.isLast; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, id.hashCode); +- hash = JenkinsSmiHash.combine(hash, results.hashCode); +- hash = JenkinsSmiHash.combine(hash, isLast.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * server.connected params +- * +- * { +- * "version": String +- * "pid": int +- * "sessionId": optional String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerConnectedParams implements HasToJson { +- String _version; +- +- int _pid; +- +- String _sessionId; +- +- /** +- * The version number of the analysis server. +- */ +- String get version => _version; +- +- /** +- * The version number of the analysis server. +- */ +- void set version(String value) { +- assert(value != null); +- this._version = value; +- } +- +- /** +- * The process id of the analysis server process. +- */ +- int get pid => _pid; +- +- /** +- * The process id of the analysis server process. +- */ +- void set pid(int value) { +- assert(value != null); +- this._pid = value; +- } +- +- /** +- * The session id for this session. +- */ +- String get sessionId => _sessionId; +- +- /** +- * The session id for this session. +- */ +- void set sessionId(String value) { +- this._sessionId = value; +- } +- +- ServerConnectedParams(String version, int pid, {String sessionId}) { +- this.version = version; +- this.pid = pid; +- this.sessionId = sessionId; +- } +- +- factory ServerConnectedParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String version; +- if (json.containsKey("version")) { +- version = +- jsonDecoder.decodeString(jsonPath + ".version", json["version"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "version"); +- } +- int pid; +- if (json.containsKey("pid")) { +- pid = jsonDecoder.decodeInt(jsonPath + ".pid", json["pid"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "pid"); +- } +- String sessionId; +- if (json.containsKey("sessionId")) { +- sessionId = jsonDecoder.decodeString( +- jsonPath + ".sessionId", json["sessionId"]); +- } +- return new ServerConnectedParams(version, pid, sessionId: sessionId); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "server.connected params", json); +- } +- } +- +- factory ServerConnectedParams.fromNotification(Notification notification) { +- return new ServerConnectedParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["version"] = version; +- result["pid"] = pid; +- if (sessionId != null) { +- result["sessionId"] = sessionId; +- } +- return result; +- } +- +- Notification toNotification() { +- return new Notification("server.connected", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ServerConnectedParams) { +- return version == other.version && +- pid == other.pid && +- sessionId == other.sessionId; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, version.hashCode); +- hash = JenkinsSmiHash.combine(hash, pid.hashCode); +- hash = JenkinsSmiHash.combine(hash, sessionId.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * server.error params +- * +- * { +- * "isFatal": bool +- * "message": String +- * "stackTrace": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerErrorParams implements HasToJson { +- bool _isFatal; +- +- String _message; +- +- String _stackTrace; +- +- /** +- * True if the error is a fatal error, meaning that the server will shutdown +- * automatically after sending this notification. +- */ +- bool get isFatal => _isFatal; +- +- /** +- * True if the error is a fatal error, meaning that the server will shutdown +- * automatically after sending this notification. +- */ +- void set isFatal(bool value) { +- assert(value != null); +- this._isFatal = value; +- } +- +- /** +- * The error message indicating what kind of error was encountered. +- */ +- String get message => _message; +- +- /** +- * The error message indicating what kind of error was encountered. +- */ +- void set message(String value) { +- assert(value != null); +- this._message = value; +- } +- +- /** +- * The stack trace associated with the generation of the error, used for +- * debugging the server. +- */ +- String get stackTrace => _stackTrace; +- +- /** +- * The stack trace associated with the generation of the error, used for +- * debugging the server. +- */ +- void set stackTrace(String value) { +- assert(value != null); +- this._stackTrace = value; +- } +- +- ServerErrorParams(bool isFatal, String message, String stackTrace) { +- this.isFatal = isFatal; +- this.message = message; +- this.stackTrace = stackTrace; +- } +- +- factory ServerErrorParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- bool isFatal; +- if (json.containsKey("isFatal")) { +- isFatal = +- jsonDecoder.decodeBool(jsonPath + ".isFatal", json["isFatal"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "isFatal"); +- } +- String message; +- if (json.containsKey("message")) { +- message = +- jsonDecoder.decodeString(jsonPath + ".message", json["message"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "message"); +- } +- String stackTrace; +- if (json.containsKey("stackTrace")) { +- stackTrace = jsonDecoder.decodeString( +- jsonPath + ".stackTrace", json["stackTrace"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "stackTrace"); +- } +- return new ServerErrorParams(isFatal, message, stackTrace); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "server.error params", json); +- } +- } +- +- factory ServerErrorParams.fromNotification(Notification notification) { +- return new ServerErrorParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["isFatal"] = isFatal; +- result["message"] = message; +- result["stackTrace"] = stackTrace; +- return result; +- } +- +- Notification toNotification() { +- return new Notification("server.error", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ServerErrorParams) { +- return isFatal == other.isFatal && +- message == other.message && +- stackTrace == other.stackTrace; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, isFatal.hashCode); +- hash = JenkinsSmiHash.combine(hash, message.hashCode); +- hash = JenkinsSmiHash.combine(hash, stackTrace.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * server.getVersion params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerGetVersionParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "server.getVersion", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is ServerGetVersionParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 55877452; +- } +-} +- +-/** +- * server.getVersion result +- * +- * { +- * "version": String +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerGetVersionResult implements ResponseResult { +- String _version; +- +- /** +- * The version number of the analysis server. +- */ +- String get version => _version; +- +- /** +- * The version number of the analysis server. +- */ +- void set version(String value) { +- assert(value != null); +- this._version = value; +- } +- +- ServerGetVersionResult(String version) { +- this.version = version; +- } +- +- factory ServerGetVersionResult.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- String version; +- if (json.containsKey("version")) { +- version = +- jsonDecoder.decodeString(jsonPath + ".version", json["version"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "version"); +- } +- return new ServerGetVersionResult(version); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "server.getVersion result", json); +- } +- } +- +- factory ServerGetVersionResult.fromResponse(Response response) { +- return new ServerGetVersionResult.fromJson( +- new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), +- "result", +- response.result); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["version"] = version; +- return result; +- } +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ServerGetVersionResult) { +- return version == other.version; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, version.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * ServerService +- * +- * enum { +- * STATUS +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerService implements Enum { +- static const ServerService STATUS = const ServerService._("STATUS"); +- +- /** +- * A list containing all of the enum values that are defined. +- */ +- static const List VALUES = const [STATUS]; +- +- @override +- final String name; +- +- const ServerService._(this.name); +- +- factory ServerService(String name) { +- switch (name) { +- case "STATUS": +- return STATUS; +- } +- throw new Exception('Illegal enum value: $name'); +- } +- +- factory ServerService.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json is String) { +- try { +- return new ServerService(json); +- } catch (_) { +- // Fall through +- } +- } +- throw jsonDecoder.mismatch(jsonPath, "ServerService", json); +- } +- +- @override +- String toString() => "ServerService.$name"; +- +- String toJson() => name; +-} +- +-/** +- * server.setSubscriptions params +- * +- * { +- * "subscriptions": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerSetSubscriptionsParams implements RequestParams { +- List _subscriptions; +- +- /** +- * A list of the services being subscribed to. +- */ +- List get subscriptions => _subscriptions; +- +- /** +- * A list of the services being subscribed to. +- */ +- void set subscriptions(List value) { +- assert(value != null); +- this._subscriptions = value; +- } +- +- ServerSetSubscriptionsParams(List subscriptions) { +- this.subscriptions = subscriptions; +- } +- +- factory ServerSetSubscriptionsParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- List subscriptions; +- if (json.containsKey("subscriptions")) { +- subscriptions = jsonDecoder.decodeList( +- jsonPath + ".subscriptions", +- json["subscriptions"], +- (String jsonPath, Object json) => +- new ServerService.fromJson(jsonDecoder, jsonPath, json)); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "subscriptions"); +- } +- return new ServerSetSubscriptionsParams(subscriptions); +- } else { +- throw jsonDecoder.mismatch( +- jsonPath, "server.setSubscriptions params", json); +- } +- } +- +- factory ServerSetSubscriptionsParams.fromRequest(Request request) { +- return new ServerSetSubscriptionsParams.fromJson( +- new RequestDecoder(request), "params", request.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["subscriptions"] = +- subscriptions.map((ServerService value) => value.toJson()).toList(); +- return result; +- } +- +- @override +- Request toRequest(String id) { +- return new Request(id, "server.setSubscriptions", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ServerSetSubscriptionsParams) { +- return listEqual(subscriptions, other.subscriptions, +- (ServerService a, ServerService b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * server.setSubscriptions result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerSetSubscriptionsResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is ServerSetSubscriptionsResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 748820900; +- } +-} +- +-/** +- * server.shutdown params +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerShutdownParams implements RequestParams { +- @override +- Map toJson() => {}; +- +- @override +- Request toRequest(String id) { +- return new Request(id, "server.shutdown", null); +- } +- +- @override +- bool operator ==(other) { +- if (other is ServerShutdownParams) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 366630911; +- } +-} +- +-/** +- * server.shutdown result +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerShutdownResult implements ResponseResult { +- @override +- Map toJson() => {}; +- +- @override +- Response toResponse(String id) { +- return new Response(id, result: null); +- } +- +- @override +- bool operator ==(other) { +- if (other is ServerShutdownResult) { +- return true; +- } +- return false; +- } +- +- @override +- int get hashCode { +- return 193626532; +- } +-} +- +-/** +- * server.status params +- * +- * { +- * "analysis": optional AnalysisStatus +- * "pub": optional PubStatus +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class ServerStatusParams implements HasToJson { +- AnalysisStatus _analysis; +- +- PubStatus _pub; +- +- /** +- * The current status of analysis, including whether analysis is being +- * performed and if so what is being analyzed. +- */ +- AnalysisStatus get analysis => _analysis; +- +- /** +- * The current status of analysis, including whether analysis is being +- * performed and if so what is being analyzed. +- */ +- void set analysis(AnalysisStatus value) { +- this._analysis = value; +- } +- +- /** +- * The current status of pub execution, indicating whether we are currently +- * running pub. +- */ +- PubStatus get pub => _pub; +- +- /** +- * The current status of pub execution, indicating whether we are currently +- * running pub. +- */ +- void set pub(PubStatus value) { +- this._pub = value; +- } +- +- ServerStatusParams({AnalysisStatus analysis, PubStatus pub}) { +- this.analysis = analysis; +- this.pub = pub; +- } +- +- factory ServerStatusParams.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- AnalysisStatus analysis; +- if (json.containsKey("analysis")) { +- analysis = new AnalysisStatus.fromJson( +- jsonDecoder, jsonPath + ".analysis", json["analysis"]); +- } +- PubStatus pub; +- if (json.containsKey("pub")) { +- pub = +- new PubStatus.fromJson(jsonDecoder, jsonPath + ".pub", json["pub"]); +- } +- return new ServerStatusParams(analysis: analysis, pub: pub); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "server.status params", json); +- } +- } +- +- factory ServerStatusParams.fromNotification(Notification notification) { +- return new ServerStatusParams.fromJson( +- new ResponseDecoder(null), "params", notification.params); +- } +- +- @override +- Map toJson() { +- Map result = {}; +- if (analysis != null) { +- result["analysis"] = analysis.toJson(); +- } +- if (pub != null) { +- result["pub"] = pub.toJson(); +- } +- return result; +- } +- +- Notification toNotification() { +- return new Notification("server.status", toJson()); +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is ServerStatusParams) { +- return analysis == other.analysis && pub == other.pub; +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, analysis.hashCode); +- hash = JenkinsSmiHash.combine(hash, pub.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +- +-/** +- * TypeHierarchyItem +- * +- * { +- * "classElement": Element +- * "displayName": optional String +- * "memberElement": optional Element +- * "superclass": optional int +- * "interfaces": List +- * "mixins": List +- * "subclasses": List +- * } +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class TypeHierarchyItem implements HasToJson { +- Element _classElement; +- +- String _displayName; +- +- Element _memberElement; +- +- int _superclass; +- +- List _interfaces; +- +- List _mixins; +- +- List _subclasses; +- +- /** +- * The class element represented by this item. +- */ +- Element get classElement => _classElement; +- +- /** +- * The class element represented by this item. +- */ +- void set classElement(Element value) { +- assert(value != null); +- this._classElement = value; +- } +- +- /** +- * The name to be displayed for the class. This field will be omitted if the +- * display name is the same as the name of the element. The display name is +- * different if there is additional type information to be displayed, such as +- * type arguments. +- */ +- String get displayName => _displayName; +- +- /** +- * The name to be displayed for the class. This field will be omitted if the +- * display name is the same as the name of the element. The display name is +- * different if there is additional type information to be displayed, such as +- * type arguments. +- */ +- void set displayName(String value) { +- this._displayName = value; +- } +- +- /** +- * The member in the class corresponding to the member on which the hierarchy +- * was requested. This field will be omitted if the hierarchy was not +- * requested for a member or if the class does not have a corresponding +- * member. +- */ +- Element get memberElement => _memberElement; +- +- /** +- * The member in the class corresponding to the member on which the hierarchy +- * was requested. This field will be omitted if the hierarchy was not +- * requested for a member or if the class does not have a corresponding +- * member. +- */ +- void set memberElement(Element value) { +- this._memberElement = value; +- } +- +- /** +- * The index of the item representing the superclass of this class. This +- * field will be omitted if this item represents the class Object. +- */ +- int get superclass => _superclass; +- +- /** +- * The index of the item representing the superclass of this class. This +- * field will be omitted if this item represents the class Object. +- */ +- void set superclass(int value) { +- this._superclass = value; +- } +- +- /** +- * The indexes of the items representing the interfaces implemented by this +- * class. The list will be empty if there are no implemented interfaces. +- */ +- List get interfaces => _interfaces; +- +- /** +- * The indexes of the items representing the interfaces implemented by this +- * class. The list will be empty if there are no implemented interfaces. +- */ +- void set interfaces(List value) { +- assert(value != null); +- this._interfaces = value; +- } +- +- /** +- * The indexes of the items representing the mixins referenced by this class. +- * The list will be empty if there are no classes mixed in to this class. +- */ +- List get mixins => _mixins; +- +- /** +- * The indexes of the items representing the mixins referenced by this class. +- * The list will be empty if there are no classes mixed in to this class. +- */ +- void set mixins(List value) { +- assert(value != null); +- this._mixins = value; +- } +- +- /** +- * The indexes of the items representing the subtypes of this class. The list +- * will be empty if there are no subtypes or if this item represents a +- * supertype of the pivot type. +- */ +- List get subclasses => _subclasses; +- +- /** +- * The indexes of the items representing the subtypes of this class. The list +- * will be empty if there are no subtypes or if this item represents a +- * supertype of the pivot type. +- */ +- void set subclasses(List value) { +- assert(value != null); +- this._subclasses = value; +- } +- +- TypeHierarchyItem(Element classElement, +- {String displayName, +- Element memberElement, +- int superclass, +- List interfaces, +- List mixins, +- List subclasses}) { +- this.classElement = classElement; +- this.displayName = displayName; +- this.memberElement = memberElement; +- this.superclass = superclass; +- if (interfaces == null) { +- this.interfaces = []; +- } else { +- this.interfaces = interfaces; +- } +- if (mixins == null) { +- this.mixins = []; +- } else { +- this.mixins = mixins; +- } +- if (subclasses == null) { +- this.subclasses = []; +- } else { +- this.subclasses = subclasses; +- } +- } +- +- factory TypeHierarchyItem.fromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json) { +- if (json == null) { +- json = {}; +- } +- if (json is Map) { +- Element classElement; +- if (json.containsKey("classElement")) { +- classElement = new Element.fromJson( +- jsonDecoder, jsonPath + ".classElement", json["classElement"]); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "classElement"); +- } +- String displayName; +- if (json.containsKey("displayName")) { +- displayName = jsonDecoder.decodeString( +- jsonPath + ".displayName", json["displayName"]); +- } +- Element memberElement; +- if (json.containsKey("memberElement")) { +- memberElement = new Element.fromJson( +- jsonDecoder, jsonPath + ".memberElement", json["memberElement"]); +- } +- int superclass; +- if (json.containsKey("superclass")) { +- superclass = +- jsonDecoder.decodeInt(jsonPath + ".superclass", json["superclass"]); +- } +- List interfaces; +- if (json.containsKey("interfaces")) { +- interfaces = jsonDecoder.decodeList(jsonPath + ".interfaces", +- json["interfaces"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "interfaces"); +- } +- List mixins; +- if (json.containsKey("mixins")) { +- mixins = jsonDecoder.decodeList( +- jsonPath + ".mixins", json["mixins"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "mixins"); +- } +- List subclasses; +- if (json.containsKey("subclasses")) { +- subclasses = jsonDecoder.decodeList(jsonPath + ".subclasses", +- json["subclasses"], jsonDecoder.decodeInt); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "subclasses"); +- } +- return new TypeHierarchyItem(classElement, +- displayName: displayName, +- memberElement: memberElement, +- superclass: superclass, +- interfaces: interfaces, +- mixins: mixins, +- subclasses: subclasses); +- } else { +- throw jsonDecoder.mismatch(jsonPath, "TypeHierarchyItem", json); +- } +- } +- +- @override +- Map toJson() { +- Map result = {}; +- result["classElement"] = classElement.toJson(); +- if (displayName != null) { +- result["displayName"] = displayName; +- } +- if (memberElement != null) { +- result["memberElement"] = memberElement.toJson(); +- } +- if (superclass != null) { +- result["superclass"] = superclass; +- } +- result["interfaces"] = interfaces; +- result["mixins"] = mixins; +- result["subclasses"] = subclasses; +- return result; +- } +- +- @override +- String toString() => JSON.encode(toJson()); +- +- @override +- bool operator ==(other) { +- if (other is TypeHierarchyItem) { +- return classElement == other.classElement && +- displayName == other.displayName && +- memberElement == other.memberElement && +- superclass == other.superclass && +- listEqual(interfaces, other.interfaces, (int a, int b) => a == b) && +- listEqual(mixins, other.mixins, (int a, int b) => a == b) && +- listEqual(subclasses, other.subclasses, (int a, int b) => a == b); +- } +- return false; +- } +- +- @override +- int get hashCode { +- int hash = 0; +- hash = JenkinsSmiHash.combine(hash, classElement.hashCode); +- hash = JenkinsSmiHash.combine(hash, displayName.hashCode); +- hash = JenkinsSmiHash.combine(hash, memberElement.hashCode); +- hash = JenkinsSmiHash.combine(hash, superclass.hashCode); +- hash = JenkinsSmiHash.combine(hash, interfaces.hashCode); +- hash = JenkinsSmiHash.combine(hash, mixins.hashCode); +- hash = JenkinsSmiHash.combine(hash, subclasses.hashCode); +- return JenkinsSmiHash.finish(hash); +- } +-} +diff --git a/pkg/analysis_server/lib/src/analysis_logger.dart b/pkg/analysis_server/lib/src/analysis_logger.dart +deleted file mode 100644 +index 33911961423..00000000000 +--- a/pkg/analysis_server/lib/src/analysis_logger.dart ++++ /dev/null +@@ -1,55 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:logging/logging.dart' as logging; +- +-/** +- * Instances of the class [AnalysisLogger] translate from the analysis engine's +- * API to the logging package's API. +- */ +-class AnalysisLogger implements Logger { +- /** +- * The underlying logger that is being wrapped. +- */ +- final logging.Logger baseLogger = new logging.Logger('analysis.server'); +- +- /** +- * The analysis server that is using this logger. +- */ +- final AnalysisServer server; +- +- AnalysisLogger(this.server) { +- assert(server != null); +- logging.Logger.root.onRecord.listen((logging.LogRecord record) { +- AnalysisEngine.instance.instrumentationService.logLogEntry( +- record.level.name, +- record.time, +- record.message, +- record.error, +- record.stackTrace); +- }); +- } +- +- @override +- void logError(String message, [CaughtException exception]) { +- if (exception == null) { +- baseLogger.severe(message); +- } else { +- baseLogger.severe(message, exception.exception, exception.stackTrace); +- } +- server.sendServerErrorNotification(message, exception, null); +- } +- +- @override +- void logInformation(String message, [CaughtException exception]) { +- if (exception == null) { +- baseLogger.info(message); +- } else { +- baseLogger.info(message, exception.exception, exception.stackTrace); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart +deleted file mode 100644 +index b6ee79a64d1..00000000000 +--- a/pkg/analysis_server/lib/src/analysis_server.dart ++++ /dev/null +@@ -1,1557 +0,0 @@ +-// Copyright (c) 2014, 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 'dart:core'; +-import 'dart:io' as io; +-import 'dart:math' show max; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart' +- hide AnalysisOptions; +-import 'package:analysis_server/src/analysis_logger.dart'; +-import 'package:analysis_server/src/channel/channel.dart'; +-import 'package:analysis_server/src/collections.dart'; +-import 'package:analysis_server/src/computer/computer_highlights.dart'; +-import 'package:analysis_server/src/computer/computer_highlights2.dart'; +-import 'package:analysis_server/src/computer/computer_outline.dart'; +-import 'package:analysis_server/src/computer/new_notifications.dart'; +-import 'package:analysis_server/src/context_manager.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analysis_server/src/domain_analytics.dart'; +-import 'package:analysis_server/src/domain_completion.dart'; +-import 'package:analysis_server/src/domain_diagnostic.dart'; +-import 'package:analysis_server/src/domain_execution.dart'; +-import 'package:analysis_server/src/domain_kythe.dart'; +-import 'package:analysis_server/src/domain_server.dart'; +-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart'; +-import 'package:analysis_server/src/domains/analysis/occurrences.dart'; +-import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analysis_server/src/operation/operation_analysis.dart'; +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/plugin/plugin_watcher.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as server; +-import 'package:analysis_server/src/search/search_domain.dart'; +-import 'package:analysis_server/src/server/diagnostic_server.dart'; +-import 'package:analysis_server/src/services/correction/namespace.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; +-import 'package:analysis_server/src/utilities/null_string_sink.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/plugin/resolver_provider.dart'; +-import 'package:analyzer/source/pub_package_map_provider.dart'; +-import 'package:analyzer/src/context/builder.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart' as nd; +-import 'package:analyzer/src/dart/analysis/file_state.dart' as nd; +-import 'package:analyzer/src/dart/analysis/status.dart' as nd; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/source_io.dart'; +-import 'package:analyzer/src/generated/utilities_general.dart'; +-import 'package:analyzer/src/util/glob.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +-import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart'; +-import 'package:front_end/byte_store.dart'; +-import 'package:front_end/src/base/performance_logger.dart'; +-import 'package:telemetry/crash_reporting.dart'; +-import 'package:telemetry/telemetry.dart' as telemetry; +-import 'package:watcher/watcher.dart'; +- +-typedef void OptionUpdater(AnalysisOptionsImpl options); +- +-/** +- * Enum representing reasons why analysis might be done for a given file. +- */ +-class AnalysisDoneReason { +- /** +- * Analysis of the file completed successfully. +- */ +- static const AnalysisDoneReason COMPLETE = +- const AnalysisDoneReason._('COMPLETE'); +- +- /** +- * Analysis of the file was aborted because the context was removed. +- */ +- static const AnalysisDoneReason CONTEXT_REMOVED = +- const AnalysisDoneReason._('CONTEXT_REMOVED'); +- +- /** +- * Textual description of this [AnalysisDoneReason]. +- */ +- final String text; +- +- const AnalysisDoneReason._(this.text); +-} +- +-/** +- * Instances of the class [AnalysisServer] implement a server that listens on a +- * [CommunicationChannel] for analysis requests and process them. +- */ +-class AnalysisServer { +- /** +- * The version of the analysis server. The value should be replaced +- * automatically during the build. +- */ +- static final String VERSION = '1.18.4'; +- +- /** +- * The options of this server instance. +- */ +- AnalysisServerOptions options; +- +- /** +- * The channel from which requests are received and to which responses should +- * be sent. +- */ +- final ServerCommunicationChannel channel; +- +- /** +- * The object used to manage sending a subset of notifications to the client. +- * The subset of notifications are those to which plugins may contribute. +- * This field is `null` when the new plugin support is disabled. +- */ +- final NotificationManager notificationManager; +- +- /** +- * The object used to manage the execution of plugins. +- */ +- PluginManager pluginManager; +- +- /** +- * The [ResourceProvider] using which paths are converted into [Resource]s. +- */ +- final ResourceProvider resourceProvider; +- +- /** +- * The [SearchEngine] for this server, may be `null` if indexing is disabled. +- */ +- SearchEngine searchEngine; +- +- /** +- * A list of the globs used to determine which files should be analyzed. The +- * list is lazily created and should be accessed using [analyzedFilesGlobs]. +- */ +- List _analyzedFilesGlobs = null; +- +- /** +- * The [ContextManager] that handles the mapping from analysis roots to +- * context directories. +- */ +- ContextManager contextManager; +- +- /** +- * A flag indicating whether the server is running. When false, contexts +- * will no longer be added to [contextWorkQueue], and [performOperation] will +- * discard any tasks it finds on [contextWorkQueue]. +- */ +- bool running; +- +- /** +- * A flag indicating the value of the 'analyzing' parameter sent in the last +- * status message to the client. +- */ +- bool statusAnalyzing = false; +- +- /** +- * A list of the request handlers used to handle the requests sent to this +- * server. +- */ +- List handlers; +- +- /** +- * The object used to manage the SDK's known to this server. +- */ +- DartSdkManager sdkManager; +- +- /** +- * The instrumentation service that is to be used by this analysis server. +- */ +- final InstrumentationService instrumentationService; +- +- /** +- * A set of the [ServerService]s to send notifications for. +- */ +- Set serverServices = new HashSet(); +- +- /** +- * A set of the [GeneralAnalysisService]s to send notifications for. +- */ +- Set generalAnalysisServices = +- new HashSet(); +- +- /** +- * A table mapping [AnalysisService]s to the file paths for which these +- * notifications should be sent. +- */ +- Map> analysisServices = +- new HashMap>(); +- +- /** +- * Performance information before initial analysis is complete. +- */ +- ServerPerformance performanceDuringStartup = new ServerPerformance(); +- +- /** +- * Performance information after initial analysis is complete +- * or `null` if the initial analysis is not yet complete +- */ +- ServerPerformance performanceAfterStartup; +- +- /** +- * A [RecentBuffer] of the most recent exceptions encountered by the analysis +- * server. +- */ +- final RecentBuffer exceptions = new RecentBuffer(10); +- +- /** +- * The class into which performance information is currently being recorded. +- * During startup, this will be the same as [performanceDuringStartup] +- * and after startup is complete, this switches to [performanceAfterStartup]. +- */ +- ServerPerformance _performance; +- +- /** +- * The [Completer] that completes when analysis is complete. +- */ +- Completer _onAnalysisCompleteCompleter; +- +- /** +- * The controller that is notified when analysis is started. +- */ +- StreamController _onAnalysisStartedController; +- +- /** +- * The controller that is notified when a single file has been analyzed. +- */ +- StreamController _onFileAnalyzedController; +- +- /** +- * The content overlay for all analysis drivers. +- */ +- final nd.FileContentOverlay fileContentOverlay = new nd.FileContentOverlay(); +- +- /** +- * The current state of overlays from the client. This is used as the +- * content cache for all contexts. +- */ +- final ContentCache overlayState = new ContentCache(); +- +- /** +- * If the "analysis.analyzedFiles" notification is currently being subscribed +- * to (see [generalAnalysisServices]), and at least one such notification has +- * been sent since the subscription was enabled, the set of analyzed files +- * that was delivered in the most recently sent notification. Otherwise +- * `null`. +- */ +- Set prevAnalyzedFiles; +- +- /** +- * The default options used to create new analysis contexts. This object is +- * also referenced by the ContextManager. +- */ +- final AnalysisOptionsImpl defaultContextOptions = new AnalysisOptionsImpl(); +- +- /** +- * The file resolver provider used to override the way file URI's are +- * resolved in some contexts. +- */ +- ResolverProvider fileResolverProvider; +- +- /** +- * The package resolver provider used to override the way package URI's are +- * resolved in some contexts. +- */ +- ResolverProvider packageResolverProvider; +- +- PerformanceLog _analysisPerformanceLogger; +- +- ByteStore byteStore; +- nd.AnalysisDriverScheduler analysisDriverScheduler; +- +- /** +- * The controller for [onAnalysisSetChanged]. +- */ +- StreamController _onAnalysisSetChangedController = +- new StreamController.broadcast(); +- +- /** +- * This exists as a temporary stopgap for plugins, until the official plugin +- * API is complete. +- */ +- StreamController _onFileAddedController; +- +- /** +- * This exists as a temporary stopgap for plugins, until the official plugin +- * API is complete. +- */ +- StreamController _onFileChangedController; +- +- /** +- * This exists as a temporary stopgap for plugins, until the official plugin +- * API is complete. +- */ +- Function onResultErrorSupplementor; +- +- /** +- * This exists as a temporary stopgap for plugins, until the official plugin +- * API is complete. +- */ +- Function onNoAnalysisResult; +- +- /** +- * This exists as a temporary stopgap for plugins, until the official plugin +- * API is complete. +- */ +- Function onNoAnalysisCompletion; +- +- /** +- * The set of the files that are currently priority. +- */ +- final Set priorityFiles = new Set(); +- +- /** +- * The DiagnosticServer for this AnalysisServer. If available, it can be used +- * to start an http diagnostics server or return the port for an existing +- * server. +- */ +- DiagnosticServer diagnosticServer; +- +- /** +- * Initialize a newly created server to receive requests from and send +- * responses to the given [channel]. +- * +- * If [rethrowExceptions] is true, then any exceptions thrown by analysis are +- * propagated up the call stack. The default is true to allow analysis +- * exceptions to show up in unit tests, but it should be set to false when +- * running a full analysis server. +- */ +- AnalysisServer( +- this.channel, +- this.resourceProvider, +- PubPackageMapProvider packageMapProvider, +- this.options, +- this.sdkManager, +- this.instrumentationService, +- {this.diagnosticServer, +- ResolverProvider fileResolverProvider: null, +- ResolverProvider packageResolverProvider: null}) +- : notificationManager = +- new NotificationManager(channel, resourceProvider) { +- _performance = performanceDuringStartup; +- +- pluginManager = new PluginManager( +- resourceProvider, +- _getByteStorePath(), +- sdkManager.defaultSdkDirectory, +- notificationManager, +- instrumentationService); +- PluginWatcher pluginWatcher = +- new PluginWatcher(resourceProvider, pluginManager); +- +- defaultContextOptions.generateImplicitErrors = false; +- +- { +- String name = options.newAnalysisDriverLog; +- StringSink sink = new NullStringSink(); +- if (name != null) { +- if (name == 'stdout') { +- sink = io.stdout; +- } else if (name.startsWith('file:')) { +- String path = name.substring('file:'.length); +- sink = new io.File(path).openWrite(mode: io.FileMode.APPEND); +- } +- } +- _analysisPerformanceLogger = new PerformanceLog(sink); +- } +- byteStore = _createByteStore(); +- analysisDriverScheduler = new nd.AnalysisDriverScheduler( +- _analysisPerformanceLogger, +- driverWatcher: pluginWatcher); +- analysisDriverScheduler.status.listen(sendStatusNotificationNew); +- analysisDriverScheduler.start(); +- +- contextManager = new ContextManagerImpl( +- resourceProvider, +- sdkManager, +- packageResolverProvider, +- packageMapProvider, +- analyzedFilesGlobs, +- instrumentationService, +- defaultContextOptions); +- this.fileResolverProvider = fileResolverProvider; +- this.packageResolverProvider = packageResolverProvider; +- ServerContextManagerCallbacks contextManagerCallbacks = +- new ServerContextManagerCallbacks(this, resourceProvider); +- contextManager.callbacks = contextManagerCallbacks; +- AnalysisEngine.instance.logger = new AnalysisLogger(this); +- _onAnalysisStartedController = new StreamController.broadcast(); +- _onFileAnalyzedController = new StreamController.broadcast(); +- // temporary plugin support: +- _onFileAddedController = new StreamController.broadcast(); +- // temporary plugin support: +- _onFileChangedController = new StreamController.broadcast(); +- running = true; +- onAnalysisStarted.first.then((_) { +- onAnalysisComplete.then((_) { +- performanceAfterStartup = new ServerPerformance(); +- _performance = performanceAfterStartup; +- }); +- }); +- searchEngine = new SearchEngineImpl(driverMap.values); +- Notification notification = new ServerConnectedParams(VERSION, io.pid, +- sessionId: instrumentationService.sessionId) +- .toNotification(); +- channel.sendNotification(notification); +- channel.listen(handleRequest, onDone: done, onError: error); +- handlers = [ +- new ServerDomainHandler(this), +- new AnalysisDomainHandler(this), +- new EditDomainHandler(this), +- new SearchDomainHandler(this), +- new CompletionDomainHandler(this), +- new ExecutionDomainHandler(this), +- new DiagnosticDomainHandler(this), +- new AnalyticsDomainHandler(this), +- new KytheDomainHandler(this) +- ]; +- } +- +- /** +- * Return a list of the globs used to determine which files should be analyzed. +- */ +- List get analyzedFilesGlobs { +- if (_analyzedFilesGlobs == null) { +- _analyzedFilesGlobs = []; +- List patterns = [ +- '**/*.${AnalysisEngine.SUFFIX_DART}', +- '**/*.${AnalysisEngine.SUFFIX_HTML}', +- '**/*.${AnalysisEngine.SUFFIX_HTM}', +- '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}', +- '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}' +- ]; +- for (String pattern in patterns) { +- try { +- _analyzedFilesGlobs +- .add(new Glob(resourceProvider.pathContext.separator, pattern)); +- } catch (exception, stackTrace) { +- AnalysisEngine.instance.logger.logError( +- 'Invalid glob pattern: "$pattern"', +- new CaughtException(exception, stackTrace)); +- } +- } +- } +- return _analyzedFilesGlobs; +- } +- +- /** +- * A table mapping [Folder]s to the [AnalysisDriver]s associated with them. +- */ +- Map get driverMap => contextManager.driverMap; +- +- /** +- * The [Future] that completes when analysis is complete. +- */ +- Future get onAnalysisComplete { +- if (isAnalysisComplete()) { +- return new Future.value(); +- } +- if (_onAnalysisCompleteCompleter == null) { +- _onAnalysisCompleteCompleter = new Completer(); +- } +- return _onAnalysisCompleteCompleter.future; +- } +- +- /** +- * The stream that is notified when the analysis set is changed - this might +- * be a change to a file, external via a watch event, or internal via +- * overlay. This means that the resolved world might have changed. +- * +- * The type of produced elements is not specified and should not be used. +- */ +- Stream get onAnalysisSetChanged => _onAnalysisSetChangedController.stream; +- +- /** +- * The stream that is notified with `true` when analysis is started. +- */ +- Stream get onAnalysisStarted { +- return _onAnalysisStartedController.stream; +- } +- +- /** +- * The stream that is notified when a single file has been added. This exists +- * as a temporary stopgap for plugins, until the official plugin API is +- * complete. +- */ +- Stream get onFileAdded => _onFileAddedController.stream; +- +- /** +- * The stream that is notified when a single file has been analyzed. +- */ +- Stream get onFileAnalyzed => _onFileAnalyzedController.stream; +- +- /** +- * The stream that is notified when a single file has been changed. This +- * exists as a temporary stopgap for plugins, until the official plugin API is +- * complete. +- */ +- Stream get onFileChanged => _onFileChangedController.stream; +- +- /** +- * Return the total time the server's been alive. +- */ +- Duration get uptime { +- DateTime start = new DateTime.fromMillisecondsSinceEpoch( +- performanceDuringStartup.startTime); +- return new DateTime.now().difference(start); +- } +- +- /** +- * The socket from which requests are being read has been closed. +- */ +- void done() { +- running = false; +- } +- +- /** +- * There was an error related to the socket from which requests are being +- * read. +- */ +- void error(argument) { +- running = false; +- } +- +- /** +- * If the given notice applies to a file contained within an analysis root, +- * notify interested parties that the file has been (at least partially) +- * analyzed. +- */ +- void fileAnalyzed(ChangeNotice notice) { +- if (contextManager.isInAnalysisRoot(notice.source.fullName)) { +- _onFileAnalyzedController.add(notice); +- } +- } +- +- /** +- * Return one of the SDKs that has been created, or `null` if no SDKs have +- * been created yet. +- */ +- DartSdk findSdk() { +- DartSdk sdk = sdkManager.anySdk; +- if (sdk != null) { +- return sdk; +- } +- // TODO(brianwilkerson) Should we create an SDK using the default options? +- return null; +- } +- +- /** +- * Return an analysis driver to which the file with the given [path] is +- * added if one exists, otherwise a driver in which the file was analyzed if +- * one exists, otherwise the first driver, otherwise `null`. +- */ +- nd.AnalysisDriver getAnalysisDriver(String path) { +- List drivers = driverMap.values.toList(); +- if (drivers.isNotEmpty) { +- // Sort the drivers so that more deeply nested contexts will be checked +- // before enclosing contexts. +- drivers.sort((first, second) => +- second.contextRoot.root.length - first.contextRoot.root.length); +- nd.AnalysisDriver driver = drivers.firstWhere( +- (driver) => driver.contextRoot.containsFile(path), +- orElse: () => null); +- driver ??= drivers.firstWhere( +- (driver) => driver.knownFiles.contains(path), +- orElse: () => null); +- driver ??= drivers.first; +- return driver; +- } +- return null; +- } +- +- /** +- * Return the analysis result for the file with the given [path]. The file is +- * analyzed in one of the analysis drivers to which the file was added, +- * otherwise in the first driver, otherwise `null` is returned. +- */ +- Future getAnalysisResult(String path, +- {bool sendCachedToStream: false}) async { +- if (!AnalysisEngine.isDartFileName(path)) { +- return null; +- } +- +- try { +- nd.AnalysisDriver driver = getAnalysisDriver(path); +- return await driver?.getResult(path, +- sendCachedToStream: sendCachedToStream); +- } catch (e) { +- // Ignore the exception. +- // We don't want to log the same exception again and again. +- return null; +- } +- } +- +- /** +- * Return the [AstProvider] for the given [path]. +- */ +- AstProvider getAstProvider(String path) { +- nd.AnalysisDriver analysisDriver = getAnalysisDriver(path); +- return new AstProviderForDriver(analysisDriver); +- } +- +- /** +- * Return the cached analysis result for the file with the given [path]. +- * If there is no cached result, return `null`. +- */ +- nd.AnalysisResult getCachedAnalysisResult(String path) { +- if (!AnalysisEngine.isDartFileName(path)) { +- return null; +- } +- +- nd.AnalysisDriver driver = getAnalysisDriver(path); +- return driver?.getCachedResult(path); +- } +- +- /** +- * Return the [nd.AnalysisDriver] for the "innermost" context whose associated +- * folder is or contains the given path. ("innermost" refers to the nesting +- * of contexts, so if there is a context for path /foo and a context for +- * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is +- * the context for /foo/bar.) +- * +- * If no context contains the given path, `null` is returned. +- */ +- nd.AnalysisDriver getContainingDriver(String path) { +- return contextManager.getDriverFor(path); +- } +- +- /** +- * Return a [Future] that completes with the [Element] at the given +- * [offset] of the given [file], or with `null` if there is no node at the +- * [offset] or the node does not have an element. +- */ +- Future getElementAtOffset(String file, int offset) async { +- AstNode node = await getNodeAtOffset(file, offset); +- return getElementOfNode(node); +- } +- +- /** +- * Return the [Element] of the given [node], or `null` if [node] is `null` or +- * does not have an element. +- */ +- Element getElementOfNode(AstNode node) { +- if (node == null) { +- return null; +- } +- if (node is SimpleIdentifier && node.parent is LibraryIdentifier) { +- node = node.parent; +- } +- if (node is LibraryIdentifier) { +- node = node.parent; +- } +- if (node is StringLiteral && node.parent is UriBasedDirective) { +- return null; +- } +- Element element = ElementLocator.locate(node); +- if (node is SimpleIdentifier && element is PrefixElement) { +- element = getImportElement(node); +- } +- return element; +- } +- +- /** +- * Return a [Future] that completes with the resolved [AstNode] at the +- * given [offset] of the given [file], or with `null` if there is no node as +- * the [offset]. +- */ +- Future getNodeAtOffset(String file, int offset) async { +- nd.AnalysisResult result = await getAnalysisResult(file); +- CompilationUnit unit = result?.unit; +- if (unit != null) { +- return new NodeLocator(offset).searchWithin(unit); +- } +- return null; +- } +- +- /** +- * Return a [Future] that completes with the resolved [CompilationUnit] for +- * the Dart file with the given [path], or with `null` if the file is not a +- * Dart file or cannot be resolved. +- */ +- Future getResolvedCompilationUnit(String path) async { +- nd.AnalysisResult result = await getAnalysisResult(path); +- return result?.unit; +- } +- +- /** +- * Handle a [request] that was read from the communication channel. +- */ +- void handleRequest(Request request) { +- _performance.logRequest(request); +- runZoned(() { +- ServerPerformanceStatistics.serverRequests.makeCurrentWhile(() { +- int count = handlers.length; +- for (int i = 0; i < count; i++) { +- try { +- Response response = handlers[i].handleRequest(request); +- if (response == Response.DELAYED_RESPONSE) { +- return; +- } +- if (response != null) { +- channel.sendResponse(response); +- return; +- } +- } on RequestFailure catch (exception) { +- channel.sendResponse(exception.response); +- return; +- } catch (exception, stackTrace) { +- RequestError error = new RequestError( +- RequestErrorCode.SERVER_ERROR, exception.toString()); +- if (stackTrace != null) { +- error.stackTrace = stackTrace.toString(); +- } +- Response response = new Response(request.id, error: error); +- channel.sendResponse(response); +- return; +- } +- } +- channel.sendResponse(new Response.unknownRequest(request)); +- }); +- }, onError: (exception, stackTrace) { +- sendServerErrorNotification( +- 'Failed to handle request: ${request.toJson()}', +- exception, +- stackTrace, +- fatal: true); +- }); +- } +- +- /** +- * Returns `true` if there is a subscription for the given [service] and +- * [file]. +- */ +- bool hasAnalysisSubscription(AnalysisService service, String file) { +- Set files = analysisServices[service]; +- return files != null && files.contains(file); +- } +- +- /** +- * Return `true` if analysis is complete. +- */ +- bool isAnalysisComplete() { +- return !analysisDriverScheduler.isAnalyzing; +- } +- +- /** +- * Return `true` if the given path is a valid `FilePath`. +- * +- * This means that it is absolute and normalized. +- */ +- bool isValidFilePath(String path) { +- return resourceProvider.absolutePathContext.isValid(path); +- } +- +- /** +- * Trigger reanalysis of all files in the given list of analysis [roots], or +- * everything if the analysis roots is `null`. +- */ +- void reanalyze(List roots) { +- // Instruct the contextDirectoryManager to rebuild all contexts from +- // scratch. +- contextManager.refresh(roots); +- } +- +- /** +- * Send the given [notification] to the client. +- */ +- void sendNotification(Notification notification) { +- channel.sendNotification(notification); +- } +- +- /** +- * Send the given [response] to the client. +- */ +- void sendResponse(Response response) { +- channel.sendResponse(response); +- } +- +- /** +- * Sends a `server.error` notification. +- */ +- void sendServerErrorNotification(String message, exception, stackTrace, +- {bool fatal: false}) { +- StringBuffer buffer = new StringBuffer(); +- buffer.write(exception ?? 'null exception'); +- if (stackTrace != null) { +- buffer.writeln(); +- buffer.write(stackTrace); +- } else if (exception is! CaughtException) { +- stackTrace = StackTrace.current; +- buffer.writeln(); +- buffer.write(stackTrace); +- } +- +- // send the notification +- channel.sendNotification( +- new ServerErrorParams(fatal, message, buffer.toString()) +- .toNotification()); +- +- // send to crash reporting +- if (options.crashReportSender != null) { +- // Catch and ignore any exceptions when reporting exceptions (network +- // errors or other). +- options.crashReportSender +- .sendReport(exception, stackTrace: stackTrace) +- .catchError((_) {}); +- } +- +- // remember the last few exceptions +- if (exception is CaughtException) { +- stackTrace ??= exception.stackTrace; +- } +- exceptions.add(new ServerException(message, exception, stackTrace, fatal)); +- } +- +- /** +- * Send status notification to the client. The state of analysis is given by +- * the [status] information. +- */ +- void sendStatusNotificationNew(nd.AnalysisStatus status) { +- if (status.isAnalyzing) { +- _onAnalysisStartedController.add(true); +- } +- if (_onAnalysisCompleteCompleter != null && !status.isAnalyzing) { +- _onAnalysisCompleteCompleter.complete(); +- _onAnalysisCompleteCompleter = null; +- } +- // Perform on-idle actions. +- if (!status.isAnalyzing) { +- if (generalAnalysisServices +- .contains(GeneralAnalysisService.ANALYZED_FILES)) { +- sendAnalysisNotificationAnalyzedFiles(this); +- } +- _scheduleAnalysisImplementedNotification(); +- } +- // Only send status when subscribed. +- if (!serverServices.contains(ServerService.STATUS)) { +- return; +- } +- // Only send status when it changes +- if (statusAnalyzing == status.isAnalyzing) { +- return; +- } +- statusAnalyzing = status.isAnalyzing; +- AnalysisStatus analysis = new AnalysisStatus(status.isAnalyzing); +- channel.sendNotification( +- new ServerStatusParams(analysis: analysis).toNotification()); +- } +- +- /** +- * Implementation for `analysis.setAnalysisRoots`. +- * +- * TODO(scheglov) implement complete projects/contexts semantics. +- * +- * The current implementation is intentionally simplified and expected +- * that only folders are given each given folder corresponds to the exactly +- * one context. +- * +- * So, we can start working in parallel on adding services and improving +- * projects/contexts support. +- */ +- void setAnalysisRoots(String requestId, List includedPaths, +- List excludedPaths, Map packageRoots) { +- if (notificationManager != null) { +- notificationManager.setAnalysisRoots(includedPaths, excludedPaths); +- } +- try { +- contextManager.setRoots(includedPaths, excludedPaths, packageRoots); +- } on UnimplementedError catch (e) { +- throw new RequestFailure( +- new Response.unsupportedFeature(requestId, e.message)); +- } +- } +- +- /** +- * Implementation for `analysis.setSubscriptions`. +- */ +- void setAnalysisSubscriptions( +- Map> subscriptions) { +- if (notificationManager != null) { +- notificationManager.setSubscriptions(subscriptions); +- } +- this.analysisServices = subscriptions; +- Set allNewFiles = +- subscriptions.values.expand((files) => files).toSet(); +- for (String file in allNewFiles) { +- // The result will be produced by the "results" stream with +- // the fully resolved unit, and processed with sending analysis +- // notifications as it happens after content changes. +- if (AnalysisEngine.isDartFileName(file)) { +- getAnalysisResult(file, sendCachedToStream: true); +- } +- } +- } +- +- /** +- * Implementation for `analysis.setGeneralSubscriptions`. +- */ +- void setGeneralAnalysisSubscriptions( +- List subscriptions) { +- Set newServices = subscriptions.toSet(); +- if (newServices.contains(GeneralAnalysisService.ANALYZED_FILES) && +- !generalAnalysisServices +- .contains(GeneralAnalysisService.ANALYZED_FILES) && +- isAnalysisComplete()) { +- sendAnalysisNotificationAnalyzedFiles(this); +- } else if (!newServices.contains(GeneralAnalysisService.ANALYZED_FILES) && +- generalAnalysisServices +- .contains(GeneralAnalysisService.ANALYZED_FILES)) { +- prevAnalyzedFiles = null; +- } +- generalAnalysisServices = newServices; +- } +- +- /** +- * Set the priority files to the given [files]. +- */ +- void setPriorityFiles(String requestId, List files) { +- priorityFiles.clear(); +- priorityFiles.addAll(files); +- // Set priority files in drivers. +- driverMap.values.forEach((driver) { +- driver.priorityFiles = files; +- }); +- } +- +- /** +- * Returns `true` if errors should be reported for [file] with the given +- * absolute path. +- */ +- bool shouldSendErrorsNotificationFor(String file) { +- return contextManager.isInAnalysisRoot(file); +- } +- +- Future shutdown() async { +- running = false; +- +- await options.analytics +- ?.waitForLastPing(timeout: new Duration(milliseconds: 200)); +- options.analytics?.close(); +- +- // Defer closing the channel and shutting down the instrumentation server so +- // that the shutdown response can be sent and logged. +- new Future(() { +- instrumentationService.shutdown(); +- channel.close(); +- }); +- } +- +- /** +- * Implementation for `analysis.updateContent`. +- */ +- void updateContent(String id, Map changes) { +- _onAnalysisSetChangedController.add(null); +- changes.forEach((file, change) { +- // Prepare the new contents. +- String oldContents = fileContentOverlay[file]; +- String newContents; +- if (change is AddContentOverlay) { +- newContents = change.content; +- } else if (change is ChangeContentOverlay) { +- if (oldContents == null) { +- // The client may only send a ChangeContentOverlay if there is +- // already an existing overlay for the source. +- throw new RequestFailure(new Response(id, +- error: new RequestError(RequestErrorCode.INVALID_OVERLAY_CHANGE, +- 'Invalid overlay change'))); +- } +- try { +- newContents = SourceEdit.applySequence(oldContents, change.edits); +- } on RangeError { +- throw new RequestFailure(new Response(id, +- error: new RequestError(RequestErrorCode.INVALID_OVERLAY_CHANGE, +- 'Invalid overlay change'))); +- } +- } else if (change is RemoveContentOverlay) { +- newContents = null; +- } else { +- // Protocol parsing should have ensured that we never get here. +- throw new AnalysisException('Illegal change type'); +- } +- +- fileContentOverlay[file] = newContents; +- +- driverMap.values.forEach((driver) { +- driver.changeFile(file); +- }); +- +- // temporary plugin support: +- _onFileChangedController.add(file); +- +- // If the file did not exist, and is "overlay only", it still should be +- // analyzed. Add it to driver to which it should have been added. +- contextManager.getDriverFor(file)?.addFile(file); +- +- // TODO(scheglov) implement other cases +- }); +- } +- +- /** +- * Use the given updaters to update the values of the options in every +- * existing analysis context. +- */ +- void updateOptions(List optionUpdaters) { +- // TODO(scheglov) implement for the new analysis driver +-// // +-// // Update existing contexts. +-// // +-// for (AnalysisContext context in analysisContexts) { +-// AnalysisOptionsImpl options = +-// new AnalysisOptionsImpl.from(context.analysisOptions); +-// optionUpdaters.forEach((OptionUpdater optionUpdater) { +-// optionUpdater(options); +-// }); +-// context.analysisOptions = options; +-// // TODO(brianwilkerson) As far as I can tell, this doesn't cause analysis +-// // to be scheduled for this context. +-// } +-// // +-// // Update the defaults used to create new contexts. +-// // +-// optionUpdaters.forEach((OptionUpdater optionUpdater) { +-// optionUpdater(defaultContextOptions); +-// }); +- } +- +- void _computingPackageMap(bool computing) { +- if (serverServices.contains(ServerService.STATUS)) { +- PubStatus pubStatus = new PubStatus(computing); +- ServerStatusParams params = new ServerStatusParams(pub: pubStatus); +- sendNotification(params.toNotification()); +- } +- } +- +- /** +- * If the state location can be accessed, return the file byte store, +- * otherwise return the memory byte store. +- */ +- ByteStore _createByteStore() { +- const int M = 1024 * 1024 /*1 MiB*/; +- const int G = 1024 * 1024 * 1024 /*1 GiB*/; +- if (resourceProvider is PhysicalResourceProvider) { +- Folder stateLocation = +- resourceProvider.getStateLocation('.analysis-driver'); +- if (stateLocation != null) { +- return new MemoryCachingByteStore( +- new EvictingFileByteStore(stateLocation.path, G), 64 * M); +- } +- } +- return new MemoryCachingByteStore(new NullByteStore(), 64 * M); +- } +- +- /** +- * Return the path to the location of the byte store on disk, or `null` if +- * there is no on-disk byte store. +- */ +- String _getByteStorePath() { +- if (resourceProvider is PhysicalResourceProvider) { +- Folder stateLocation = +- resourceProvider.getStateLocation('.analysis-driver'); +- if (stateLocation != null) { +- return stateLocation.path; +- } +- } +- return null; +- } +- +- bool _hasAnalysisServiceSubscription(AnalysisService service, String file) { +- return analysisServices[service]?.contains(file) ?? false; +- } +- +- _scheduleAnalysisImplementedNotification() async { +- Set files = analysisServices[AnalysisService.IMPLEMENTED]; +- if (files != null) { +- scheduleImplementedNotification(this, files); +- } +- } +-} +- +-/** +- * Various IDE options. +- */ +-class AnalysisServerOptions { +- bool useAnalysisHighlight2 = false; +- +- String fileReadMode = 'as-is'; +- String newAnalysisDriverLog; +- +- String clientId; +- String clientVersion; +- +- /** +- * Base path where to cache data. +- */ +- String cacheFolder; +- +- /** +- * The analytics instance; note, this object can be `null`, and should be +- * accessed via a null-aware operator. +- */ +- telemetry.Analytics analytics; +- +- /** +- * The crash report sender instance; note, this object can be `null`, and +- * should be accessed via a null-aware operator. +- */ +- CrashReportSender crashReportSender; +- +- /** +- * Whether to enable the Dart 2.0 Front End. +- */ +- bool previewDart2 = false; +-} +- +-/** +- * A [PriorityChangeEvent] indicates the set the priority files has changed. +- */ +-class PriorityChangeEvent { +- final Source firstSource; +- +- PriorityChangeEvent(this.firstSource); +-} +- +-class ServerContextManagerCallbacks extends ContextManagerCallbacks { +- final AnalysisServer analysisServer; +- +- /** +- * The [ResourceProvider] by which paths are converted into [Resource]s. +- */ +- final ResourceProvider resourceProvider; +- +- ServerContextManagerCallbacks(this.analysisServer, this.resourceProvider); +- +- @override +- NotificationManager get notificationManager => +- analysisServer.notificationManager; +- +- @override +- nd.AnalysisDriver addAnalysisDriver( +- Folder folder, ContextRoot contextRoot, AnalysisOptions options) { +- ContextBuilder builder = createContextBuilder(folder, options); +- nd.AnalysisDriver analysisDriver = builder.buildDriver(contextRoot); +- analysisDriver.results.listen((result) { +- NotificationManager notificationManager = +- analysisServer.notificationManager; +- String path = result.path; +- if (analysisServer.shouldSendErrorsNotificationFor(path)) { +- if (notificationManager != null) { +- notificationManager.recordAnalysisErrors( +- NotificationManager.serverId, +- path, +- server.doAnalysisError_listFromEngine( +- result.driver.analysisOptions, +- result.lineInfo, +- result.errors)); +- } else { +- new_sendErrorNotification(analysisServer, result); +- } +- } +- CompilationUnit unit = result.unit; +- if (unit != null) { +- if (notificationManager != null) { +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.HIGHLIGHTS, path)) { +- _runDelayed(() { +- notificationManager.recordHighlightRegions( +- NotificationManager.serverId, +- path, +- _computeHighlightRegions(unit)); +- }); +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.NAVIGATION, path)) { +- _runDelayed(() { +- notificationManager.recordNavigationParams( +- NotificationManager.serverId, +- path, +- _computeNavigationParams(path, unit)); +- }); +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.OCCURRENCES, path)) { +- _runDelayed(() { +- notificationManager.recordOccurrences( +- NotificationManager.serverId, +- path, +- _computeOccurrences(unit)); +- }); +- } +-// if (analysisServer._hasAnalysisServiceSubscription( +-// AnalysisService.OUTLINE, path)) { +-// _runDelayed(() { +-// // TODO(brianwilkerson) Change NotificationManager to store params +-// // so that fileKind and libraryName can be recorded / passed along. +-// notificationManager.recordOutlines(NotificationManager.serverId, +-// path, _computeOutlineParams(path, unit, result.lineInfo)); +-// }); +-// } +- } else { +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.HIGHLIGHTS, path)) { +- _runDelayed(() { +- sendAnalysisNotificationHighlights(analysisServer, path, unit); +- }); +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.NAVIGATION, path)) { +- _runDelayed(() { +- new_sendDartNotificationNavigation(analysisServer, result); +- }); +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.OCCURRENCES, path)) { +- _runDelayed(() { +- new_sendDartNotificationOccurrences(analysisServer, result); +- }); +- } +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.CLOSING_LABELS, path)) { +- _runDelayed(() { +- sendAnalysisNotificationClosingLabels( +- analysisServer, path, result.lineInfo, unit); +- }); +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.OUTLINE, path)) { +- _runDelayed(() { +- SourceKind sourceKind = +- unit.directives.any((d) => d is PartOfDirective) +- ? SourceKind.PART +- : SourceKind.LIBRARY; +- sendAnalysisNotificationOutline( +- analysisServer, path, result.lineInfo, sourceKind, unit); +- }); +- } +- if (analysisServer._hasAnalysisServiceSubscription( +- AnalysisService.OVERRIDES, path)) { +- _runDelayed(() { +- sendAnalysisNotificationOverrides(analysisServer, path, unit); +- }); +- } +- // TODO(scheglov) Implement notifications for AnalysisService.IMPLEMENTED. +- } +- }); +- analysisDriver.exceptions.listen((nd.ExceptionResult result) { +- String message = 'Analysis failed: ${result.path}'; +- if (result.contextKey != null) { +- message += ' context: ${result.contextKey}'; +- } +- AnalysisEngine.instance.logger.logError(message, result.exception); +- }); +- analysisServer.driverMap[folder] = analysisDriver; +- return analysisDriver; +- } +- +- @override +- void afterWatchEvent(WatchEvent event) { +- analysisServer._onAnalysisSetChangedController.add(null); +- } +- +- @override +- void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { +- nd.AnalysisDriver analysisDriver = analysisServer.driverMap[contextFolder]; +- if (analysisDriver != null) { +- changeSet.addedSources.forEach((source) { +- analysisDriver.addFile(source.fullName); +- // temporary plugin support: +- analysisServer._onFileAddedController.add(source.fullName); +- }); +- changeSet.changedSources.forEach((source) { +- analysisDriver.changeFile(source.fullName); +- // temporary plugin support: +- analysisServer._onFileChangedController.add(source.fullName); +- }); +- changeSet.removedSources.forEach((source) { +- analysisDriver.removeFile(source.fullName); +- }); +- } +- } +- +- @override +- void applyFileRemoved(nd.AnalysisDriver driver, String file) { +- driver.removeFile(file); +- sendAnalysisNotificationFlushResults(analysisServer, [file]); +- } +- +- @override +- void broadcastWatchEvent(WatchEvent event) { +- analysisServer.pluginManager.broadcastWatchEvent(event); +- } +- +- @override +- void computingPackageMap(bool computing) => +- analysisServer._computingPackageMap(computing); +- +- @override +- ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) { +- String defaultPackageFilePath = null; +- String defaultPackagesDirectoryPath = null; +- String path = (analysisServer.contextManager as ContextManagerImpl) +- .normalizedPackageRoots[folder.path]; +- if (path != null) { +- Resource resource = resourceProvider.getResource(path); +- if (resource.exists) { +- if (resource is File) { +- defaultPackageFilePath = path; +- } else { +- defaultPackagesDirectoryPath = path; +- } +- } +- } +- +- ContextBuilderOptions builderOptions = new ContextBuilderOptions(); +- builderOptions.defaultOptions = options; +- builderOptions.defaultPackageFilePath = defaultPackageFilePath; +- builderOptions.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath; +- ContextBuilder builder = new ContextBuilder(resourceProvider, +- analysisServer.sdkManager, analysisServer.overlayState, +- options: builderOptions); +- builder.fileResolverProvider = analysisServer.fileResolverProvider; +- builder.packageResolverProvider = analysisServer.packageResolverProvider; +- builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler; +- builder.performanceLog = analysisServer._analysisPerformanceLogger; +- builder.byteStore = analysisServer.byteStore; +- builder.fileContentOverlay = analysisServer.fileContentOverlay; +- builder.previewDart2 = analysisServer.options.previewDart2; +- return builder; +- } +- +- @override +- void moveContext(Folder from, Folder to) { +- // There is nothing to do. +- // This method is mostly for tests. +- // Context managers manage folders and contexts themselves. +- } +- +- @override +- void removeContext(Folder folder, List flushedFiles) { +- sendAnalysisNotificationFlushResults(analysisServer, flushedFiles); +- nd.AnalysisDriver driver = analysisServer.driverMap.remove(folder); +- driver.dispose(); +- } +- +- List _computeHighlightRegions(CompilationUnit unit) { +- if (analysisServer.options.useAnalysisHighlight2) { +- return new DartUnitHighlightsComputer2(unit).compute(); +- } else { +- return new DartUnitHighlightsComputer(unit).compute(); +- } +- } +- +- String _computeLibraryName(CompilationUnit unit) { +- for (Directive directive in unit.directives) { +- if (directive is LibraryDirective && directive.name != null) { +- return directive.name.name; +- } +- } +- for (Directive directive in unit.directives) { +- if (directive is PartOfDirective && directive.libraryName != null) { +- return directive.libraryName.name; +- } +- } +- return null; +- } +- +- server.AnalysisNavigationParams _computeNavigationParams( +- String path, CompilationUnit unit) { +- NavigationCollectorImpl collector = new NavigationCollectorImpl(); +- computeDartNavigation(collector, unit, null, null); +- collector.createRegions(); +- return new server.AnalysisNavigationParams( +- path, collector.regions, collector.targets, collector.files); +- } +- +- List _computeOccurrences(CompilationUnit unit) { +- OccurrencesCollectorImpl collector = new OccurrencesCollectorImpl(); +- addDartOccurrences(collector, unit); +- return collector.allOccurrences; +- } +- +- // ignore: unused_element +- server.AnalysisOutlineParams _computeOutlineParams( +- String path, CompilationUnit unit, LineInfo lineInfo) { +- // compute FileKind +- SourceKind sourceKind = unit.directives.any((d) => d is PartOfDirective) +- ? SourceKind.PART +- : SourceKind.LIBRARY; +- server.FileKind fileKind = server.FileKind.LIBRARY; +- if (sourceKind == SourceKind.LIBRARY) { +- fileKind = server.FileKind.LIBRARY; +- } else if (sourceKind == SourceKind.PART) { +- fileKind = server.FileKind.PART; +- } +- // compute library name +- String libraryName = _computeLibraryName(unit); +- // compute Outline +- DartUnitOutlineComputer computer = +- new DartUnitOutlineComputer(path, lineInfo, unit); +- server.Outline outline = computer.compute(); +- return new server.AnalysisOutlineParams(path, fileKind, outline, +- libraryName: libraryName); +- } +- +- /** +- * Run [f] in a new [Future]. +- * +- * This method is used to delay sending notifications. If there is a more +- * important consumer of an analysis results, specifically a code completion +- * computer, we want it to run before spending time of sending notifications. +- * +- * TODO(scheglov) Consider replacing this with full priority based scheduler. +- * +- * TODO(scheglov) Alternatively, if code completion work in a way that does +- * not produce (at first) fully resolved unit, but only part of it - a single +- * method, or a top-level declaration, we would not have this problem - the +- * completion computer would be the only consumer of the partial analysis +- * result. +- */ +- void _runDelayed(f()) { +- new Future(f); +- } +-} +- +-/** +- * Used to record server exceptions. +- */ +-class ServerException { +- final String message; +- final dynamic exception; +- final StackTrace stackTrace; +- final bool fatal; +- +- ServerException(this.message, this.exception, this.stackTrace, this.fatal); +- +- @override +- String toString() => message; +-} +- +-/** +- * A class used by [AnalysisServer] to record performance information +- * such as request latency. +- */ +-class ServerPerformance { +- /** +- * The creation time and the time when performance information +- * started to be recorded here. +- */ +- int startTime = new DateTime.now().millisecondsSinceEpoch; +- +- /** +- * The number of requests. +- */ +- int requestCount = 0; +- +- /** +- * The total latency (milliseconds) for all recorded requests. +- */ +- int requestLatency = 0; +- +- /** +- * The maximum latency (milliseconds) for all recorded requests. +- */ +- int maxLatency = 0; +- +- /** +- * The number of requests with latency > 150 milliseconds. +- */ +- int slowRequestCount = 0; +- +- /** +- * Log performance information about the given request. +- */ +- void logRequest(Request request) { +- ++requestCount; +- if (request.clientRequestTime != null) { +- int latency = +- new DateTime.now().millisecondsSinceEpoch - request.clientRequestTime; +- requestLatency += latency; +- maxLatency = max(maxLatency, latency); +- if (latency > 150) { +- ++slowRequestCount; +- } +- } +- } +-} +- +-/** +- * Container with global [AnalysisServer] performance statistics. +- */ +-class ServerPerformanceStatistics { +- /** +- * The [PerformanceTag] for `package:analysis_server`. +- */ +- static PerformanceTag server = new PerformanceTag('server'); +- +- /** +- * The [PerformanceTag] for time spent in [ExecutionDomainHandler]. +- */ +- static PerformanceTag executionNotifications = +- new PerformanceTag('executionNotifications'); +- +- /** +- * The [PerformanceTag] for time spent performing a _DartIndexOperation. +- */ +- static PerformanceTag indexOperation = new PerformanceTag('indexOperation'); +- +- /** +- * The [PerformanceTag] for time spent between calls to +- * AnalysisServer.performOperation when the server is not idle. +- */ +- static PerformanceTag intertask = new PerformanceTag('intertask'); +- +- /** +- * The [PerformanceTag] for time spent between calls to +- * AnalysisServer.performOperation when the server is idle. +- */ +- static PerformanceTag idle = new PerformanceTag('idle'); +- +- /** +- * The [PerformanceTag] for time spent in +- * PerformAnalysisOperation._sendNotices. +- */ +- static PerformanceTag notices = server.createChild('notices'); +- +- /** +- * The [PerformanceTag] for time spent running pub. +- */ +- static PerformanceTag pub = server.createChild('pub'); +- +- /** +- * The [PerformanceTag] for time spent in server communication channels. +- */ +- static PerformanceTag serverChannel = server.createChild('channel'); +- +- /** +- * The [PerformanceTag] for time spent in server request handlers. +- */ +- static PerformanceTag serverRequests = server.createChild('requests'); +- +- /** +- * The [PerformanceTag] for time spent in split store microtasks. +- */ +- static PerformanceTag splitStore = new PerformanceTag('splitStore'); +-} +diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart +deleted file mode 100644 +index dce7e5912e1..00000000000 +--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart ++++ /dev/null +@@ -1,175 +0,0 @@ +-// Copyright (c) 2014, 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:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/channel/channel.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +- +-/** +- * Instances of the class [ByteStreamClientChannel] implement a +- * [ClientCommunicationChannel] that uses a stream and a sink (typically, +- * standard input and standard output) to communicate with servers. +- */ +-class ByteStreamClientChannel implements ClientCommunicationChannel { +- final Stream input; +- final IOSink output; +- +- @override +- Stream responseStream; +- +- @override +- Stream notificationStream; +- +- ByteStreamClientChannel(this.input, this.output) { +- Stream jsonStream = input +- .transform(const Utf8Decoder()) +- .transform(new LineSplitter()) +- .transform(new JsonStreamDecoder()) +- .where((json) => json is Map) +- .asBroadcastStream(); +- responseStream = jsonStream +- .where((json) => json[Notification.EVENT] == null) +- .transform(new ResponseConverter()) +- .asBroadcastStream(); +- notificationStream = jsonStream +- .where((json) => json[Notification.EVENT] != null) +- .transform(new NotificationConverter()) +- .asBroadcastStream(); +- } +- +- @override +- Future close() { +- return output.close(); +- } +- +- @override +- Future sendRequest(Request request) async { +- String id = request.id; +- output.write(JSON.encode(request.toJson()) + '\n'); +- return await responseStream +- .firstWhere((Response response) => response.id == id); +- } +-} +- +-/** +- * Instances of the class [ByteStreamServerChannel] implement a +- * [ServerCommunicationChannel] that uses a stream and a sink (typically, +- * standard input and standard output) to communicate with clients. +- */ +-class ByteStreamServerChannel implements ServerCommunicationChannel { +- final Stream _input; +- +- final IOSink _output; +- +- /** +- * The instrumentation service that is to be used by this analysis server. +- */ +- final InstrumentationService _instrumentationService; +- +- /** +- * Completer that will be signalled when the input stream is closed. +- */ +- final Completer _closed = new Completer(); +- +- /** +- * True if [close] has been called. +- */ +- bool _closeRequested = false; +- +- ByteStreamServerChannel( +- this._input, this._output, this._instrumentationService); +- +- /** +- * Future that will be completed when the input stream is closed. +- */ +- Future get closed { +- return _closed.future; +- } +- +- @override +- void close() { +- if (!_closeRequested) { +- _closeRequested = true; +- assert(!_closed.isCompleted); +- _closed.complete(); +- } +- } +- +- @override +- void listen(void onRequest(Request request), +- {Function onError, void onDone()}) { +- _input.transform(const Utf8Decoder()).transform(new LineSplitter()).listen( +- (String data) => _readRequest(data, onRequest), +- onError: onError, onDone: () { +- close(); +- onDone(); +- }); +- } +- +- @override +- void sendNotification(Notification notification) { +- // Don't send any further notifications after the communication channel is +- // closed. +- if (_closeRequested) { +- return; +- } +- ServerPerformanceStatistics.serverChannel.makeCurrentWhile(() { +- String jsonEncoding = JSON.encode(notification.toJson()); +- _outputLine(jsonEncoding); +- _instrumentationService.logNotification(jsonEncoding); +- }); +- } +- +- @override +- void sendResponse(Response response) { +- // Don't send any further responses after the communication channel is +- // closed. +- if (_closeRequested) { +- return; +- } +- ServerPerformanceStatistics.serverChannel.makeCurrentWhile(() { +- String jsonEncoding = JSON.encode(response.toJson()); +- _outputLine(jsonEncoding); +- _instrumentationService.logResponse(jsonEncoding); +- }); +- } +- +- /** +- * Send the string [s] to [_output] followed by a newline. +- */ +- void _outputLine(String s) { +- runZoned(() { +- _output.writeln(s); +- }, onError: (e) { +- close(); +- }); +- } +- +- /** +- * Read a request from the given [data] and use the given function to handle +- * the request. +- */ +- void _readRequest(Object data, void onRequest(Request request)) { +- // Ignore any further requests after the communication channel is closed. +- if (_closed.isCompleted) { +- return; +- } +- ServerPerformanceStatistics.serverChannel.makeCurrentWhile(() { +- _instrumentationService.logRequest(data); +- // Parse the string as a JSON descriptor and process the resulting +- // structure as a request. +- Request request = new Request.fromString(data); +- if (request == null) { +- sendResponse(new Response.invalidRequestFormat()); +- return; +- } +- onRequest(request); +- }); +- } +-} +diff --git a/pkg/analysis_server/lib/src/channel/channel.dart b/pkg/analysis_server/lib/src/channel/channel.dart +deleted file mode 100644 +index ca75739e2a5..00000000000 +--- a/pkg/analysis_server/lib/src/channel/channel.dart ++++ /dev/null +@@ -1,150 +0,0 @@ +-// Copyright (c) 2014, 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:convert'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +- +-/** +- * Instances of the class [ChannelChunkSink] uses a [Converter] to translate +- * chunks. +- */ +-class ChannelChunkSink extends ChunkedConversionSink { +- /** +- * The converter used to translate chunks. +- */ +- final Converter converter; +- +- /** +- * The sink to which the converted chunks are added. +- */ +- final Sink sink; +- +- /** +- * A flag indicating whether the sink has been closed. +- */ +- bool closed = false; +- +- /** +- * Initialize a newly create sink to use the given [converter] to convert +- * chunks before adding them to the given [sink]. +- */ +- ChannelChunkSink(this.converter, this.sink); +- +- @override +- void add(S chunk) { +- if (!closed) { +- T convertedChunk = converter.convert(chunk); +- if (convertedChunk != null) { +- sink.add(convertedChunk); +- } +- } +- } +- +- @override +- void close() { +- closed = true; +- sink.close(); +- } +-} +- +-/** +- * The abstract class [ClientCommunicationChannel] defines the behavior of +- * objects that allow a client to send [Request]s to an [AnalysisServer] and to +- * receive both [Response]s and [Notification]s. +- */ +-abstract class ClientCommunicationChannel { +- /** +- * The stream of notifications from the server. +- */ +- Stream notificationStream; +- +- /** +- * The stream of responses from the server. +- */ +- Stream responseStream; +- +- /** +- * Close the channel to the server. Once called, all future communication +- * with the server via [sendRequest] will silently be ignored. +- */ +- Future close(); +- +- /** +- * Send the given [request] to the server +- * and return a future with the associated [Response]. +- */ +- Future sendRequest(Request request); +-} +- +-/** +- * Instances of the class [JsonStreamDecoder] convert JSON strings to JSON +- * maps. +- */ +-class JsonStreamDecoder extends Converter { +- @override +- Map convert(String text) => JSON.decode(text); +- +- @override +- ChunkedConversionSink startChunkedConversion(Sink sink) => +- new ChannelChunkSink(this, sink); +-} +- +-/** +- * Instances of the class [NotificationConverter] convert JSON maps to +- * [Notification]s. +- */ +-class NotificationConverter extends Converter { +- @override +- Notification convert(Map json) => new Notification.fromJson(json); +- +- @override +- ChunkedConversionSink startChunkedConversion(Sink sink) => +- new ChannelChunkSink(this, sink); +-} +- +-/** +- * Instances of the class [ResponseConverter] convert JSON maps to [Response]s. +- */ +-class ResponseConverter extends Converter { +- @override +- Response convert(Map json) => new Response.fromJson(json); +- +- @override +- ChunkedConversionSink startChunkedConversion(Sink sink) => +- new ChannelChunkSink(this, sink); +-} +- +-/** +- * The abstract class [ServerCommunicationChannel] defines the behavior of +- * objects that allow an [AnalysisServer] to receive [Request]s and to return +- * both [Response]s and [Notification]s. +- */ +-abstract class ServerCommunicationChannel { +- /** +- * Close the communication channel. +- */ +- void close(); +- +- /** +- * Listen to the channel for requests. If a request is received, invoke the +- * [onRequest] function. If an error is encountered while trying to read from +- * the socket, invoke the [onError] function. If the socket is closed by the +- * client, invoke the [onDone] function. +- * Only one listener is allowed per channel. +- */ +- void listen(void onRequest(Request request), +- {Function onError, void onDone()}); +- +- /** +- * Send the given [notification] to the client. +- */ +- void sendNotification(Notification notification); +- +- /** +- * Send the given [response] to the client. +- */ +- void sendResponse(Response response); +-} +diff --git a/pkg/analysis_server/lib/src/collections.dart b/pkg/analysis_server/lib/src/collections.dart +deleted file mode 100644 +index 6c88a0463a3..00000000000 +--- a/pkg/analysis_server/lib/src/collections.dart ++++ /dev/null +@@ -1,71 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Returns the concatenation of the input [iterables]. +- * +- * The returned iterable is a lazily-evaluated view on the input iterables. +- */ +-Iterable concat(Iterable> iterables) => +- iterables.expand((x) => x); +- +-/** +- * Returns the concatenation of the input [iterables] as a [List]. +- */ +-List concatToList(Iterable> iterables) => +- concat(iterables).toList(); +- +-/** +- * Returns the given [list] if it is not empty, or `null` otherwise. +- */ +-List nullIfEmpty(List list) { +- if (list == null) { +- return null; +- } +- if (list.isEmpty) { +- return null; +- } +- return list; +-} +- +-/// A pair of values. +-class Pair { +- final E first; +- final F last; +- +- Pair(this.first, this.last); +- +- int get hashCode => first.hashCode ^ last.hashCode; +- +- bool operator ==(other) { +- if (other is! Pair) return false; +- return other.first == first && other.last == last; +- } +- +- String toString() => '($first, $last)'; +-} +- +-/** +- * A container that remembers the last `n` items added to it. +- * +- * It will never grow larger than [capacity]. It's a LIFO queue - the last item +- * added will be the first one returned from [items]. +- */ +-class RecentBuffer { +- final int capacity; +- +- List _buffer = []; +- +- RecentBuffer(this.capacity); +- +- Iterable get items => _buffer.reversed; +- +- void add(T item) { +- _buffer.add(item); +- +- if (_buffer.length > capacity) { +- _buffer.removeAt(0); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart +deleted file mode 100644 +index 71c5ff32838..00000000000 +--- a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart ++++ /dev/null +@@ -1,105 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-// TODO(devoncarew): We should look into not creating any labels until there's +-// at least 2 levels of nesting. +- +-/** +- * A computer for [CompilationUnit] closing labels. +- */ +-class DartUnitClosingLabelsComputer { +- final LineInfo _lineInfo; +- final CompilationUnit _unit; +- final List _closingLabels = []; +- +- DartUnitClosingLabelsComputer(this._lineInfo, this._unit); +- +- /** +- * Returns a list of closing labels, not `null`. +- */ +- List compute() { +- _unit.accept(new _DartUnitClosingLabelsComputerVisitor(this)); +- return _closingLabels; +- } +-} +- +-/** +- * An AST visitor for [DartUnitClosingLabelsComputer]. +- */ +-class _DartUnitClosingLabelsComputerVisitor +- extends RecursiveAstVisitor { +- final DartUnitClosingLabelsComputer computer; +- +- int interpolatedStringsEntered = 0; +- +- _DartUnitClosingLabelsComputerVisitor(this.computer); +- +- @override +- Object visitInstanceCreationExpression(InstanceCreationExpression node) { +- if (node.argumentList != null) { +- var label = node.constructorName.type.name.name; +- if (node.constructorName.name != null) { +- label += ".${node.constructorName.name.name}"; +- } +- // We override the node used for doing line calculations because otherwise +- // constructors that split over multiple lines (but have parens on same +- // line) would incorrectly get labels, because node.start on an instance +- // creation expression starts at the start of the expression. +- _addLabel(node, label, checkLinesUsing: node.argumentList); +- } +- +- return super.visitInstanceCreationExpression(node); +- } +- +- @override +- Object visitListLiteral(ListLiteral node) { +- final NodeList args = node.typeArguments?.arguments; +- final String typeName = args != null ? args[0]?.toString() : null; +- +- if (typeName != null) { +- _addLabel(node, "<$typeName>[]"); +- } +- +- return super.visitListLiteral(node); +- } +- +- @override +- Object visitStringInterpolation(StringInterpolation node) { +- interpolatedStringsEntered++; +- try { +- return super.visitStringInterpolation(node); +- } finally { +- interpolatedStringsEntered--; +- } +- } +- +- void _addLabel(AstNode node, String label, {AstNode checkLinesUsing}) { +- // Never add labels if we're inside strings. +- if (interpolatedStringsEntered > 0) { +- return; +- } +- +- checkLinesUsing = checkLinesUsing ?? node; +- +- final LineInfo_Location start = +- computer._lineInfo.getLocation(checkLinesUsing.offset); +- final LineInfo_Location end = +- computer._lineInfo.getLocation(checkLinesUsing.end - 1); +- +- int spannedLines = end.lineNumber - start.lineNumber; +- if (spannedLines < 1) { +- return; +- } +- +- final ClosingLabel closingLabel = +- new ClosingLabel(node.offset, node.length, label); +- +- computer._closingLabels.add(closingLabel); +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart +deleted file mode 100644 +index c49b17a4740..00000000000 +--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart ++++ /dev/null +@@ -1,737 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +- +-/** +- * A computer for [HighlightRegion]s in a Dart [CompilationUnit]. +- */ +-class DartUnitHighlightsComputer { +- final CompilationUnit _unit; +- +- final List _regions = []; +- +- DartUnitHighlightsComputer(this._unit); +- +- /** +- * Returns the computed highlight regions, not `null`. +- */ +- List compute() { +- _unit.accept(new _DartUnitHighlightsComputerVisitor(this)); +- _addCommentRanges(); +- return _regions; +- } +- +- void _addCommentRanges() { +- Token token = _unit.beginToken; +- while (token != null && token.type != TokenType.EOF) { +- Token commentToken = token.precedingComments; +- while (commentToken != null) { +- HighlightRegionType highlightType = null; +- if (commentToken.type == TokenType.MULTI_LINE_COMMENT) { +- if (commentToken.lexeme.startsWith('/**')) { +- highlightType = HighlightRegionType.COMMENT_DOCUMENTATION; +- } else { +- highlightType = HighlightRegionType.COMMENT_BLOCK; +- } +- } +- if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) { +- highlightType = HighlightRegionType.COMMENT_END_OF_LINE; +- } +- if (highlightType != null) { +- _addRegion_token(commentToken, highlightType); +- } +- commentToken = commentToken.next; +- } +- token = token.next; +- } +- } +- +- void _addIdentifierRegion(SimpleIdentifier node) { +- if (_addIdentifierRegion_keyword(node)) { +- return; +- } +- if (_addIdentifierRegion_class(node)) { +- return; +- } +- if (_addIdentifierRegion_constructor(node)) { +- return; +- } +- if (_addIdentifierRegion_dynamicType(node)) { +- return; +- } +- if (_addIdentifierRegion_getterSetterDeclaration(node)) { +- return; +- } +- if (_addIdentifierRegion_field(node)) { +- return; +- } +- if (_addIdentifierRegion_function(node)) { +- return; +- } +- if (_addIdentifierRegion_functionTypeAlias(node)) { +- return; +- } +- if (_addIdentifierRegion_importPrefix(node)) { +- return; +- } +- if (_addIdentifierRegion_label(node)) { +- return; +- } +- if (_addIdentifierRegion_localVariable(node)) { +- return; +- } +- if (_addIdentifierRegion_method(node)) { +- return; +- } +- if (_addIdentifierRegion_parameter(node)) { +- return; +- } +- if (_addIdentifierRegion_typeParameter(node)) { +- return; +- } +- _addRegion_node(node, HighlightRegionType.IDENTIFIER_DEFAULT); +- } +- +- void _addIdentifierRegion_annotation(Annotation node) { +- ArgumentList arguments = node.arguments; +- if (arguments == null) { +- _addRegion_node(node, HighlightRegionType.ANNOTATION); +- } else { +- _addRegion_nodeStart_tokenEnd( +- node, arguments.beginToken, HighlightRegionType.ANNOTATION); +- _addRegion_token(arguments.endToken, HighlightRegionType.ANNOTATION); +- } +- } +- +- bool _addIdentifierRegion_class(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! ClassElement) { +- return false; +- } +- ClassElement classElement = element; +- // prepare type +- HighlightRegionType type; +- if (classElement.isEnum) { +- type = HighlightRegionType.ENUM; +- } else { +- type = HighlightRegionType.CLASS; +- } +- // add region +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_constructor(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! ConstructorElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR); +- } +- +- bool _addIdentifierRegion_dynamicType(SimpleIdentifier node) { +- // should be variable +- Element element = node.staticElement; +- if (element is! VariableElement) { +- return false; +- } +- // has propagated type +- if (node.propagatedType != null) { +- return false; +- } +- // has dynamic static type +- DartType staticType = node.staticType; +- if (staticType == null || !staticType.isDynamic) { +- return false; +- } +- // OK +- return _addRegion_node(node, HighlightRegionType.DYNAMIC_TYPE); +- } +- +- bool _addIdentifierRegion_field(SimpleIdentifier node) { +- Element element = node.bestElement; +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- if (element is PropertyAccessorElement) { +- element = (element as PropertyAccessorElement).variable; +- } +- // prepare type +- HighlightRegionType type; +- if (element is FieldElement) { +- Element enclosingElement = element.enclosingElement; +- if (enclosingElement is ClassElement && enclosingElement.isEnum) { +- type = HighlightRegionType.ENUM_CONSTANT; +- } else if (element.isStatic) { +- type = HighlightRegionType.FIELD_STATIC; +- } else { +- type = HighlightRegionType.FIELD; +- } +- } else if (element is TopLevelVariableElement) { +- type = HighlightRegionType.TOP_LEVEL_VARIABLE; +- } +- // add region +- if (type != null) { +- return _addRegion_node(node, type); +- } +- return false; +- } +- +- bool _addIdentifierRegion_function(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! FunctionElement) { +- return false; +- } +- HighlightRegionType type; +- if (node.inDeclarationContext()) { +- type = HighlightRegionType.FUNCTION_DECLARATION; +- } else { +- type = HighlightRegionType.FUNCTION; +- } +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! FunctionTypeAliasElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS); +- } +- +- bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) { +- // should be declaration +- AstNode parent = node.parent; +- if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) { +- return false; +- } +- // should be property accessor +- Element element = node.staticElement; +- if (element is! PropertyAccessorElement) { +- return false; +- } +- // getter or setter +- PropertyAccessorElement propertyAccessorElement = +- element as PropertyAccessorElement; +- if (propertyAccessorElement.isGetter) { +- return _addRegion_node(node, HighlightRegionType.GETTER_DECLARATION); +- } else { +- return _addRegion_node(node, HighlightRegionType.SETTER_DECLARATION); +- } +- } +- +- bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! PrefixElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX); +- } +- +- bool _addIdentifierRegion_keyword(SimpleIdentifier node) { +- String name = node.name; +- if (name == "void") { +- return _addRegion_node(node, HighlightRegionType.KEYWORD); +- } +- return false; +- } +- +- bool _addIdentifierRegion_label(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! LabelElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.LABEL); +- } +- +- bool _addIdentifierRegion_localVariable(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! LocalVariableElement) { +- return false; +- } +- // OK +- HighlightRegionType type; +- if (node.inDeclarationContext()) { +- type = HighlightRegionType.LOCAL_VARIABLE_DECLARATION; +- } else { +- type = HighlightRegionType.LOCAL_VARIABLE; +- } +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_method(SimpleIdentifier node) { +- Element element = node.bestElement; +- if (element is! MethodElement) { +- return false; +- } +- MethodElement methodElement = element as MethodElement; +- bool isStatic = methodElement.isStatic; +- // OK +- HighlightRegionType type; +- if (node.inDeclarationContext()) { +- if (isStatic) { +- type = HighlightRegionType.METHOD_DECLARATION_STATIC; +- } else { +- type = HighlightRegionType.METHOD_DECLARATION; +- } +- } else { +- if (isStatic) { +- type = HighlightRegionType.METHOD_STATIC; +- } else { +- type = HighlightRegionType.METHOD; +- } +- } +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_parameter(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! ParameterElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.PARAMETER); +- } +- +- bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! TypeParameterElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER); +- } +- +- void _addRegion(int offset, int length, HighlightRegionType type) { +- _regions.add(new HighlightRegion(type, offset, length)); +- } +- +- bool _addRegion_node(AstNode node, HighlightRegionType type) { +- int offset = node.offset; +- int length = node.length; +- _addRegion(offset, length, type); +- return true; +- } +- +- void _addRegion_nodeStart_tokenEnd( +- AstNode a, Token b, HighlightRegionType type) { +- int offset = a.offset; +- int end = b.end; +- _addRegion(offset, end - offset, type); +- } +- +- void _addRegion_token(Token token, HighlightRegionType type) { +- if (token != null) { +- int offset = token.offset; +- int length = token.length; +- _addRegion(offset, length, type); +- } +- } +- +- void _addRegion_tokenStart_tokenEnd( +- Token a, Token b, HighlightRegionType type) { +- int offset = a.offset; +- int end = b.end; +- _addRegion(offset, end - offset, type); +- } +-} +- +-/** +- * An AST visitor for [DartUnitHighlightsComputer]. +- */ +-class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor { +- final DartUnitHighlightsComputer computer; +- +- _DartUnitHighlightsComputerVisitor(this.computer); +- +- @override +- Object visitAnnotation(Annotation node) { +- computer._addIdentifierRegion_annotation(node); +- return super.visitAnnotation(node); +- } +- +- @override +- Object visitAsExpression(AsExpression node) { +- computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN); +- return super.visitAsExpression(node); +- } +- +- @override +- Object visitAssertStatement(AssertStatement node) { +- computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD); +- return super.visitAssertStatement(node); +- } +- +- @override +- Object visitAwaitExpression(AwaitExpression node) { +- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN); +- return super.visitAwaitExpression(node); +- } +- +- @override +- Object visitBlockFunctionBody(BlockFunctionBody node) { +- _addRegions_functionBody(node); +- return super.visitBlockFunctionBody(node); +- } +- +- @override +- Object visitBooleanLiteral(BooleanLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.KEYWORD); +- computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN); +- return super.visitBooleanLiteral(node); +- } +- +- @override +- Object visitBreakStatement(BreakStatement node) { +- computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD); +- return super.visitBreakStatement(node); +- } +- +- @override +- Object visitCatchClause(CatchClause node) { +- computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN); +- return super.visitCatchClause(node); +- } +- +- @override +- Object visitClassDeclaration(ClassDeclaration node) { +- computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token( +- node.abstractKeyword, HighlightRegionType.BUILT_IN); +- return super.visitClassDeclaration(node); +- } +- +- @override +- Object visitClassTypeAlias(ClassTypeAlias node) { +- computer._addRegion_token( +- node.abstractKeyword, HighlightRegionType.BUILT_IN); +- return super.visitClassTypeAlias(node); +- } +- +- @override +- Object visitConstructorDeclaration(ConstructorDeclaration node) { +- computer._addRegion_token( +- node.externalKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.factoryKeyword, HighlightRegionType.BUILT_IN); +- return super.visitConstructorDeclaration(node); +- } +- +- @override +- Object visitContinueStatement(ContinueStatement node) { +- computer._addRegion_token( +- node.continueKeyword, HighlightRegionType.KEYWORD); +- return super.visitContinueStatement(node); +- } +- +- @override +- Object visitDoStatement(DoStatement node) { +- computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD); +- return super.visitDoStatement(node); +- } +- +- @override +- Object visitDoubleLiteral(DoubleLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE); +- return super.visitDoubleLiteral(node); +- } +- +- @override +- Object visitEnumDeclaration(EnumDeclaration node) { +- computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD); +- return super.visitEnumDeclaration(node); +- } +- +- @override +- Object visitExportDirective(ExportDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitExportDirective(node); +- } +- +- @override +- Object visitExpressionFunctionBody(ExpressionFunctionBody node) { +- _addRegions_functionBody(node); +- return super.visitExpressionFunctionBody(node); +- } +- +- @override +- Object visitFieldDeclaration(FieldDeclaration node) { +- computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN); +- return super.visitFieldDeclaration(node); +- } +- +- @override +- Object visitForEachStatement(ForEachStatement node) { +- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD); +- return super.visitForEachStatement(node); +- } +- +- @override +- Object visitForStatement(ForStatement node) { +- computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD); +- return super.visitForStatement(node); +- } +- +- @override +- Object visitFunctionDeclaration(FunctionDeclaration node) { +- computer._addRegion_token( +- node.externalKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.propertyKeyword, HighlightRegionType.BUILT_IN); +- return super.visitFunctionDeclaration(node); +- } +- +- @override +- Object visitFunctionTypeAlias(FunctionTypeAlias node) { +- computer._addRegion_token( +- node.typedefKeyword, HighlightRegionType.BUILT_IN); +- return super.visitFunctionTypeAlias(node); +- } +- +- @override +- Object visitGenericFunctionType(GenericFunctionType node) { +- computer._addRegion_token( +- node.functionKeyword, HighlightRegionType.KEYWORD); +- return super.visitGenericFunctionType(node); +- } +- +- @override +- Object visitGenericTypeAlias(GenericTypeAlias node) { +- computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD); +- return super.visitGenericTypeAlias(node); +- } +- +- @override +- Object visitHideCombinator(HideCombinator node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitHideCombinator(node); +- } +- +- @override +- Object visitIfStatement(IfStatement node) { +- computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD); +- return super.visitIfStatement(node); +- } +- +- @override +- Object visitImplementsClause(ImplementsClause node) { +- computer._addRegion_token( +- node.implementsKeyword, HighlightRegionType.BUILT_IN); +- return super.visitImplementsClause(node); +- } +- +- @override +- Object visitImportDirective(ImportDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.deferredKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token(node.asKeyword, HighlightRegionType.BUILT_IN); +- return super.visitImportDirective(node); +- } +- +- @override +- Object visitInstanceCreationExpression(InstanceCreationExpression node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitInstanceCreationExpression(node); +- } +- +- @override +- Object visitIntegerLiteral(IntegerLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER); +- return super.visitIntegerLiteral(node); +- } +- +- @override +- Object visitIsExpression(IsExpression node) { +- computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD); +- return super.visitIsExpression(node); +- } +- +- @override +- Object visitLibraryDirective(LibraryDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitLibraryDirective(node); +- } +- +- @override +- Object visitListLiteral(ListLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST); +- computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD); +- return super.visitListLiteral(node); +- } +- +- @override +- Object visitMapLiteral(MapLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP); +- computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD); +- return super.visitMapLiteral(node); +- } +- +- @override +- Object visitMethodDeclaration(MethodDeclaration node) { +- computer._addRegion_token( +- node.externalKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.modifierKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.operatorKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.propertyKeyword, HighlightRegionType.BUILT_IN); +- return super.visitMethodDeclaration(node); +- } +- +- @override +- Object visitNativeClause(NativeClause node) { +- computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN); +- return super.visitNativeClause(node); +- } +- +- @override +- Object visitNativeFunctionBody(NativeFunctionBody node) { +- computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN); +- return super.visitNativeFunctionBody(node); +- } +- +- @override +- Object visitPartDirective(PartDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitPartDirective(node); +- } +- +- @override +- Object visitPartOfDirective(PartOfDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_tokenStart_tokenEnd( +- node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN); +- return super.visitPartOfDirective(node); +- } +- +- @override +- Object visitRethrowExpression(RethrowExpression node) { +- computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD); +- return super.visitRethrowExpression(node); +- } +- +- @override +- Object visitReturnStatement(ReturnStatement node) { +- computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD); +- return super.visitReturnStatement(node); +- } +- +- @override +- Object visitShowCombinator(ShowCombinator node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitShowCombinator(node); +- } +- +- @override +- Object visitSimpleIdentifier(SimpleIdentifier node) { +- computer._addIdentifierRegion(node); +- return super.visitSimpleIdentifier(node); +- } +- +- @override +- Object visitSimpleStringLiteral(SimpleStringLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING); +- return super.visitSimpleStringLiteral(node); +- } +- +- @override +- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { +- computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD); +- return super.visitSuperConstructorInvocation(node); +- } +- +- @override +- Object visitSwitchCase(SwitchCase node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitSwitchCase(node); +- } +- +- @override +- Object visitSwitchDefault(SwitchDefault node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitSwitchDefault(node); +- } +- +- @override +- Object visitSwitchStatement(SwitchStatement node) { +- computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD); +- return super.visitSwitchStatement(node); +- } +- +- @override +- Object visitThisExpression(ThisExpression node) { +- computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD); +- return super.visitThisExpression(node); +- } +- +- @override +- Object visitTryStatement(TryStatement node) { +- computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD); +- return super.visitTryStatement(node); +- } +- +- @override +- Object visitTypeName(TypeName node) { +- DartType type = node.type; +- if (type != null) { +- if (type.isDynamic && node.name.name == "dynamic") { +- computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC); +- return null; +- } +- } +- return super.visitTypeName(node); +- } +- +- @override +- Object visitVariableDeclarationList(VariableDeclarationList node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitVariableDeclarationList(node); +- } +- +- @override +- Object visitWhileStatement(WhileStatement node) { +- computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD); +- return super.visitWhileStatement(node); +- } +- +- @override +- Object visitWithClause(WithClause node) { +- computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD); +- return super.visitWithClause(node); +- } +- +- @override +- Object visitYieldStatement(YieldStatement node) { +- Token keyword = node.yieldKeyword; +- Token star = node.star; +- int offset = keyword.offset; +- int end = star != null ? star.end : keyword.end; +- computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN); +- return super.visitYieldStatement(node); +- } +- +- void _addRegions_functionBody(FunctionBody node) { +- Token keyword = node.keyword; +- if (keyword != null) { +- Token star = node.star; +- int offset = keyword.offset; +- int end = star != null ? star.end : keyword.end; +- computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart +deleted file mode 100644 +index 103d64103f5..00000000000 +--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart ++++ /dev/null +@@ -1,834 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +- +-/** +- * A computer for [HighlightRegion]s in a Dart [CompilationUnit]. +- */ +-class DartUnitHighlightsComputer2 { +- final CompilationUnit _unit; +- +- final List _regions = []; +- +- DartUnitHighlightsComputer2(this._unit); +- +- /** +- * Returns the computed highlight regions, not `null`. +- */ +- List compute() { +- _unit.accept(new _DartUnitHighlightsComputerVisitor2(this)); +- _addCommentRanges(); +- return _regions; +- } +- +- void _addCommentRanges() { +- Token token = _unit.beginToken; +- while (token != null && token.type != TokenType.EOF) { +- Token commentToken = token.precedingComments; +- while (commentToken != null) { +- HighlightRegionType highlightType = null; +- if (commentToken.type == TokenType.MULTI_LINE_COMMENT) { +- if (commentToken.lexeme.startsWith('/**')) { +- highlightType = HighlightRegionType.COMMENT_DOCUMENTATION; +- } else { +- highlightType = HighlightRegionType.COMMENT_BLOCK; +- } +- } +- if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) { +- highlightType = HighlightRegionType.COMMENT_END_OF_LINE; +- } +- if (highlightType != null) { +- _addRegion_token(commentToken, highlightType); +- } +- commentToken = commentToken.next; +- } +- token = token.next; +- } +- } +- +- void _addIdentifierRegion(SimpleIdentifier node) { +- if (_addIdentifierRegion_keyword(node)) { +- return; +- } +- if (_addIdentifierRegion_class(node)) { +- return; +- } +- if (_addIdentifierRegion_constructor(node)) { +- return; +- } +- if (_addIdentifierRegion_getterSetterDeclaration(node)) { +- return; +- } +- if (_addIdentifierRegion_field(node)) { +- return; +- } +- if (_addIdentifierRegion_dynamicLocal(node)) { +- return; +- } +- if (_addIdentifierRegion_function(node)) { +- return; +- } +- if (_addIdentifierRegion_functionTypeAlias(node)) { +- return; +- } +- if (_addIdentifierRegion_importPrefix(node)) { +- return; +- } +- if (_addIdentifierRegion_label(node)) { +- return; +- } +- if (_addIdentifierRegion_localVariable(node)) { +- return; +- } +- if (_addIdentifierRegion_method(node)) { +- return; +- } +- if (_addIdentifierRegion_parameter(node)) { +- return; +- } +- if (_addIdentifierRegion_typeParameter(node)) { +- return; +- } +- if (_addIdentifierRegion_unresolvedInstanceMemberReference(node)) { +- return; +- } +- _addRegion_node(node, HighlightRegionType.IDENTIFIER_DEFAULT); +- } +- +- void _addIdentifierRegion_annotation(Annotation node) { +- ArgumentList arguments = node.arguments; +- if (arguments == null) { +- _addRegion_node(node, HighlightRegionType.ANNOTATION); +- } else { +- _addRegion_nodeStart_tokenEnd( +- node, arguments.beginToken, HighlightRegionType.ANNOTATION); +- _addRegion_token(arguments.endToken, HighlightRegionType.ANNOTATION); +- } +- } +- +- bool _addIdentifierRegion_class(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! ClassElement) { +- return false; +- } +- ClassElement classElement = element; +- // prepare type +- HighlightRegionType type; +- if (classElement.isEnum) { +- type = HighlightRegionType.ENUM; +- } else { +- type = HighlightRegionType.CLASS; +- } +- // add region +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_constructor(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! ConstructorElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR); +- } +- +- bool _addIdentifierRegion_dynamicLocal(SimpleIdentifier node) { +- // no propagated type +- if (node.propagatedType != null) { +- return false; +- } +- // has dynamic static type +- DartType staticType = node.staticType; +- if (staticType == null || !staticType.isDynamic) { +- return false; +- } +- // OK +- Element element = node.staticElement; +- if (element is LocalVariableElement) { +- HighlightRegionType type = node.inDeclarationContext() +- ? HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION +- : HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE; +- return _addRegion_node(node, type); +- } +- if (element is ParameterElement) { +- HighlightRegionType type = node.inDeclarationContext() +- ? HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION +- : HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE; +- return _addRegion_node(node, type); +- } +- return false; +- } +- +- bool _addIdentifierRegion_field(SimpleIdentifier node) { +- Element element = node.bestElement; +- if (element is FieldFormalParameterElement) { +- if (node.parent is FieldFormalParameter) { +- element = (element as FieldFormalParameterElement).field; +- } +- } +- // prepare type +- HighlightRegionType type; +- if (element is FieldElement) { +- Element enclosingElement = element.enclosingElement; +- if (enclosingElement is ClassElement && enclosingElement.isEnum) { +- type = HighlightRegionType.ENUM_CONSTANT; +- } else if (element.isStatic) { +- type = HighlightRegionType.STATIC_FIELD_DECLARATION; +- } else { +- type = node.inDeclarationContext() +- ? HighlightRegionType.INSTANCE_FIELD_DECLARATION +- : HighlightRegionType.INSTANCE_FIELD_REFERENCE; +- } +- } else if (element is TopLevelVariableElement) { +- type = HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION; +- } +- if (element is PropertyAccessorElement) { +- PropertyAccessorElement accessor = element; +- Element enclosingElement = element.enclosingElement; +- if (accessor.variable is TopLevelVariableElement) { +- type = accessor.isGetter +- ? HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE +- : HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE; +- } else if (enclosingElement is ClassElement && enclosingElement.isEnum) { +- type = HighlightRegionType.ENUM_CONSTANT; +- } else if (accessor.isStatic) { +- type = accessor.isGetter +- ? HighlightRegionType.STATIC_GETTER_REFERENCE +- : HighlightRegionType.STATIC_SETTER_REFERENCE; +- } else { +- type = accessor.isGetter +- ? HighlightRegionType.INSTANCE_GETTER_REFERENCE +- : HighlightRegionType.INSTANCE_SETTER_REFERENCE; +- } +- } +- // add region +- if (type != null) { +- return _addRegion_node(node, type); +- } +- return false; +- } +- +- bool _addIdentifierRegion_function(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! FunctionElement) { +- return false; +- } +- HighlightRegionType type; +- bool isTopLevel = element.enclosingElement is CompilationUnitElement; +- if (node.inDeclarationContext()) { +- type = isTopLevel +- ? HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION +- : HighlightRegionType.LOCAL_FUNCTION_DECLARATION; +- } else { +- type = isTopLevel +- ? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE +- : HighlightRegionType.LOCAL_FUNCTION_REFERENCE; +- } +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! FunctionTypeAliasElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS); +- } +- +- bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) { +- // should be declaration +- AstNode parent = node.parent; +- if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) { +- return false; +- } +- // should be property accessor +- Element element = node.staticElement; +- if (element is! PropertyAccessorElement) { +- return false; +- } +- // getter or setter +- PropertyAccessorElement propertyAccessorElement = +- element as PropertyAccessorElement; +- bool isTopLevel = element.enclosingElement is CompilationUnitElement; +- HighlightRegionType type; +- if (propertyAccessorElement.isGetter) { +- if (isTopLevel) { +- type = HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION; +- } else if (propertyAccessorElement.isStatic) { +- type = HighlightRegionType.STATIC_GETTER_DECLARATION; +- } else { +- type = HighlightRegionType.INSTANCE_GETTER_DECLARATION; +- } +- } else { +- if (isTopLevel) { +- type = HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION; +- } else if (propertyAccessorElement.isStatic) { +- type = HighlightRegionType.STATIC_SETTER_DECLARATION; +- } else { +- type = HighlightRegionType.INSTANCE_SETTER_DECLARATION; +- } +- } +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! PrefixElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX); +- } +- +- bool _addIdentifierRegion_keyword(SimpleIdentifier node) { +- String name = node.name; +- if (name == "void") { +- return _addRegion_node(node, HighlightRegionType.KEYWORD); +- } +- return false; +- } +- +- bool _addIdentifierRegion_label(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! LabelElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.LABEL); +- } +- +- bool _addIdentifierRegion_localVariable(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! LocalVariableElement) { +- return false; +- } +- // OK +- HighlightRegionType type = node.inDeclarationContext() +- ? HighlightRegionType.LOCAL_VARIABLE_DECLARATION +- : HighlightRegionType.LOCAL_VARIABLE_REFERENCE; +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_method(SimpleIdentifier node) { +- Element element = node.bestElement; +- if (element is! MethodElement) { +- return false; +- } +- MethodElement methodElement = element as MethodElement; +- bool isStatic = methodElement.isStatic; +- // OK +- HighlightRegionType type; +- if (node.inDeclarationContext()) { +- if (isStatic) { +- type = HighlightRegionType.STATIC_METHOD_DECLARATION; +- } else { +- type = HighlightRegionType.INSTANCE_METHOD_DECLARATION; +- } +- } else { +- if (isStatic) { +- type = HighlightRegionType.STATIC_METHOD_REFERENCE; +- } else { +- type = HighlightRegionType.INSTANCE_METHOD_REFERENCE; +- } +- } +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_parameter(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! ParameterElement) { +- return false; +- } +- HighlightRegionType type = node.inDeclarationContext() +- ? HighlightRegionType.PARAMETER_DECLARATION +- : HighlightRegionType.PARAMETER_REFERENCE; +- return _addRegion_node(node, type); +- } +- +- bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is! TypeParameterElement) { +- return false; +- } +- return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER); +- } +- +- bool _addIdentifierRegion_unresolvedInstanceMemberReference( +- SimpleIdentifier node) { +- // unresolved +- Element element = node.bestElement; +- if (element != null) { +- return false; +- } +- // invoke / get / set +- bool decorate = false; +- AstNode parent = node.parent; +- if (parent is MethodInvocation) { +- Expression target = parent.realTarget; +- if (parent.methodName == node && +- target != null && +- _isDynamicExpression(target)) { +- decorate = true; +- } +- } else if (node.inGetterContext() || node.inSetterContext()) { +- if (parent is PrefixedIdentifier) { +- decorate = parent.identifier == node; +- } else if (parent is PropertyAccess) { +- decorate = parent.propertyName == node; +- } +- } +- if (decorate) { +- _addRegion_node( +- node, HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE); +- return true; +- } +- return false; +- } +- +- void _addRegion(int offset, int length, HighlightRegionType type) { +- _regions.add(new HighlightRegion(type, offset, length)); +- } +- +- bool _addRegion_node(AstNode node, HighlightRegionType type) { +- int offset = node.offset; +- int length = node.length; +- _addRegion(offset, length, type); +- return true; +- } +- +- void _addRegion_nodeStart_tokenEnd( +- AstNode a, Token b, HighlightRegionType type) { +- int offset = a.offset; +- int end = b.end; +- _addRegion(offset, end - offset, type); +- } +- +- void _addRegion_token(Token token, HighlightRegionType type) { +- if (token != null) { +- int offset = token.offset; +- int length = token.length; +- _addRegion(offset, length, type); +- } +- } +- +- void _addRegion_tokenStart_tokenEnd( +- Token a, Token b, HighlightRegionType type) { +- int offset = a.offset; +- int end = b.end; +- _addRegion(offset, end - offset, type); +- } +- +- static bool _isDynamicExpression(Expression e) { +- if (e is SimpleIdentifier && e.staticElement is PrefixElement) { +- return false; +- } +- return resolutionMap.bestTypeForExpression(e).isDynamic; +- } +-} +- +-/** +- * An AST visitor for [DartUnitHighlightsComputer2]. +- */ +-class _DartUnitHighlightsComputerVisitor2 extends RecursiveAstVisitor { +- final DartUnitHighlightsComputer2 computer; +- +- _DartUnitHighlightsComputerVisitor2(this.computer); +- +- @override +- Object visitAnnotation(Annotation node) { +- computer._addIdentifierRegion_annotation(node); +- return super.visitAnnotation(node); +- } +- +- @override +- Object visitAsExpression(AsExpression node) { +- computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN); +- return super.visitAsExpression(node); +- } +- +- @override +- Object visitAssertStatement(AssertStatement node) { +- computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD); +- return super.visitAssertStatement(node); +- } +- +- @override +- Object visitAwaitExpression(AwaitExpression node) { +- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN); +- return super.visitAwaitExpression(node); +- } +- +- @override +- Object visitBlockFunctionBody(BlockFunctionBody node) { +- _addRegions_functionBody(node); +- return super.visitBlockFunctionBody(node); +- } +- +- @override +- Object visitBooleanLiteral(BooleanLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.KEYWORD); +- computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN); +- return super.visitBooleanLiteral(node); +- } +- +- @override +- Object visitBreakStatement(BreakStatement node) { +- computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD); +- return super.visitBreakStatement(node); +- } +- +- @override +- Object visitCatchClause(CatchClause node) { +- computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN); +- return super.visitCatchClause(node); +- } +- +- @override +- Object visitClassDeclaration(ClassDeclaration node) { +- computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token( +- node.abstractKeyword, HighlightRegionType.BUILT_IN); +- return super.visitClassDeclaration(node); +- } +- +- @override +- Object visitClassTypeAlias(ClassTypeAlias node) { +- computer._addRegion_token( +- node.abstractKeyword, HighlightRegionType.BUILT_IN); +- return super.visitClassTypeAlias(node); +- } +- +- @override +- Object visitConstructorDeclaration(ConstructorDeclaration node) { +- computer._addRegion_token( +- node.externalKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.factoryKeyword, HighlightRegionType.BUILT_IN); +- return super.visitConstructorDeclaration(node); +- } +- +- @override +- Object visitContinueStatement(ContinueStatement node) { +- computer._addRegion_token( +- node.continueKeyword, HighlightRegionType.KEYWORD); +- return super.visitContinueStatement(node); +- } +- +- @override +- Object visitDoStatement(DoStatement node) { +- computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD); +- return super.visitDoStatement(node); +- } +- +- @override +- Object visitDoubleLiteral(DoubleLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE); +- return super.visitDoubleLiteral(node); +- } +- +- @override +- Object visitEnumDeclaration(EnumDeclaration node) { +- computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD); +- return super.visitEnumDeclaration(node); +- } +- +- @override +- Object visitExportDirective(ExportDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitExportDirective(node); +- } +- +- @override +- Object visitExpressionFunctionBody(ExpressionFunctionBody node) { +- _addRegions_functionBody(node); +- return super.visitExpressionFunctionBody(node); +- } +- +- @override +- Object visitFieldDeclaration(FieldDeclaration node) { +- computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN); +- return super.visitFieldDeclaration(node); +- } +- +- @override +- Object visitForEachStatement(ForEachStatement node) { +- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD); +- return super.visitForEachStatement(node); +- } +- +- @override +- Object visitForStatement(ForStatement node) { +- computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD); +- return super.visitForStatement(node); +- } +- +- @override +- Object visitFunctionDeclaration(FunctionDeclaration node) { +- computer._addRegion_token( +- node.externalKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.propertyKeyword, HighlightRegionType.BUILT_IN); +- return super.visitFunctionDeclaration(node); +- } +- +- @override +- Object visitFunctionTypeAlias(FunctionTypeAlias node) { +- computer._addRegion_token( +- node.typedefKeyword, HighlightRegionType.BUILT_IN); +- return super.visitFunctionTypeAlias(node); +- } +- +- @override +- Object visitGenericFunctionType(GenericFunctionType node) { +- computer._addRegion_token( +- node.functionKeyword, HighlightRegionType.KEYWORD); +- return super.visitGenericFunctionType(node); +- } +- +- @override +- Object visitGenericTypeAlias(GenericTypeAlias node) { +- computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD); +- return super.visitGenericTypeAlias(node); +- } +- +- @override +- Object visitHideCombinator(HideCombinator node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitHideCombinator(node); +- } +- +- @override +- Object visitIfStatement(IfStatement node) { +- computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD); +- return super.visitIfStatement(node); +- } +- +- @override +- Object visitImplementsClause(ImplementsClause node) { +- computer._addRegion_token( +- node.implementsKeyword, HighlightRegionType.BUILT_IN); +- return super.visitImplementsClause(node); +- } +- +- @override +- Object visitImportDirective(ImportDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.deferredKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token(node.asKeyword, HighlightRegionType.BUILT_IN); +- return super.visitImportDirective(node); +- } +- +- @override +- Object visitInstanceCreationExpression(InstanceCreationExpression node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitInstanceCreationExpression(node); +- } +- +- @override +- Object visitIntegerLiteral(IntegerLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER); +- return super.visitIntegerLiteral(node); +- } +- +- @override +- Object visitIsExpression(IsExpression node) { +- computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD); +- return super.visitIsExpression(node); +- } +- +- @override +- Object visitLibraryDirective(LibraryDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitLibraryDirective(node); +- } +- +- @override +- Object visitLibraryIdentifier(LibraryIdentifier node) { +- computer._addRegion_node(node, HighlightRegionType.LIBRARY_NAME); +- return null; +- } +- +- @override +- Object visitListLiteral(ListLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST); +- computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD); +- return super.visitListLiteral(node); +- } +- +- @override +- Object visitMapLiteral(MapLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP); +- computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD); +- return super.visitMapLiteral(node); +- } +- +- @override +- Object visitMethodDeclaration(MethodDeclaration node) { +- computer._addRegion_token( +- node.externalKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.modifierKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.operatorKeyword, HighlightRegionType.BUILT_IN); +- computer._addRegion_token( +- node.propertyKeyword, HighlightRegionType.BUILT_IN); +- return super.visitMethodDeclaration(node); +- } +- +- @override +- Object visitNativeClause(NativeClause node) { +- computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN); +- return super.visitNativeClause(node); +- } +- +- @override +- Object visitNativeFunctionBody(NativeFunctionBody node) { +- computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN); +- return super.visitNativeFunctionBody(node); +- } +- +- @override +- Object visitPartDirective(PartDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitPartDirective(node); +- } +- +- @override +- Object visitPartOfDirective(PartOfDirective node) { +- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE); +- computer._addRegion_tokenStart_tokenEnd( +- node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN); +- return super.visitPartOfDirective(node); +- } +- +- @override +- Object visitRethrowExpression(RethrowExpression node) { +- computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD); +- return super.visitRethrowExpression(node); +- } +- +- @override +- Object visitReturnStatement(ReturnStatement node) { +- computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD); +- return super.visitReturnStatement(node); +- } +- +- @override +- Object visitShowCombinator(ShowCombinator node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN); +- return super.visitShowCombinator(node); +- } +- +- @override +- Object visitSimpleIdentifier(SimpleIdentifier node) { +- computer._addIdentifierRegion(node); +- return super.visitSimpleIdentifier(node); +- } +- +- @override +- Object visitSimpleStringLiteral(SimpleStringLiteral node) { +- computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING); +- return super.visitSimpleStringLiteral(node); +- } +- +- @override +- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { +- computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD); +- return super.visitSuperConstructorInvocation(node); +- } +- +- @override +- Object visitSwitchCase(SwitchCase node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitSwitchCase(node); +- } +- +- @override +- Object visitSwitchDefault(SwitchDefault node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitSwitchDefault(node); +- } +- +- @override +- Object visitSwitchStatement(SwitchStatement node) { +- computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD); +- return super.visitSwitchStatement(node); +- } +- +- @override +- Object visitThisExpression(ThisExpression node) { +- computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD); +- return super.visitThisExpression(node); +- } +- +- @override +- Object visitTryStatement(TryStatement node) { +- computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD); +- computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD); +- return super.visitTryStatement(node); +- } +- +- @override +- Object visitTypeName(TypeName node) { +- DartType type = node.type; +- if (type != null) { +- if (type.isDynamic && node.name.name == "dynamic") { +- computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC); +- return null; +- } +- } +- return super.visitTypeName(node); +- } +- +- @override +- Object visitVariableDeclarationList(VariableDeclarationList node) { +- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD); +- return super.visitVariableDeclarationList(node); +- } +- +- @override +- Object visitWhileStatement(WhileStatement node) { +- computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD); +- return super.visitWhileStatement(node); +- } +- +- @override +- Object visitWithClause(WithClause node) { +- computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD); +- return super.visitWithClause(node); +- } +- +- @override +- Object visitYieldStatement(YieldStatement node) { +- Token keyword = node.yieldKeyword; +- Token star = node.star; +- int offset = keyword.offset; +- int end = star != null ? star.end : keyword.end; +- computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN); +- return super.visitYieldStatement(node); +- } +- +- void _addRegions_functionBody(FunctionBody node) { +- Token keyword = node.keyword; +- if (keyword != null) { +- Token star = node.star; +- int offset = keyword.offset; +- int end = star != null ? star.end : keyword.end; +- computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart +deleted file mode 100644 +index 96b07f50bdc..00000000000 +--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart ++++ /dev/null +@@ -1,140 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart' +- show HoverInformation; +-import 'package:analysis_server/src/computer/computer_overrides.dart'; +-import 'package:analysis_server/src/utilities/documentation.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +- +-/** +- * A computer for the hover at the specified offset of a Dart [CompilationUnit]. +- */ +-class DartUnitHoverComputer { +- final CompilationUnit _unit; +- final int _offset; +- +- DartUnitHoverComputer(this._unit, this._offset); +- +- /** +- * Returns the computed hover, maybe `null`. +- */ +- HoverInformation compute() { +- AstNode node = new NodeLocator(_offset).searchWithin(_unit); +- if (node == null) { +- return null; +- } +- if (node.parent is TypeName && +- node.parent.parent is ConstructorName && +- node.parent.parent.parent is InstanceCreationExpression) { +- node = node.parent.parent.parent; +- } +- if (node.parent is ConstructorName && +- node.parent.parent is InstanceCreationExpression) { +- node = node.parent.parent; +- } +- if (node is Expression) { +- Expression expression = node; +- HoverInformation hover = +- new HoverInformation(expression.offset, expression.length); +- // element +- Element element = ElementLocator.locate(expression); +- if (element != null) { +- // variable, if synthetic accessor +- if (element is PropertyAccessorElement) { +- PropertyAccessorElement accessor = element; +- if (accessor.isSynthetic) { +- element = accessor.variable; +- } +- } +- // description +- hover.elementDescription = element.toString(); +- hover.elementKind = element.kind.displayName; +- hover.isDeprecated = element.isDeprecated; +- // not local element +- if (element.enclosingElement is! ExecutableElement) { +- // containing class +- ClassElement containingClass = +- element.getAncestor((e) => e is ClassElement); +- if (containingClass != null) { +- hover.containingClassDescription = containingClass.displayName; +- } +- // containing library +- LibraryElement library = element.library; +- if (library != null) { +- hover.containingLibraryName = library.name; +- hover.containingLibraryPath = library.source.fullName; +- } +- } +- // documentation +- hover.dartdoc = _computeDocumentation(element); +- } +- // parameter +- hover.parameter = _safeToString(expression.bestParameterElement); +- // types +- { +- AstNode parent = expression.parent; +- DartType staticType = null; +- DartType propagatedType = expression.propagatedType; +- if (element is ParameterElement) { +- staticType = element.type; +- } else if (element == null || element is VariableElement) { +- staticType = expression.staticType; +- } +- if (parent is MethodInvocation && parent.methodName == expression) { +- staticType = parent.staticInvokeType; +- propagatedType = parent.propagatedInvokeType; +- if (staticType != null && staticType.isDynamic) { +- staticType = null; +- } +- if (propagatedType != null && propagatedType.isDynamic) { +- propagatedType = null; +- } +- } +- hover.staticType = _safeToString(staticType); +- hover.propagatedType = _safeToString(propagatedType); +- } +- // done +- return hover; +- } +- // not an expression +- return null; +- } +- +- String _computeDocumentation(Element element) { +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- if (element is ParameterElement) { +- element = element.enclosingElement; +- } +- if (element == null) { +- // This can happen when the code is invalid, such as having a field formal +- // parameter for a field that does not exist. +- return null; +- } +- // The documentation of the element itself. +- if (element.documentationComment != null) { +- return removeDartDocDelimiters(element.documentationComment); +- } +- // Look for documentation comments of overridden members. +- OverriddenElements overridden = findOverriddenElements(element); +- for (Element superElement in [] +- ..addAll(overridden.superElements) +- ..addAll(overridden.interfaceElements)) { +- String rawDoc = superElement.documentationComment; +- if (rawDoc != null) { +- Element interfaceClass = superElement.enclosingElement; +- return removeDartDocDelimiters(rawDoc) + +- '\n\nCopied from `${interfaceClass.displayName}`.'; +- } +- } +- return null; +- } +- +- static _safeToString(obj) => obj?.toString(); +-} +diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart +deleted file mode 100644 +index c9e4a865798..00000000000 +--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart ++++ /dev/null +@@ -1,488 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/collections.dart'; +-import 'package:analysis_server/src/utilities/flutter.dart' as flutter; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart' as engine; +-import 'package:analyzer/dart/element/type.dart' as engine; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * A computer for [CompilationUnit] outline. +- */ +-class DartUnitOutlineComputer { +- final String file; +- final CompilationUnit unit; +- final LineInfo lineInfo; +- +- DartUnitOutlineComputer(this.file, this.lineInfo, this.unit); +- +- /** +- * Returns the computed outline, not `null`. +- */ +- Outline compute() { +- List unitContents = []; +- for (CompilationUnitMember unitMember in unit.declarations) { +- if (unitMember is ClassDeclaration) { +- ClassDeclaration classDeclaration = unitMember; +- List classContents = []; +- for (ClassMember classMember in classDeclaration.members) { +- if (classMember is ConstructorDeclaration) { +- ConstructorDeclaration constructorDeclaration = classMember; +- classContents.add(_newConstructorOutline(constructorDeclaration)); +- } +- if (classMember is FieldDeclaration) { +- FieldDeclaration fieldDeclaration = classMember; +- VariableDeclarationList fields = fieldDeclaration.fields; +- if (fields != null) { +- TypeAnnotation fieldType = fields.type; +- String fieldTypeName = _safeToSource(fieldType); +- for (VariableDeclaration field in fields.variables) { +- classContents.add(_newVariableOutline(fieldTypeName, +- ElementKind.FIELD, field, fieldDeclaration.isStatic)); +- } +- } +- } +- if (classMember is MethodDeclaration) { +- MethodDeclaration methodDeclaration = classMember; +- classContents.add(_newMethodOutline(methodDeclaration)); +- } +- } +- unitContents.add(_newClassOutline(classDeclaration, classContents)); +- } +- if (unitMember is EnumDeclaration) { +- EnumDeclaration enumDeclaration = unitMember; +- List constantOutlines = []; +- for (EnumConstantDeclaration constant in enumDeclaration.constants) { +- constantOutlines.add(_newEnumConstant(constant)); +- } +- unitContents.add(_newEnumOutline(enumDeclaration, constantOutlines)); +- } +- if (unitMember is TopLevelVariableDeclaration) { +- TopLevelVariableDeclaration fieldDeclaration = unitMember; +- VariableDeclarationList fields = fieldDeclaration.variables; +- if (fields != null) { +- TypeAnnotation fieldType = fields.type; +- String fieldTypeName = _safeToSource(fieldType); +- for (VariableDeclaration field in fields.variables) { +- unitContents.add(_newVariableOutline( +- fieldTypeName, ElementKind.TOP_LEVEL_VARIABLE, field, false)); +- } +- } +- } +- if (unitMember is FunctionDeclaration) { +- FunctionDeclaration functionDeclaration = unitMember; +- unitContents.add(_newFunctionOutline(functionDeclaration, true)); +- } +- if (unitMember is ClassTypeAlias) { +- ClassTypeAlias alias = unitMember; +- unitContents.add(_newClassTypeAlias(alias)); +- } +- if (unitMember is FunctionTypeAlias) { +- FunctionTypeAlias alias = unitMember; +- unitContents.add(_newFunctionTypeAliasOutline(alias)); +- } +- } +- Outline unitOutline = _newUnitOutline(unitContents); +- return unitOutline; +- } +- +- List _addFunctionBodyOutlines(FunctionBody body) { +- List contents = []; +- body.accept(new _FunctionBodyOutlinesVisitor(this, contents)); +- return contents; +- } +- +- Location _getLocationNode(AstNode node) { +- int offset = node.offset; +- int length = node.length; +- return _getLocationOffsetLength(offset, length); +- } +- +- Location _getLocationOffsetLength(int offset, int length) { +- LineInfo_Location lineLocation = lineInfo.getLocation(offset); +- int startLine = lineLocation.lineNumber; +- int startColumn = lineLocation.columnNumber; +- return new Location(file, offset, length, startLine, startColumn); +- } +- +- /** +- * Returns the [AstNode]'s source region. +- */ +- SourceRange _getSourceRange(AstNode node) { +- int endOffset = node.end; +- // prepare position of the node among its siblings +- int firstOffset; +- List siblings; +- AstNode parent = node.parent; +- // field +- if (parent is VariableDeclarationList) { +- VariableDeclarationList variableList = parent as VariableDeclarationList; +- List variables = variableList.variables; +- int variableIndex = variables.indexOf(node); +- if (variableIndex == variables.length - 1) { +- endOffset = variableList.parent.end; +- } +- if (variableIndex == 0) { +- node = parent.parent; +- parent = node.parent; +- } else if (variableIndex >= 1) { +- firstOffset = variables[variableIndex - 1].end; +- return new SourceRange(firstOffset, endOffset - firstOffset); +- } +- } +- // unit or class member +- if (parent is CompilationUnit) { +- firstOffset = node.offset; +- siblings = parent.declarations; +- } else if (parent is ClassDeclaration) { +- firstOffset = parent.leftBracket.end; +- siblings = parent.members; +- } else { +- int offset = node.offset; +- return new SourceRange(offset, endOffset - offset); +- } +- // first child: [endOfParent, endOfNode] +- int index = siblings.indexOf(node); +- if (index == 0) { +- return new SourceRange(firstOffset, endOffset - firstOffset); +- } +- // not first child: [endOfPreviousSibling, endOfNode] +- int prevSiblingEnd = siblings[index - 1].end; +- return new SourceRange(prevSiblingEnd, endOffset - prevSiblingEnd); +- } +- +- Outline _newClassOutline(ClassDeclaration node, List classContents) { +- SimpleIdentifier nameNode = node.name; +- String name = nameNode.name; +- SourceRange range = _getSourceRange(node); +- Element element = new Element( +- ElementKind.CLASS, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(node), +- isAbstract: node.isAbstract), +- location: _getLocationNode(nameNode), +- typeParameters: _getTypeParametersStr(node.typeParameters)); +- return new Outline(element, range.offset, range.length, +- children: nullIfEmpty(classContents)); +- } +- +- Outline _newClassTypeAlias(ClassTypeAlias node) { +- SimpleIdentifier nameNode = node.name; +- String name = nameNode.name; +- SourceRange range = _getSourceRange(node); +- Element element = new Element( +- ElementKind.CLASS_TYPE_ALIAS, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(node), +- isAbstract: node.isAbstract), +- location: _getLocationNode(nameNode), +- typeParameters: _getTypeParametersStr(node.typeParameters)); +- return new Outline(element, range.offset, range.length); +- } +- +- Outline _newConstructorOutline(ConstructorDeclaration constructor) { +- Identifier returnType = constructor.returnType; +- String name = returnType.name; +- int offset = returnType.offset; +- int length = returnType.length; +- SimpleIdentifier constructorNameNode = constructor.name; +- bool isPrivate = false; +- if (constructorNameNode != null) { +- String constructorName = constructorNameNode.name; +- isPrivate = Identifier.isPrivateName(constructorName); +- name += '.$constructorName'; +- offset = constructorNameNode.offset; +- length = constructorNameNode.length; +- } +- SourceRange range = _getSourceRange(constructor); +- FormalParameterList parameters = constructor.parameters; +- String parametersStr = _safeToSource(parameters); +- Element element = new Element( +- ElementKind.CONSTRUCTOR, +- name, +- Element.makeFlags( +- isPrivate: isPrivate, isDeprecated: _isDeprecated(constructor)), +- location: _getLocationOffsetLength(offset, length), +- parameters: parametersStr); +- List contents = _addFunctionBodyOutlines(constructor.body); +- Outline outline = new Outline(element, range.offset, range.length, +- children: nullIfEmpty(contents)); +- return outline; +- } +- +- Outline _newEnumConstant(EnumConstantDeclaration node) { +- SimpleIdentifier nameNode = node.name; +- String name = nameNode.name; +- SourceRange range = _getSourceRange(node); +- Element element = new Element( +- ElementKind.ENUM_CONSTANT, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(node)), +- location: _getLocationNode(nameNode)); +- return new Outline(element, range.offset, range.length); +- } +- +- Outline _newEnumOutline(EnumDeclaration node, List children) { +- SimpleIdentifier nameNode = node.name; +- String name = nameNode.name; +- SourceRange range = _getSourceRange(node); +- Element element = new Element( +- ElementKind.ENUM, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(node)), +- location: _getLocationNode(nameNode)); +- return new Outline(element, range.offset, range.length, +- children: nullIfEmpty(children)); +- } +- +- Outline _newFunctionOutline(FunctionDeclaration function, bool isStatic) { +- TypeAnnotation returnType = function.returnType; +- SimpleIdentifier nameNode = function.name; +- String name = nameNode.name; +- FunctionExpression functionExpression = function.functionExpression; +- FormalParameterList parameters = functionExpression.parameters; +- ElementKind kind; +- if (function.isGetter) { +- kind = ElementKind.GETTER; +- } else if (function.isSetter) { +- kind = ElementKind.SETTER; +- } else { +- kind = ElementKind.FUNCTION; +- } +- SourceRange range = _getSourceRange(function); +- String parametersStr = _safeToSource(parameters); +- String returnTypeStr = _safeToSource(returnType); +- Element element = new Element( +- kind, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(function), +- isStatic: isStatic), +- location: _getLocationNode(nameNode), +- parameters: parametersStr, +- returnType: returnTypeStr); +- List contents = _addFunctionBodyOutlines(functionExpression.body); +- Outline outline = new Outline(element, range.offset, range.length, +- children: nullIfEmpty(contents)); +- return outline; +- } +- +- Outline _newFunctionTypeAliasOutline(FunctionTypeAlias node) { +- TypeAnnotation returnType = node.returnType; +- SimpleIdentifier nameNode = node.name; +- String name = nameNode.name; +- SourceRange range = _getSourceRange(node); +- FormalParameterList parameters = node.parameters; +- String parametersStr = _safeToSource(parameters); +- String returnTypeStr = _safeToSource(returnType); +- Element element = new Element( +- ElementKind.FUNCTION_TYPE_ALIAS, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(node)), +- location: _getLocationNode(nameNode), +- parameters: parametersStr, +- returnType: returnTypeStr, +- typeParameters: _getTypeParametersStr(node.typeParameters)); +- return new Outline(element, range.offset, range.length); +- } +- +- Outline _newMethodOutline(MethodDeclaration method) { +- TypeAnnotation returnType = method.returnType; +- SimpleIdentifier nameNode = method.name; +- String name = nameNode.name; +- FormalParameterList parameters = method.parameters; +- ElementKind kind; +- if (method.isGetter) { +- kind = ElementKind.GETTER; +- } else if (method.isSetter) { +- kind = ElementKind.SETTER; +- } else { +- kind = ElementKind.METHOD; +- } +- SourceRange range = _getSourceRange(method); +- String parametersStr = parameters?.toSource(); +- String returnTypeStr = _safeToSource(returnType); +- Element element = new Element( +- kind, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(method), +- isAbstract: method.isAbstract, +- isStatic: method.isStatic), +- location: _getLocationNode(nameNode), +- parameters: parametersStr, +- returnType: returnTypeStr); +- List contents = _addFunctionBodyOutlines(method.body); +- Outline outline = new Outline(element, range.offset, range.length, +- children: nullIfEmpty(contents)); +- return outline; +- } +- +- Outline _newUnitOutline(List unitContents) { +- Element element = new Element( +- ElementKind.COMPILATION_UNIT, '', Element.makeFlags(), +- location: _getLocationNode(unit)); +- return new Outline(element, unit.offset, unit.length, +- children: nullIfEmpty(unitContents)); +- } +- +- Outline _newVariableOutline(String typeName, ElementKind kind, +- VariableDeclaration variable, bool isStatic) { +- SimpleIdentifier nameNode = variable.name; +- String name = nameNode.name; +- SourceRange range = _getSourceRange(variable); +- Element element = new Element( +- kind, +- name, +- Element.makeFlags( +- isPrivate: Identifier.isPrivateName(name), +- isDeprecated: _isDeprecated(variable), +- isStatic: isStatic, +- isConst: variable.isConst, +- isFinal: variable.isFinal), +- location: _getLocationNode(nameNode), +- returnType: typeName); +- Outline outline = new Outline(element, range.offset, range.length); +- return outline; +- } +- +- static String _getTypeParametersStr(TypeParameterList parameters) { +- if (parameters == null) { +- return null; +- } +- return parameters.toSource(); +- } +- +- /** +- * Returns `true` if the given [element] is not `null` and deprecated. +- */ +- static bool _isDeprecated(Declaration declaration) { +- engine.Element element = declaration.element; +- return element != null && element.isDeprecated; +- } +- +- static String _safeToSource(AstNode node) => +- node == null ? '' : node.toSource(); +-} +- +-/** +- * A visitor for building local function outlines. +- */ +-class _FunctionBodyOutlinesVisitor extends RecursiveAstVisitor { +- final DartUnitOutlineComputer outlineComputer; +- final List contents; +- +- _FunctionBodyOutlinesVisitor(this.outlineComputer, this.contents); +- +- /** +- * Return `true` if the given [element] is the method 'group' defined in the +- * test package. +- */ +- bool isGroup(engine.ExecutableElement element) { +- return element is engine.FunctionElement && +- element.name == 'group' && +- _isInsideTestPackage(element); +- } +- +- /** +- * Return `true` if the given [element] is the method 'test' defined in the +- * test package. +- */ +- bool isTest(engine.ExecutableElement element) { +- return element is engine.FunctionElement && +- element.name == 'test' && +- _isInsideTestPackage(element); +- } +- +- @override +- visitFunctionDeclaration(FunctionDeclaration node) { +- contents.add(outlineComputer._newFunctionOutline(node, false)); +- } +- +- @override +- visitInstanceCreationExpression(InstanceCreationExpression node) { +- if (flutter.isWidgetCreation(node)) { +- List children = []; +- node.argumentList +- .accept(new _FunctionBodyOutlinesVisitor(outlineComputer, children)); +- +- String text = flutter.getWidgetPresentationText(node); +- Element element = new Element(ElementKind.CONSTRUCTOR_INVOCATION, text, 0, +- location: outlineComputer._getLocationOffsetLength(node.offset, 0)); +- +- contents.add(new Outline(element, node.offset, node.length, +- children: nullIfEmpty(children))); +- } else { +- super.visitInstanceCreationExpression(node); +- } +- } +- +- @override +- visitMethodInvocation(MethodInvocation node) { +- SimpleIdentifier nameNode = node.methodName; +- engine.ExecutableElement executableElement = nameNode.bestElement; +- +- String extractString(NodeList arguments) { +- if (arguments != null && arguments.length > 0) { +- Expression argument = arguments[0]; +- if (argument is StringLiteral) { +- String value = argument.stringValue; +- if (value != null) { +- return value; +- } +- } +- return argument.toSource(); +- } +- return 'unnamed'; +- } +- +- void addOutlineNode(ElementKind kind, [List children]) { +- SourceRange range = outlineComputer._getSourceRange(node); +- String kindName = kind == ElementKind.UNIT_TEST_GROUP ? 'group' : 'test'; +- String name = '$kindName("${extractString( +- node.argumentList?.arguments)}")'; +- Element element = new Element(kind, name, 0, +- location: outlineComputer._getLocationNode(nameNode)); +- contents.add(new Outline(element, range.offset, range.length, +- children: nullIfEmpty(children))); +- } +- +- if (isGroup(executableElement)) { +- List groupContents = []; +- node.argumentList.accept( +- new _FunctionBodyOutlinesVisitor(outlineComputer, groupContents)); +- addOutlineNode(ElementKind.UNIT_TEST_GROUP, groupContents); +- } else if (isTest(executableElement)) { +- addOutlineNode(ElementKind.UNIT_TEST_TEST); +- } else { +- super.visitMethodInvocation(node); +- } +- } +- +- /** +- * Return `true` if the given [element] is a top-level member of the test +- * package. +- */ +- bool _isInsideTestPackage(engine.FunctionElement element) { +- engine.Element parent = element.enclosingElement; +- return parent is engine.CompilationUnitElement && +- parent.source.fullName.endsWith('test.dart'); +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart +deleted file mode 100644 +index 5d53fd72d92..00000000000 +--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart ++++ /dev/null +@@ -1,237 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/collections.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as proto; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +- +-/** +- * Return the elements that the given [element] overrides. +- */ +-OverriddenElements findOverriddenElements(Element element) { +- if (element?.enclosingElement is ClassElement) { +- return new _OverriddenElementsFinder(element).find(); +- } +- return new OverriddenElements(element, [], []); +-} +- +-/** +- * A computer for class member overrides in a Dart [CompilationUnit]. +- */ +-class DartUnitOverridesComputer { +- final CompilationUnit _unit; +- final List _overrides = []; +- +- DartUnitOverridesComputer(this._unit); +- +- /** +- * Returns the computed occurrences, not `null`. +- */ +- List compute() { +- for (CompilationUnitMember unitMember in _unit.declarations) { +- if (unitMember is ClassDeclaration) { +- for (ClassMember classMember in unitMember.members) { +- if (classMember is MethodDeclaration) { +- if (classMember.isStatic) { +- continue; +- } +- _addOverride(classMember.name); +- } +- if (classMember is FieldDeclaration) { +- if (classMember.isStatic) { +- continue; +- } +- List fields = classMember.fields.variables; +- for (VariableDeclaration field in fields) { +- _addOverride(field.name); +- } +- } +- } +- } +- } +- return _overrides; +- } +- +- /** +- * Add a new [Override] for the declaration with the given name [node]. +- */ +- void _addOverride(SimpleIdentifier node) { +- Element element = node.staticElement; +- OverriddenElements overridesResult = +- new _OverriddenElementsFinder(element).find(); +- List superElements = overridesResult.superElements; +- List interfaceElements = overridesResult.interfaceElements; +- if (superElements.isNotEmpty || interfaceElements.isNotEmpty) { +- proto.OverriddenMember superMember = superElements.isNotEmpty +- ? proto.newOverriddenMember_fromEngine(superElements.first) +- : null; +- List interfaceMembers = interfaceElements +- .map((member) => proto.newOverriddenMember_fromEngine(member)) +- .toList(); +- _overrides.add(new proto.Override(node.offset, node.length, +- superclassMember: superMember, +- interfaceMembers: nullIfEmpty(interfaceMembers))); +- } +- } +-} +- +-/** +- * The container with elements that a class member overrides. +- */ +-class OverriddenElements { +- /** +- * The element that overrides other class members. +- */ +- final Element element; +- +- /** +- * The elements that [element] overrides and which is defined in a class that +- * is a superclass of the class that defines [element]. +- */ +- final List superElements; +- +- /** +- * The elements that [element] overrides and which is defined in a class that +- * which is implemented by the class that defines [element]. +- */ +- final List interfaceElements; +- +- OverriddenElements(this.element, this.superElements, this.interfaceElements); +-} +- +-class _OverriddenElementsFinder { +- static const List FIELD_KINDS = const [ +- ElementKind.FIELD, +- ElementKind.GETTER, +- ElementKind.SETTER +- ]; +- +- static const List GETTER_KINDS = const [ +- ElementKind.FIELD, +- ElementKind.GETTER +- ]; +- +- static const List METHOD_KINDS = const [ +- ElementKind.METHOD +- ]; +- +- static const List SETTER_KINDS = const [ +- ElementKind.FIELD, +- ElementKind.SETTER +- ]; +- +- Element _seed; +- LibraryElement _library; +- ClassElement _class; +- String _name; +- List _kinds; +- +- List _superElements = []; +- List _interfaceElements = []; +- Set _visited = new Set(); +- +- _OverriddenElementsFinder(Element seed) { +- _seed = seed; +- _class = seed.enclosingElement; +- if (_class == null) { +- // TODO(brianwilkerson) Remove this code when the issue has been fixed +- // (https://github.com/dart-lang/sdk/issues/25884) +- Type type = seed.runtimeType; +- String name = seed.name; +- throw new ArgumentError( +- 'The $type named $name does not have an enclosing element'); +- } +- _library = _class.library; +- _name = seed.displayName; +- if (seed is MethodElement) { +- _kinds = METHOD_KINDS; +- } else if (seed is PropertyAccessorElement) { +- _kinds = seed.isGetter ? GETTER_KINDS : SETTER_KINDS; +- } else { +- _kinds = FIELD_KINDS; +- } +- } +- +- /** +- * Add the [OverriddenElements] for this element. +- */ +- OverriddenElements find() { +- _visited.clear(); +- _addSuperOverrides(_class.supertype); +- _visited.clear(); +- _addInterfaceOverrides(_class.type, false); +- _superElements.forEach(_interfaceElements.remove); +- return new OverriddenElements(_seed, _superElements, _interfaceElements); +- } +- +- void _addInterfaceOverrides(InterfaceType type, bool checkType) { +- if (type == null) { +- return; +- } +- if (!_visited.add(type)) { +- return; +- } +- // this type +- if (checkType) { +- Element element = _lookupMember(type.element); +- if (element != null && !_interfaceElements.contains(element)) { +- _interfaceElements.add(element); +- } +- } +- // interfaces +- for (InterfaceType interfaceType in type.interfaces) { +- _addInterfaceOverrides(interfaceType, true); +- } +- // super +- _addInterfaceOverrides(type.superclass, checkType); +- } +- +- void _addSuperOverrides(InterfaceType type) { +- if (type == null) { +- return; +- } +- if (!_visited.add(type)) { +- return; +- } +- // this type +- Element element = _lookupMember(type.element); +- if (element != null && !_superElements.contains(element)) { +- _superElements.add(element); +- } +- // super +- _addSuperOverrides(type.superclass); +- } +- +- Element _lookupMember(ClassElement classElement) { +- if (classElement == null) { +- return null; +- } +- Element member; +- // method +- if (_kinds.contains(ElementKind.METHOD)) { +- member = classElement.lookUpMethod(_name, _library); +- if (member != null) { +- return member; +- } +- } +- // getter +- if (_kinds.contains(ElementKind.GETTER)) { +- member = classElement.lookUpGetter(_name, _library); +- if (member != null) { +- return member; +- } +- } +- // setter +- if (_kinds.contains(ElementKind.SETTER)) { +- member = classElement.lookUpSetter(_name + '=', _library); +- if (member != null) { +- return member; +- } +- } +- // not found +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart +deleted file mode 100644 +index 0b3617e57df..00000000000 +--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart ++++ /dev/null +@@ -1,433 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/dart/analysis/results.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/ast_factory.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/ast/ast_factory.dart'; +-import 'package:analyzer/src/dart/ast/token.dart'; +-import 'package:analyzer/src/dart/resolver/scope.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +-import 'package:front_end/src/base/syntactic_entity.dart'; +-import 'package:path/src/context.dart'; +- +-/** +- * An object used to compute a set of edits to add imports to a given library in +- * order to make a given set of elements visible. +- * +- * This is used to implement the `edit.importElements` request. +- */ +-class ImportElementsComputer { +- /** +- * The resource provider used to access the file system. +- */ +- final ResourceProvider resourceProvider; +- +- /** +- * The resolution result associated with the defining compilation unit of the +- * library to which imports might be added. +- */ +- final ResolveResult libraryResult; +- +- /** +- * Initialize a newly created builder. +- */ +- ImportElementsComputer(this.resourceProvider, this.libraryResult); +- +- /** +- * Create the edits that will cause the list of [importedElements] to be +- * imported into the library at the given [path]. +- */ +- Future createEdits( +- List importedElementsList) async { +- List filteredImportedElements = +- _filterImportedElements(importedElementsList); +- LibraryElement libraryElement = libraryResult.libraryElement; +- SourceFactory sourceFactory = libraryResult.session.sourceFactory; +- List existingImports = []; +- for (var directive in libraryResult.unit.directives) { +- if (directive is ImportDirective) { +- existingImports.add(directive); +- } +- } +- +- DartChangeBuilder builder = new DartChangeBuilder(libraryResult.session); +- await builder.addFileEdit(libraryResult.path, +- (DartFileEditBuilder builder) { +- for (ImportedElements importedElements in filteredImportedElements) { +- List matchingImports = +- _findMatchingImports(existingImports, importedElements); +- if (matchingImports.isEmpty) { +- // +- // The required library is not being imported with a matching prefix, +- // so we need to add an import. +- // +- File importedFile = resourceProvider.getFile(importedElements.path); +- Uri uri = sourceFactory.restoreUri(importedFile.createSource()); +- Source importedSource = importedFile.createSource(uri); +- String importUri = +- _getLibrarySourceUri(libraryElement, importedSource); +- _InsertionDescription description = +- _getInsertionDescription(importUri); +- builder.addInsertion(description.offset, (DartEditBuilder builder) { +- for (int i = 0; i < description.newLinesBefore; i++) { +- builder.writeln(); +- } +- builder.write("import '"); +- builder.write(importUri); +- builder.write("'"); +- if (importedElements.prefix.isNotEmpty) { +- builder.write(' as '); +- builder.write(importedElements.prefix); +- } +- builder.write(';'); +- for (int i = 0; i < description.newLinesAfter; i++) { +- builder.writeln(); +- } +- }); +- } else { +- // +- // There are some imports of the library with a matching prefix. We +- // need to determine whether the names are already visible or whether +- // we need to make edits to make them visible. +- // +- // Compute the edits that need to be made. +- // +- Map updateMap = +- {}; +- for (String requiredName in importedElements.elements) { +- _computeUpdate(updateMap, matchingImports, requiredName); +- } +- // +- // Apply the edits. +- // +- for (ImportDirective directive in updateMap.keys) { +- _ImportUpdate update = updateMap[directive]; +- List namesToUnhide = update.namesToUnhide; +- List namesToShow = update.namesToShow; +- namesToShow.sort(); +- NodeList combinators = directive.combinators; +- int combinatorCount = combinators.length; +- for (int combinatorIndex = 0; +- combinatorIndex < combinatorCount; +- combinatorIndex++) { +- Combinator combinator = combinators[combinatorIndex]; +- if (combinator is HideCombinator && namesToUnhide.isNotEmpty) { +- NodeList hiddenNames = combinator.hiddenNames; +- int nameCount = hiddenNames.length; +- int first = -1; +- for (int nameIndex = 0; nameIndex < nameCount; nameIndex++) { +- if (namesToUnhide.contains(hiddenNames[nameIndex].name)) { +- if (first < 0) { +- first = nameIndex; +- } +- } else { +- if (first >= 0) { +- // Remove a range of names. +- builder.addDeletion(range.startStart( +- hiddenNames[first], hiddenNames[nameIndex])); +- first = -1; +- } +- } +- } +- if (first == 0) { +- // Remove the whole combinator. +- if (combinatorIndex == 0) { +- if (combinatorCount > 1) { +- builder.addDeletion(range.startStart( +- combinator, combinators[combinatorIndex + 1])); +- } else { +- SyntacticEntity precedingNode = directive.prefix ?? +- directive.deferredKeyword ?? +- directive.uri; +- if (precedingNode == null) { +- builder.addDeletion(range.node(combinator)); +- } else { +- builder.addDeletion( +- range.endEnd(precedingNode, combinator)); +- } +- } +- } else { +- builder.addDeletion(range.endEnd( +- combinators[combinatorIndex - 1], combinator)); +- } +- } else if (first > 0) { +- // Remove a range of names that includes the last name. +- builder.addDeletion(range.endEnd( +- hiddenNames[first - 1], hiddenNames[nameCount - 1])); +- } +- } else if (combinator is ShowCombinator && +- namesToShow.isNotEmpty) { +- // TODO(brianwilkerson) Add the names in alphabetic order. +- builder.addInsertion(combinator.shownNames.last.end, +- (DartEditBuilder builder) { +- for (String nameToShow in namesToShow) { +- builder.write(', '); +- builder.write(nameToShow); +- } +- }); +- } +- } +- } +- } +- } +- }); +- return builder.sourceChange; +- } +- +- /** +- * Choose the import for which the least amount of work is required, +- * preferring to do no work in there is an import that already makes the name +- * visible, and preferring to remove hide combinators rather than add show +- * combinators. +- * +- * The name is visible without needing any changes if: +- * - there is an import with no combinators, +- * - there is an import with only hide combinators and none of them hide the +- * name, +- * - there is an import that shows the name and doesn't subsequently hide the +- * name. +- */ +- void _computeUpdate(Map updateMap, +- List matchingImports, String requiredName) { +- /** +- * Return `true` if the [requiredName] is in the given list of [names]. +- */ +- bool nameIn(NodeList names) { +- for (SimpleIdentifier name in names) { +- if (name.name == requiredName) { +- return true; +- } +- } +- return false; +- } +- +- ImportDirective preferredDirective = null; +- int bestEditCount = -1; +- bool deleteHide = false; +- bool addShow = false; +- +- for (ImportDirective directive in matchingImports) { +- NodeList combinators = directive.combinators; +- if (combinators.isEmpty) { +- return; +- } +- bool hasHide = false; +- bool needsShow = false; +- int editCount = 0; +- for (Combinator combinator in combinators) { +- if (combinator is HideCombinator) { +- if (nameIn(combinator.hiddenNames)) { +- hasHide = true; +- editCount++; +- } +- } else if (combinator is ShowCombinator) { +- if (needsShow || !nameIn(combinator.shownNames)) { +- needsShow = true; +- editCount++; +- } +- } +- } +- if (editCount == 0) { +- return; +- } else if (bestEditCount < 0 || editCount < bestEditCount) { +- preferredDirective = directive; +- bestEditCount = editCount; +- deleteHide = hasHide; +- addShow = needsShow; +- } +- } +- +- _ImportUpdate update = updateMap.putIfAbsent( +- preferredDirective, () => new _ImportUpdate(preferredDirective)); +- if (deleteHide) { +- update.unhide(requiredName); +- } +- if (addShow) { +- update.show(requiredName); +- } +- } +- +- /** +- * Filter the given list of imported elements ([originalList]) so that only +- * the names that are not already defined still remain. Names that are already +- * defined are removed even if they might not resolve to the same name as in +- * the original source. +- */ +- List _filterImportedElements( +- List originalList) { +- LibraryElement libraryElement = libraryResult.libraryElement; +- LibraryScope libraryScope = new LibraryScope(libraryElement); +- AstFactory factory = new AstFactoryImpl(); +- List filteredList = []; +- for (ImportedElements elements in originalList) { +- List originalElements = elements.elements; +- List filteredElements = originalElements.toList(); +- for (String name in originalElements) { +- Identifier identifier = factory +- .simpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); +- if (elements.prefix.isNotEmpty) { +- SimpleIdentifier prefix = factory.simpleIdentifier( +- new StringToken(TokenType.IDENTIFIER, elements.prefix, -1)); +- Token period = new SimpleToken(TokenType.PERIOD, -1); +- identifier = factory.prefixedIdentifier(prefix, period, identifier); +- } +- Element element = libraryScope.lookup(identifier, libraryElement); +- if (element != null) { +- filteredElements.remove(name); +- } +- } +- if (originalElements.length == filteredElements.length) { +- filteredList.add(elements); +- } else if (filteredElements.isNotEmpty) { +- filteredList.add(new ImportedElements( +- elements.path, elements.prefix, filteredElements)); +- } +- } +- return filteredList; +- } +- +- /** +- * Return all of the import elements in the list of [existingImports] that +- * match the given specification of [importedElements], or an empty list if +- * there are no such imports. +- */ +- List _findMatchingImports( +- List existingImports, +- ImportedElements importedElements) { +- List matchingImports = []; +- for (ImportDirective existingImport in existingImports) { +- if (_matches(existingImport, importedElements)) { +- matchingImports.add(existingImport); +- } +- } +- return matchingImports; +- } +- +- /** +- * Return the offset at which an import of the given [importUri] should be +- * inserted. +- * +- * Partially copied from DartFileEditBuilderImpl. +- */ +- _InsertionDescription _getInsertionDescription(String importUri) { +- CompilationUnit unit = libraryResult.unit; +- LibraryDirective libraryDirective; +- List importDirectives = []; +- List otherDirectives = []; +- for (Directive directive in unit.directives) { +- if (directive is LibraryDirective) { +- libraryDirective = directive; +- } else if (directive is ImportDirective) { +- importDirectives.add(directive); +- } else { +- otherDirectives.add(directive); +- } +- } +- if (importDirectives.isEmpty) { +- if (libraryDirective == null) { +- if (otherDirectives.isEmpty) { +- // TODO(brianwilkerson) Insert after any non-doc comments. +- return new _InsertionDescription(0, after: 2); +- } +- return new _InsertionDescription(otherDirectives[0].offset, after: 2); +- } +- return new _InsertionDescription(libraryDirective.end, before: 2); +- } +- // TODO(brianwilkerson) Fix this to find the right location. +- // See DartFileEditBuilderImpl._addLibraryImports for inspiration. +- return new _InsertionDescription(importDirectives.last.end, before: 1); +- } +- +- /** +- * Computes the best URI to import [what] into [from]. +- * +- * Copied from DartFileEditBuilderImpl. +- */ +- String _getLibrarySourceUri(LibraryElement from, Source what) { +- String whatPath = what.fullName; +- // check if an absolute URI (such as 'dart:' or 'package:') +- Uri whatUri = what.uri; +- String whatUriScheme = whatUri.scheme; +- if (whatUriScheme != '' && whatUriScheme != 'file') { +- return whatUri.toString(); +- } +- // compute a relative URI +- Context context = resourceProvider.pathContext; +- String fromFolder = context.dirname(from.source.fullName); +- String relativeFile = context.relative(whatPath, from: fromFolder); +- return context.split(relativeFile).join('/'); +- } +- +- /** +- * Return `true` if the given [import] matches the given specification of +- * [importedElements]. They will match if they import the same library using +- * the same prefix. +- */ +- bool _matches(ImportDirective import, ImportedElements importedElements) { +- return (import.element as ImportElement).importedLibrary.source.fullName == +- importedElements.path && +- (import.prefix?.name ?? '') == importedElements.prefix; +- } +-} +- +-/** +- * Information about how a given import directive needs to be updated in order +- * to make the required names visible. +- */ +-class _ImportUpdate { +- /** +- * The import directive to be updated. +- */ +- final ImportDirective import; +- +- /** +- * The list of names that are currently hidden that need to not be hidden. +- */ +- final List namesToUnhide = []; +- +- /** +- * The list of names that need to be added to show clauses. +- */ +- final List namesToShow = []; +- +- /** +- * Initialize a newly created information holder to hold information about +- * updates to the given [import]. +- */ +- _ImportUpdate(this.import); +- +- /** +- * Record that the given [name] needs to be added to show combinators. +- */ +- void show(String name) { +- namesToShow.add(name); +- } +- +- /** +- * Record that the given [name] needs to be removed from hide combinators. +- */ +- void unhide(String name) { +- namesToUnhide.add(name); +- } +-} +- +-class _InsertionDescription { +- final int newLinesBefore; +- final int offset; +- final int newLinesAfter; +- +- _InsertionDescription(this.offset, {int before: 0, int after: 0}) +- : this.newLinesBefore = before, +- this.newLinesAfter = after; +-} +diff --git a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart b/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart +deleted file mode 100644 +index e7dd9e87ac5..00000000000 +--- a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart ++++ /dev/null +@@ -1,129 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-/** +- * An object used to compute the list of elements referenced within a given +- * region of a compilation unit that are imported into the compilation unit's +- * library. +- */ +-class ImportedElementsComputer { +- /** +- * The compilation unit in which the elements are referenced. +- */ +- final CompilationUnit unit; +- +- /** +- * The offset of the region containing the references to be returned. +- */ +- final int offset; +- +- /** +- * The length of the region containing the references to be returned. +- */ +- final int length; +- +- /** +- * Initialize a newly created computer to compute the list of imported +- * elements referenced in the given [unit] within the region with the given +- * [offset] and [length]. +- */ +- ImportedElementsComputer(this.unit, this.offset, this.length); +- +- /** +- * Compute and return the list of imported elements. +- */ +- List compute() { +- _Visitor visitor = +- new _Visitor(unit.element.library, offset, offset + length); +- unit.accept(visitor); +- return visitor.importedElements.values.toList(); +- } +-} +- +-/** +- * The visitor used by an [ImportedElementsComputer] to record the names of all +- * imported elements. +- */ +-class _Visitor extends UnifyingAstVisitor { +- /** +- * The element representing the library containing the code being visited. +- */ +- final LibraryElement containingLibrary; +- +- /** +- * The offset of the start of the region of text being copied. +- */ +- final int startOffset; +- +- /** +- * The offset of the end of the region of text being copied. +- */ +- final int endOffset; +- +- /** +- * A table mapping library path and prefix keys to the imported elements from +- * that library. +- */ +- Map importedElements = {}; +- +- /** +- * Initialize a newly created visitor to visit nodes within a specified +- * region. +- */ +- _Visitor(this.containingLibrary, this.startOffset, this.endOffset); +- +- @override +- Object visitNode(AstNode node) { +- if (node.offset <= endOffset && node.end >= startOffset) { +- node.visitChildren(this); +- } +- return null; +- } +- +- @override +- Object visitSimpleIdentifier(SimpleIdentifier node) { +- if (!node.inDeclarationContext() && +- node.offset <= endOffset && +- node.end >= startOffset && +- !_isConstructorDeclarationReturnType(node)) { +- Element nodeElement = node.staticElement; +- if (nodeElement != null && +- nodeElement.enclosingElement is CompilationUnitElement) { +- LibraryElement nodeLibrary = nodeElement.library; +- String path = nodeLibrary.definingCompilationUnit.source.fullName; +- String prefix = ''; +- AstNode parent = node.parent; +- if (parent is PrefixedIdentifier && parent.identifier == node) { +- SimpleIdentifier prefixIdentifier = parent.prefix; +- if (prefixIdentifier.offset <= endOffset && +- prefixIdentifier.end >= startOffset) { +- Element prefixElement = prefixIdentifier.staticElement; +- if (prefixElement is PrefixElement) { +- prefix = prefixElement.name; +- } +- } +- } +- String key = '$prefix;$path'; +- ImportedElements elements = importedElements.putIfAbsent( +- key, () => new ImportedElements(path, prefix, [])); +- List elementNames = elements.elements; +- String elementName = nodeElement.name; +- if (!elementNames.contains(elementName)) { +- elementNames.add(elementName); +- } +- } +- } +- return null; +- } +- +- static bool _isConstructorDeclarationReturnType(SimpleIdentifier node) { +- AstNode parent = node.parent; +- return parent is ConstructorDeclaration && parent.returnType == node; +- } +-} +diff --git a/pkg/analysis_server/lib/src/computer/new_notifications.dart b/pkg/analysis_server/lib/src/computer/new_notifications.dart +deleted file mode 100644 +index 0e11991a95f..00000000000 +--- a/pkg/analysis_server/lib/src/computer/new_notifications.dart ++++ /dev/null +@@ -1,45 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart' as protocol; +-import 'package:analysis_server/src/analysis_server.dart' show AnalysisServer; +-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart'; +-import 'package:analysis_server/src/domains/analysis/occurrences.dart'; +-import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart'; +- +-void new_sendDartNotificationNavigation( +- AnalysisServer analysisServer, AnalysisResult result) { +- var unit = result.unit; +- if (unit != null) { +- NavigationCollectorImpl collector = new NavigationCollectorImpl(); +- computeDartNavigation(collector, unit, null, null); +- collector.createRegions(); +- var params = new protocol.AnalysisNavigationParams( +- result.path, collector.regions, collector.targets, collector.files); +- analysisServer.sendNotification(params.toNotification()); +- } +-} +- +-void new_sendDartNotificationOccurrences( +- AnalysisServer analysisServer, AnalysisResult result) { +- var unit = result.unit; +- if (unit != null) { +- OccurrencesCollectorImpl collector = new OccurrencesCollectorImpl(); +- addDartOccurrences(collector, unit); +- var params = new protocol.AnalysisOccurrencesParams( +- result.path, collector.allOccurrences); +- analysisServer.sendNotification(params.toNotification()); +- } +-} +- +-void new_sendErrorNotification( +- AnalysisServer analysisServer, AnalysisResult result) { +- var serverErrors = protocol.doAnalysisError_listFromEngine( +- result.driver.analysisOptions, result.lineInfo, result.errors); +- var params = new protocol.AnalysisErrorsParams(result.path, serverErrors); +- analysisServer.sendNotification(params.toNotification()); +-} +diff --git a/pkg/analysis_server/lib/src/constants.dart b/pkg/analysis_server/lib/src/constants.dart +deleted file mode 100644 +index ab9accf90a0..00000000000 +--- a/pkg/analysis_server/lib/src/constants.dart ++++ /dev/null +@@ -1,100 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-const String ADD = 'add'; +-const String ADDED = 'added'; +-const String ASSISTS = 'assists'; +-const String CHANGE = 'change'; +-const String CHILDREN = 'children'; +-const String CLASS_ELEMENT = 'classElement'; +-const String CLASS_NAME = 'className'; +-const String CODE = 'code'; +-const String COMPLETION = 'completion'; +-const String COMPLETION_RESULTS = 'completion.results'; +-const String CONTAINING_LIBRARY_NAME = 'containingLibraryName'; +-const String CONTAINING_LIBRARY_PATH = 'containingLibraryPath'; +-const String CONTENT = 'content'; +-const String CORRECTION = 'correction'; +-const String DART_DOC = 'dartdoc'; +-const String DEFAULT = 'default'; +-const String DISPLAY_NAME = 'displayName'; +-const String EDITS = 'edits'; +-const String ELEMENT = 'element'; // boolean +-const String ELEMENT_DESCRIPTION = 'elementDescription'; // boolean +-const String ELEMENT_KIND = 'elementKind'; // boolean +-const String ENABLE_ASYNC = 'enableAsync'; // boolean +-const String ENABLE_DEFERRED_LOADING = 'enableDeferredLoading'; // boolean +-const String ENABLE_ENUMS = 'enableEnums'; +-const String ERROR = 'error'; +-const String ERRORS = 'errors'; +-const String EXCLUDED = 'excluded'; +-const String FATAL = 'fatal'; +-const String FILE = 'file'; +-const String FILE_STAMP = 'fileStamp'; +-const String FILES = 'files'; +-const String FIXES = 'fixes'; +-const String FLAGS = 'flags'; +-const String GENERATE_DART2JS_HINTS = 'generateDart2jsHints'; +-const String GENERATE_HINTS = 'generateHints'; +-const String HAS_FIX = 'hasFix'; +-const String HIERARCHY_ITEMS = 'hierarchyItems'; +-const String HOVERS = 'hovers'; +-const String ID = 'id'; +-const String INCLUDE_POTENTIAL = 'includePotential'; +-const String INCLUDED = 'included'; +-const String INTERFACE_MEMBERS = 'interfaceMembers'; +-const String INTERFACES = 'interfaces'; +-const String IS_ABSTRACT = 'isAbstract'; +-const String IS_DEPRECATED = 'isDeprecated'; +-const String IS_POTENTIAL = 'isPotential'; +-const String IS_STATIC = 'isStatic'; +-const String KIND = 'kind'; +-const String KINDS = 'kinds'; +-const String LAST = 'last'; +-const String LENGTH = 'length'; +-const String LINKED_EDIT_GROUPS = 'linkedEditGroups'; +-const String LOCATION = 'location'; +-const String MEMBER_ELEMENT = 'memberElement'; +-const String MESSAGE = 'message'; +-const String MIXINS = 'mixins'; +-const String NAME = 'name'; +-const String OCCURRENCES = 'occurrences'; +-const String OFFSET = 'offset'; +-const String OFFSETS = 'offsets'; +-const String OPTIONS = 'options'; +-const String OUTLINE = 'outline'; +-const String OVERRIDES = 'overrides'; +-const String PARAMETER = 'parameter'; +-const String PARAMETERS = 'parameters'; +-const String PATH = 'path'; +-const String PATTERN = 'pattern'; +-const String POSITIONS = 'positions'; +-const String PROPAGATED_TYPE = 'propagatedType'; +-const String REFACTORINGS = 'refactorings'; +-const String REGIONS = 'regions'; +-const String RELEVANCE = 'relevance'; +-const String REMOVE = 'remove'; +-const String REMOVED = 'removed'; +-const String REPLACEMENT = 'replacement'; +-const String REPLACEMENT_LENGTH = 'replacementLength'; +-const String REPLACEMENT_OFFSET = 'replacementOffset'; +-const String RESULTS = 'results'; +-const String RETURN_TYPE = 'returnType'; +-const String SELECTION = 'selection'; +-const String SELECTION_LENGTH = 'selectionLength'; +-const String SELECTION_OFFSET = 'selectionOffset'; +-const String SEVERITY = 'severity'; +-const String STACK_TRACE = 'stackTrace'; +-const String START_COLUMN = 'startColumn'; +-const String START_LINE = 'startLine'; +-const String STATIC_TYPE = 'staticType'; +-const String SUBCLASSES = 'subclasses'; +-const String SUBSCRIPTIONS = 'subscriptions'; +-const String SUGGESTIONS = 'suggestions'; +-const String SUPER_CLASS_MEMBER = 'superclassMember'; +-const String SUPERCLASS = 'superclass'; +-const String TARGETS = 'targets'; +-const String TYPE = 'type'; +-const String VALUE = 'value'; +-const String VERSION = 'version'; +diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart +deleted file mode 100644 +index 889282319d3..00000000000 +--- a/pkg/analysis_server/lib/src/context_manager.dart ++++ /dev/null +@@ -1,1817 +0,0 @@ +-// Copyright (c) 2014, 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 'dart:convert'; +-import 'dart:core'; +- +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/plugin/resolver_provider.dart'; +-import 'package:analyzer/source/analysis_options_provider.dart'; +-import 'package:analyzer/source/package_map_provider.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/source/path_filter.dart'; +-import 'package:analyzer/source/pub_package_map_provider.dart'; +-import 'package:analyzer/source/sdk_ext.dart'; +-import 'package:analyzer/src/context/builder.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/sdk/sdk.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/java_engine.dart'; +-import 'package:analyzer/src/generated/java_io.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/source_io.dart'; +-import 'package:analyzer/src/task/options.dart'; +-import 'package:analyzer/src/util/absolute_path.dart'; +-import 'package:analyzer/src/util/glob.dart'; +-import 'package:analyzer/src/util/yaml.dart'; +-import 'package:analyzer_plugin/utilities/analyzer_converter.dart'; +-import 'package:package_config/packages.dart'; +-import 'package:package_config/packages_file.dart' as pkgfile show parse; +-import 'package:package_config/src/packages_impl.dart' show MapPackages; +-import 'package:path/path.dart' as pathos; +-import 'package:watcher/watcher.dart'; +-import 'package:yaml/yaml.dart'; +- +-/** +- * Information tracked by the [ContextManager] for each context. +- */ +-class ContextInfo { +- /** +- * The [Folder] for which this information object is created. +- */ +- final Folder folder; +- +- /// The [PathFilter] used to filter sources from being analyzed. +- final PathFilter pathFilter; +- +- /** +- * The enclosed pubspec-based contexts. +- */ +- final List children = []; +- +- /** +- * The package root for this context, or null if there is no package root. +- */ +- String packageRoot; +- +- /** +- * The [ContextInfo] that encloses this one, or `null` if this is the virtual +- * [ContextInfo] object that acts as the ancestor of all other [ContextInfo] +- * objects. +- */ +- ContextInfo parent; +- +- /** +- * The package description file path for this context. +- */ +- String packageDescriptionPath; +- +- /** +- * The folder disposition for this context. +- */ +- final FolderDisposition disposition; +- +- /** +- * Paths to files which determine the folder disposition and package map. +- * +- * TODO(paulberry): if any of these files are outside of [folder], they won't +- * be watched for changes. I believe the use case for watching these files +- * is no longer relevant. +- */ +- Set _dependencies = new Set(); +- +- /** +- * The analysis driver that was created for the [folder]. +- */ +- AnalysisDriver analysisDriver; +- +- /** +- * Map from full path to the [Source] object, for each source that has been +- * added to the context. +- */ +- Map sources = new HashMap(); +- +- ContextInfo(ContextManagerImpl contextManager, this.parent, Folder folder, +- File packagespecFile, this.packageRoot, this.disposition) +- : folder = folder, +- pathFilter = new PathFilter( +- folder.path, null, contextManager.resourceProvider.pathContext) { +- packageDescriptionPath = packagespecFile.path; +- parent.children.add(this); +- } +- +- /** +- * Create the virtual [ContextInfo] which acts as an ancestor to all other +- * [ContextInfo]s. +- */ +- ContextInfo._root() +- : folder = null, +- pathFilter = null, +- packageRoot = null, +- disposition = null; +- +- /** +- * Iterate through all [children] and their children, recursively. +- */ +- Iterable get descendants sync* { +- for (ContextInfo child in children) { +- yield child; +- yield* child.descendants; +- } +- } +- +- /** +- * Returns `true` if this is a "top level" context, meaning that the folder +- * associated with it is not contained within any other folders that have an +- * associated context. +- */ +- bool get isTopLevel => parent.parent == null; +- +- /** +- * Returns `true` if [path] is excluded, as it is in one of the children. +- */ +- bool excludes(String path) { +- return children.any((child) { +- return child.folder.contains(path); +- }); +- } +- +- /** +- * Returns `true` if [resource] is excluded, as it is in one of the children. +- */ +- bool excludesResource(Resource resource) => excludes(resource.path); +- +- /** +- * Return the first [ContextInfo] in [children] whose associated folder is or +- * contains [path]. If there is no such [ContextInfo], return `null`. +- */ +- ContextInfo findChildInfoFor(String path) { +- for (ContextInfo info in children) { +- if (info.folder.isOrContains(path)) { +- return info; +- } +- } +- return null; +- } +- +- /** +- * Determine if the given [path] is one of the dependencies most recently +- * passed to [setDependencies]. +- */ +- bool hasDependency(String path) => _dependencies.contains(path); +- +- /// Returns `true` if [path] should be ignored. +- bool ignored(String path) => pathFilter.ignored(path); +- +- /** +- * Returns `true` if [path] is the package description file for this context +- * (pubspec.yaml or .packages). +- */ +- bool isPathToPackageDescription(String path) => +- path == packageDescriptionPath; +- +- /** +- * Update the set of dependencies for this context. +- */ +- void setDependencies(Iterable newDependencies) { +- _dependencies = newDependencies.toSet(); +- } +- +- /** +- * Return `true` if the given [path] is managed by this context or by +- * any of its children. +- */ +- bool _managesOrHasChildThatManages(String path) { +- if (parent == null) { +- for (ContextInfo child in children) { +- if (child._managesOrHasChildThatManages(path)) { +- return true; +- } +- } +- return false; +- } else { +- if (!folder.isOrContains(path)) { +- return false; +- } +- for (ContextInfo child in children) { +- if (child._managesOrHasChildThatManages(path)) { +- return true; +- } +- } +- return !pathFilter.ignored(path); +- } +- } +-} +- +-/** +- * Class that maintains a mapping from included/excluded paths to a set of +- * folders that should correspond to analysis contexts. +- */ +-abstract class ContextManager { +- // TODO(brianwilkerson) Support: +- // setting the default analysis options +- // setting the default content cache +- // setting the default SDK +- // telling server when a context has been added or removed (see onContextsChanged) +- // telling server when a context needs to be re-analyzed +- // notifying the client when results should be flushed +- // using analyzeFileFunctions to determine which files to analyze +- // +- // TODO(brianwilkerson) Move this class to a public library. +- +- /** +- * Get the callback interface used to create, destroy, and update contexts. +- */ +- ContextManagerCallbacks get callbacks; +- +- /** +- * Set the callback interface used to create, destroy, and update contexts. +- */ +- void set callbacks(ContextManagerCallbacks value); +- +- /** +- * A table mapping [Folder]s to the [AnalysisDriver]s associated with them. +- */ +- Map get driverMap; +- +- /** +- * Return the list of excluded paths (folders and files) most recently passed +- * to [setRoots]. +- */ +- List get excludedPaths; +- +- /** +- * Return the list of included paths (folders and files) most recently passed +- * to [setRoots]. +- */ +- List get includedPaths; +- +- /** +- * Like [getDriverFor], but returns the [Folder] which allows plugins to +- * create & manage their own tree of drivers just like using [getDriverFor]. +- * +- * This folder should be the root of analysis context, not just the containing +- * folder of the path (like basename), as this is NOT just a file API. +- * +- * This exists at least temporarily, for plugin support until the new API is +- * ready. +- */ +- Folder getContextFolderFor(String path); +- +- /** +- * Return the [AnalysisDriver] for the "innermost" context whose associated +- * folder is or contains the given path. ("innermost" refers to the nesting +- * of contexts, so if there is a context for path /foo and a context for +- * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is +- * the context for /foo/bar.) +- * +- * If no driver contains the given path, `null` is returned. +- */ +- AnalysisDriver getDriverFor(String path); +- +- /** +- * Return a list of all of the analysis drivers reachable from the given +- * [analysisRoot] (the driver associated with [analysisRoot] and all of its +- * descendants). +- */ +- List getDriversInAnalysisRoot(Folder analysisRoot); +- +- /** +- * Return `true` if the given [path] is ignored by a [ContextInfo] whose +- * folder contains it. +- */ +- bool isIgnored(String path); +- +- /** +- * Return `true` if the given absolute [path] is in one of the current +- * root folders and is not excluded. +- */ +- bool isInAnalysisRoot(String path); +- +- /** +- * Return the number of contexts reachable from the given [analysisRoot] (the +- * context associated with [analysisRoot] and all of its descendants). +- */ +- int numberOfContextsInAnalysisRoot(Folder analysisRoot); +- +- /** +- * Rebuild the set of contexts from scratch based on the data last sent to +- * [setRoots]. Only contexts contained in the given list of analysis [roots] +- * will be rebuilt, unless the list is `null`, in which case every context +- * will be rebuilt. +- */ +- void refresh(List roots); +- +- /** +- * Change the set of paths which should be used as starting points to +- * determine the context directories. +- */ +- void setRoots(List includedPaths, List excludedPaths, +- Map packageRoots); +-} +- +-/** +- * Callback interface used by [ContextManager] to (a) request that contexts be +- * created, destroyed or updated, (b) inform the client when "pub list" +- * operations are in progress, and (c) determine which files should be +- * analyzed. +- * +- * TODO(paulberry): eliminate this interface, and instead have [ContextManager] +- * operations return data structures describing how context state should be +- * modified. +- */ +-abstract class ContextManagerCallbacks { +- /** +- * Return the notification manager associated with the server. +- */ +- NotificationManager get notificationManager; +- +- /** +- * Create and return a new analysis driver rooted at the given [folder], with +- * the given analysis [options]. +- */ +- AnalysisDriver addAnalysisDriver( +- Folder folder, ContextRoot contextRoot, AnalysisOptions options); +- +- /** +- * An [event] was processed, so analysis state might be different now. +- */ +- void afterWatchEvent(WatchEvent event); +- +- /** +- * Called when the set of files associated with a context have changed (or +- * some of those files have been modified). [changeSet] is the set of +- * changes that need to be applied to the context. +- */ +- void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); +- +- /** +- * The given [file] was removed from the folder analyzed in the [driver]. +- */ +- void applyFileRemoved(AnalysisDriver driver, String file); +- +- /** +- * Sent the given watch [event] to any interested plugins. +- */ +- void broadcastWatchEvent(WatchEvent event); +- +- /** +- * Signals that the context manager has started to compute a package map (if +- * [computing] is `true`) or has finished (if [computing] is `false`). +- */ +- void computingPackageMap(bool computing); +- +- /** +- * Create and return a context builder that can be used to create a context +- * for the files in the given [folder] when analyzed using the given [options]. +- */ +- ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options); +- +- /** +- * Called when the context manager changes the folder with which a context is +- * associated. Currently this is mostly FYI, and used only in tests. +- */ +- void moveContext(Folder from, Folder to); +- +- /** +- * Remove the context associated with the given [folder]. [flushedFiles] is +- * a list of the files which will be "orphaned" by removing this context +- * (they will no longer be analyzed by any context). +- */ +- void removeContext(Folder folder, List flushedFiles); +-} +- +-/** +- * Class that maintains a mapping from included/excluded paths to a set of +- * folders that should correspond to analysis contexts. +- */ +-class ContextManagerImpl implements ContextManager { +- /** +- * The name of the `doc` directory. +- */ +- static const String DOC_DIR_NAME = 'doc'; +- +- /** +- * The name of the `lib` directory. +- */ +- static const String LIB_DIR_NAME = 'lib'; +- +- /** +- * The name of `packages` folders. +- */ +- static const String PACKAGES_NAME = 'packages'; +- +- /** +- * File name of pubspec files. +- */ +- static const String PUBSPEC_NAME = 'pubspec.yaml'; +- +- /** +- * File name of package spec files. +- */ +- static const String PACKAGE_SPEC_NAME = '.packages'; +- +- /** +- * The name of the key in an embedder file whose value is the list of +- * libraries in the SDK. +- * TODO(brianwilkerson) This is also defined in sdk.dart. +- */ +- static const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs'; +- +- /** +- * The [ResourceProvider] using which paths are converted into [Resource]s. +- */ +- final ResourceProvider resourceProvider; +- +- /** +- * The manager used to access the SDK that should be associated with a +- * particular context. +- */ +- final DartSdkManager sdkManager; +- +- /** +- * The context used to work with absolute file system paths. +- * +- * TODO(scheglov) remove [pathContext]. +- */ +- AbsolutePathContext absolutePathContext; +- +- /** +- * The context used to work with file system paths. +- */ +- pathos.Context pathContext; +- +- /** +- * The list of excluded paths (folders and files) most recently passed to +- * [setRoots]. +- */ +- List excludedPaths = []; +- +- /** +- * The list of included paths (folders and files) most recently passed to +- * [setRoots]. +- */ +- List includedPaths = []; +- +- /** +- * The map of package roots most recently passed to [setRoots]. +- */ +- Map packageRoots = {}; +- +- /** +- * Same as [packageRoots], except that source folders have been normalized +- * and non-folders have been removed. +- */ +- Map normalizedPackageRoots = {}; +- +- /** +- * A function that will return a [UriResolver] that can be used to resolve +- * `package:` URI's within a given folder, or `null` if we should fall back +- * to the standard URI resolver. +- */ +- final ResolverProvider packageResolverProvider; +- +- /** +- * Provider which is used to determine the mapping from package name to +- * package folder. +- */ +- final PubPackageMapProvider _packageMapProvider; +- +- /** +- * A list of the globs used to determine which files should be analyzed. +- */ +- final List analyzedFilesGlobs; +- +- /** +- * The default options used to create new analysis contexts. +- */ +- final AnalysisOptionsImpl defaultContextOptions; +- +- /** +- * The instrumentation service used to report instrumentation data. +- */ +- final InstrumentationService _instrumentationService; +- +- @override +- ContextManagerCallbacks callbacks; +- +- /** +- * Virtual [ContextInfo] which acts as the ancestor of all other +- * [ContextInfo]s. +- */ +- final ContextInfo rootInfo = new ContextInfo._root(); +- +- @override +- final Map driverMap = +- new HashMap(); +- +- /** +- * Stream subscription we are using to watch each analysis root directory for +- * changes. +- */ +- final Map> changeSubscriptions = +- >{}; +- +- ContextManagerImpl( +- this.resourceProvider, +- this.sdkManager, +- this.packageResolverProvider, +- this._packageMapProvider, +- this.analyzedFilesGlobs, +- this._instrumentationService, +- this.defaultContextOptions) { +- absolutePathContext = resourceProvider.absolutePathContext; +- pathContext = resourceProvider.pathContext; +- } +- +- /** +- * Check if this map defines embedded libraries. +- */ +- bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null; +- +- Folder getContextFolderFor(String path) { +- return _getInnermostContextInfoFor(path)?.folder; +- } +- +- /** +- * For testing: get the [ContextInfo] object for the given [folder], if any. +- */ +- ContextInfo getContextInfoFor(Folder folder) { +- ContextInfo info = _getInnermostContextInfoFor(folder.path); +- if (info != null && folder == info.folder) { +- return info; +- } +- return null; +- } +- +- @override +- AnalysisDriver getDriverFor(String path) { +- return _getInnermostContextInfoFor(path)?.analysisDriver; +- } +- +- @override +- List getDriversInAnalysisRoot(Folder analysisRoot) { +- List drivers = []; +- void addContextAndDescendants(ContextInfo info) { +- drivers.add(info.analysisDriver); +- info.children.forEach(addContextAndDescendants); +- } +- +- ContextInfo innermostContainingInfo = +- _getInnermostContextInfoFor(analysisRoot.path); +- if (innermostContainingInfo != null) { +- if (analysisRoot == innermostContainingInfo.folder) { +- addContextAndDescendants(innermostContainingInfo); +- } else { +- for (ContextInfo info in innermostContainingInfo.children) { +- if (analysisRoot.isOrContains(info.folder.path)) { +- addContextAndDescendants(info); +- } +- } +- } +- } +- return drivers; +- } +- +- @override +- bool isIgnored(String path) { +- ContextInfo info = rootInfo; +- do { +- info = info.findChildInfoFor(path); +- if (info == null) { +- return false; +- } +- if (info.ignored(path)) { +- return true; +- } +- } while (true); +- } +- +- @override +- bool isInAnalysisRoot(String path) { +- // check if excluded +- if (_isExcluded(path)) { +- return false; +- } +- // check if in one of the roots +- for (ContextInfo info in rootInfo.children) { +- if (info.folder.contains(path)) { +- return true; +- } +- } +- // no +- return false; +- } +- +- @override +- int numberOfContextsInAnalysisRoot(Folder analysisRoot) { +- int count = 0; +- void addContextAndDescendants(ContextInfo info) { +- count++; +- info.children.forEach(addContextAndDescendants); +- } +- +- ContextInfo innermostContainingInfo = +- _getInnermostContextInfoFor(analysisRoot.path); +- if (innermostContainingInfo != null) { +- if (analysisRoot == innermostContainingInfo.folder) { +- addContextAndDescendants(innermostContainingInfo); +- } else { +- for (ContextInfo info in innermostContainingInfo.children) { +- if (analysisRoot.isOrContains(info.folder.path)) { +- addContextAndDescendants(info); +- } +- } +- } +- } +- return count; +- } +- +- /** +- * Process [options] for the given context [info]. +- */ +- void processOptionsForDriver(ContextInfo info, +- AnalysisOptionsImpl analysisOptions, Map options) { +- if (options == null) { +- return; +- } +- +- // Check for embedded options. +- Map embeddedOptions = _getEmbeddedOptions(info); +- if (embeddedOptions != null) { +- options = _toStringMap(new Merger().merge(embeddedOptions, options)); +- } +- +- applyToAnalysisOptions(analysisOptions, options); +- +- var analyzer = options[AnalyzerOptions.analyzer]; +- if (analyzer is Map) { +- // Set ignore patterns. +- YamlList exclude = analyzer[AnalyzerOptions.exclude]; +- List excludeList = toStringList(exclude); +- if (excludeList != null) { +- setIgnorePatternsForContext(info, excludeList); +- } +- } +- } +- +- @override +- void refresh(List roots) { +- // Destroy old contexts +- List contextInfos = rootInfo.descendants.toList(); +- if (roots == null) { +- contextInfos.forEach(_destroyContext); +- } else { +- roots.forEach((Resource resource) { +- contextInfos.forEach((ContextInfo contextInfo) { +- if (resource is Folder && +- resource.isOrContains(contextInfo.folder.path)) { +- _destroyContext(contextInfo); +- } +- }); +- }); +- } +- +- // Rebuild contexts based on the data last sent to setRoots(). +- setRoots(includedPaths, excludedPaths, packageRoots); +- } +- +- /** +- * Sets the [ignorePatterns] for the context having info [info]. +- */ +- void setIgnorePatternsForContext( +- ContextInfo info, List ignorePatterns) { +- info.pathFilter.setIgnorePatterns(ignorePatterns); +- } +- +- @override +- void setRoots(List includedPaths, List excludedPaths, +- Map packageRoots) { +- this.packageRoots = packageRoots; +- +- // Normalize all package root sources by mapping them to folders on the +- // filesystem. Ignore any package root sources that aren't folders. +- normalizedPackageRoots = {}; +- packageRoots.forEach((String sourcePath, String targetPath) { +- Resource resource = resourceProvider.getResource(sourcePath); +- if (resource is Folder) { +- normalizedPackageRoots[resource.path] = targetPath; +- } +- }); +- +- List contextInfos = rootInfo.descendants.toList(); +- // included +- List includedFolders = []; +- { +- // Sort paths to ensure that outer roots are handled before inner roots, +- // so we can correctly ignore inner roots, which are already managed +- // by outer roots. +- LinkedHashSet uniqueIncludedPaths = +- new LinkedHashSet.from(includedPaths); +- List sortedIncludedPaths = uniqueIncludedPaths.toList(); +- sortedIncludedPaths.sort((a, b) => a.length - b.length); +- // Convert paths to folders. +- for (String path in sortedIncludedPaths) { +- Resource resource = resourceProvider.getResource(path); +- if (resource is Folder) { +- includedFolders.add(resource); +- } else if (!resource.exists) { +- // Non-existent resources are ignored. TODO(paulberry): we should set +- // up a watcher to ensure that if the resource appears later, we will +- // begin analyzing it. +- } else { +- // TODO(scheglov) implemented separate files analysis +- throw new UnimplementedError('$path is not a folder. ' +- 'Only support for folder analysis is implemented currently.'); +- } +- } +- } +- this.includedPaths = includedPaths; +- // excluded +- List oldExcludedPaths = this.excludedPaths; +- this.excludedPaths = excludedPaths; +- // destroy old contexts +- for (ContextInfo contextInfo in contextInfos) { +- bool isIncluded = includedFolders.any((folder) { +- return folder.isOrContains(contextInfo.folder.path); +- }); +- if (!isIncluded) { +- _destroyContext(contextInfo); +- } +- } +- // Update package roots for existing contexts +- for (ContextInfo info in rootInfo.descendants) { +- String newPackageRoot = normalizedPackageRoots[info.folder.path]; +- if (info.packageRoot != newPackageRoot) { +- info.packageRoot = newPackageRoot; +- _recomputeFolderDisposition(info); +- } +- } +- // create new contexts +- for (Folder includedFolder in includedFolders) { +- String includedPath = includedFolder.path; +- bool isManaged = rootInfo._managesOrHasChildThatManages(includedPath); +- if (!isManaged) { +- ContextInfo parent = _getParentForNewContext(includedPath); +- changeSubscriptions[includedFolder] = +- includedFolder.changes.listen(_handleWatchEvent); +- _createContexts(parent, includedFolder, excludedPaths, false); +- } +- } +- // remove newly excluded sources +- for (ContextInfo info in rootInfo.descendants) { +- // prepare excluded sources +- Map excludedSources = new HashMap(); +- info.sources.forEach((String path, Source source) { +- if (_isExcludedBy(excludedPaths, path) && +- !_isExcludedBy(oldExcludedPaths, path)) { +- excludedSources[path] = source; +- } +- }); +- // apply exclusion +- ChangeSet changeSet = new ChangeSet(); +- excludedSources.forEach((String path, Source source) { +- info.sources.remove(path); +- changeSet.removedSource(source); +- }); +- callbacks.applyChangesToContext(info.folder, changeSet); +- } +- // add previously excluded sources +- for (ContextInfo info in rootInfo.descendants) { +- ChangeSet changeSet = new ChangeSet(); +- _addPreviouslyExcludedSources( +- info, changeSet, info.folder, oldExcludedPaths); +- callbacks.applyChangesToContext(info.folder, changeSet); +- } +- } +- +- /** +- * Recursively adds all Dart and HTML files to the [changeSet]. +- */ +- void _addPreviouslyExcludedSources(ContextInfo info, ChangeSet changeSet, +- Folder folder, List oldExcludedPaths) { +- if (info.excludesResource(folder)) { +- return; +- } +- List children; +- try { +- children = folder.getChildren(); +- } on FileSystemException { +- // The folder no longer exists, or cannot be read, to there's nothing to +- // do. +- return; +- } +- for (Resource child in children) { +- String path = child.path; +- // Path is being ignored. +- if (info.ignored(path)) { +- continue; +- } +- // add files, recurse into folders +- if (child is File) { +- // ignore if should not be analyzed at all +- if (!_shouldFileBeAnalyzed(child)) { +- continue; +- } +- // ignore if was not excluded +- bool wasExcluded = _isExcludedBy(oldExcludedPaths, path) && +- !_isExcludedBy(excludedPaths, path); +- if (!wasExcluded) { +- continue; +- } +- // do add the file +- Source source = createSourceInContext(info.analysisDriver, child); +- changeSet.addedSource(source); +- info.sources[path] = source; +- } else if (child is Folder) { +- if (child.shortName == PACKAGES_NAME) { +- continue; +- } +- _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); +- } +- } +- } +- +- /** +- * Recursively adds all Dart and HTML files to the [changeSet]. +- */ +- void _addSourceFiles(ChangeSet changeSet, Folder folder, ContextInfo info) { +- if (info.excludesResource(folder) || +- folder.shortName.startsWith('.') || +- _isInTopLevelDocDir(info.folder.path, folder.path)) { +- return; +- } +- List children = null; +- try { +- children = folder.getChildren(); +- } on FileSystemException { +- // The directory either doesn't exist or cannot be read. Either way, there +- // are no children that need to be added. +- return; +- } +- for (Resource child in children) { +- String path = child.path; +- // ignore excluded files or folders +- if (_isExcluded(path) || info.excludes(path) || info.ignored(path)) { +- continue; +- } +- // add files, recurse into folders +- if (child is File) { +- if (_shouldFileBeAnalyzed(child)) { +- Source source = createSourceInContext(info.analysisDriver, child); +- changeSet.addedSource(source); +- info.sources[path] = source; +- } +- } else if (child is Folder) { +- String shortName = child.shortName; +- if (shortName == PACKAGES_NAME) { +- continue; +- } +- _addSourceFiles(changeSet, child, info); +- } +- } +- } +- +- /** +- * Use the given analysis [driver] to analyze the content of the analysis +- * options file at the given [path]. +- */ +- void _analyzeAnalysisOptionsFile(AnalysisDriver driver, String path) { +- String content = driver.fsState.getFileForPath(path).content; +- List errors = +- GenerateOptionsErrorsTask.analyzeAnalysisOptions( +- resourceProvider.getFile(path).createSource(), +- content, +- driver.sourceFactory); +- AnalyzerConverter converter = new AnalyzerConverter(); +- LineInfo lineInfo = _computeLineInfo(content); +- callbacks.notificationManager.recordAnalysisErrors( +- NotificationManager.serverId, +- path, +- converter.convertAnalysisErrors(errors, +- lineInfo: lineInfo, options: driver.analysisOptions)); +- } +- +- void _checkForAnalysisOptionsUpdate( +- String path, ContextInfo info, ChangeType changeType) { +- if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) { +- AnalysisDriver driver = info.analysisDriver; +- if (driver == null) { +- // I suspect that this happens as a result of a race condition: server +- // has determined that the file (at [path]) is in a context, but hasn't +- // yet created a driver for that context. +- return; +- } +- String contextRoot = info.folder.path; +- ContextBuilder builder = +- callbacks.createContextBuilder(info.folder, defaultContextOptions); +- AnalysisOptions options = builder.getAnalysisOptions(contextRoot, +- contextRoot: driver.contextRoot); +- SourceFactory factory = builder.createSourceFactory(contextRoot, options); +- driver.configure(analysisOptions: options, sourceFactory: factory); +- // TODO(brianwilkerson) Set exclusion patterns. +- _analyzeAnalysisOptionsFile(driver, path); +- } +- } +- +- void _checkForPackagespecUpdate( +- String path, ContextInfo info, Folder folder) { +- // Check to see if this is the .packages file for this context and if so, +- // update the context's source factory. +- if (absolutePathContext.basename(path) == PACKAGE_SPEC_NAME) { +- String contextRoot = info.folder.path; +- ContextBuilder builder = +- callbacks.createContextBuilder(info.folder, defaultContextOptions); +- AnalysisDriver driver = info.analysisDriver; +- if (driver != null) { +- AnalysisOptions options = builder.getAnalysisOptions(contextRoot, +- contextRoot: driver.contextRoot); +- SourceFactory factory = +- builder.createSourceFactory(contextRoot, options); +- driver.configure(analysisOptions: options, sourceFactory: factory); +- } +- } +- } +- +- /** +- * Compute the set of files that are being flushed, this is defined as +- * the set of sources in the removed context (context.sources), that are +- * orphaned by this context being removed (no other context includes this +- * file.) +- */ +- List _computeFlushedFiles(ContextInfo info) { +- Set flushedFiles = info.analysisDriver.addedFiles.toSet(); +- for (ContextInfo contextInfo in rootInfo.descendants) { +- AnalysisDriver other = contextInfo.analysisDriver; +- if (other != info.analysisDriver) { +- flushedFiles.removeAll(other.addedFiles); +- } +- } +- return flushedFiles.toList(growable: false); +- } +- +- /** +- * Compute the appropriate [FolderDisposition] for [folder]. Use +- * [addDependency] to indicate which files needed to be consulted in order to +- * figure out the [FolderDisposition]; these dependencies will be watched in +- * order to determine when it is necessary to call this function again. +- * +- * TODO(paulberry): use [addDependency] for tracking all folder disposition +- * dependencies (currently we only use it to track "pub list" dependencies). +- */ +- FolderDisposition _computeFolderDisposition( +- Folder folder, void addDependency(String path), File packagespecFile) { +- String packageRoot = normalizedPackageRoots[folder.path]; +- if (packageRoot != null) { +- // TODO(paulberry): We shouldn't be using JavaFile here because it +- // makes the code untestable (see dartbug.com/23909). +- JavaFile packagesDirOrFile = new JavaFile(packageRoot); +- Map> packageMap = new Map>(); +- if (packagesDirOrFile.isDirectory()) { +- for (JavaFile file in packagesDirOrFile.listFiles()) { +- // Ensure symlinks in packages directory are canonicalized +- // to prevent 'type X cannot be assigned to type X' warnings +- String path; +- try { +- path = file.getCanonicalPath(); +- } catch (e, s) { +- // Ignore packages that do not exist +- _instrumentationService.logException(e, s); +- continue; +- } +- Resource res = resourceProvider.getResource(path); +- if (res is Folder) { +- packageMap[file.getName()] = [res]; +- } +- } +- return new PackageMapDisposition(packageMap, packageRoot: packageRoot); +- } else if (packagesDirOrFile.isFile()) { +- File packageSpecFile = resourceProvider.getFile(packageRoot); +- Packages packages = _readPackagespec(packageSpecFile); +- if (packages != null) { +- return new PackagesFileDisposition(packages); +- } +- } +- // The package root does not exist (or is not a folder). Since +- // [setRoots] ignores any package roots that don't exist (or aren't +- // folders), the only way we should be able to get here is due to a race +- // condition. In any case, the package root folder is gone, so we can't +- // resolve packages. +- return new NoPackageFolderDisposition(packageRoot: packageRoot); +- } else { +- PackageMapInfo packageMapInfo; +- callbacks.computingPackageMap(true); +- try { +- // Try .packages first. +- if (absolutePathContext.basename(packagespecFile.path) == +- PACKAGE_SPEC_NAME) { +- Packages packages = _readPackagespec(packagespecFile); +- return new PackagesFileDisposition(packages); +- } +- if (packageResolverProvider != null) { +- UriResolver resolver = packageResolverProvider(folder); +- if (resolver != null) { +- return new CustomPackageResolverDisposition(resolver); +- } +- } +- +- packageMapInfo = _packageMapProvider.computePackageMap(folder); +- } finally { +- callbacks.computingPackageMap(false); +- } +- for (String dependencyPath in packageMapInfo.dependencies) { +- addDependency(dependencyPath); +- } +- if (packageMapInfo.packageMap == null) { +- return new NoPackageFolderDisposition(); +- } +- return new PackageMapDisposition(packageMapInfo.packageMap); +- } +- } +- +- /** +- * Compute line information for the given [content]. +- */ +- LineInfo _computeLineInfo(String content) { +- List lineStarts = StringUtilities.computeLineStarts(content); +- return new LineInfo(lineStarts); +- } +- +- /** +- * Create an object that can be used to find and read the analysis options +- * file for code being analyzed using the given [packages]. +- */ +- AnalysisOptionsProvider _createAnalysisOptionsProvider(Packages packages) { +- Map> packageMap = +- new ContextBuilder(resourceProvider, null, null) +- .convertPackagesToMap(packages); +- List resolvers = [ +- new ResourceUriResolver(resourceProvider), +- new PackageMapUriResolver(resourceProvider, packageMap), +- ]; +- SourceFactory sourceFactory = +- new SourceFactory(resolvers, packages, resourceProvider); +- return new AnalysisOptionsProvider(sourceFactory); +- } +- +- /** +- * Create a new empty context associated with [folder], having parent +- * [parent] and using [packagesFile] to resolve package URI's. +- */ +- ContextInfo _createContext(ContextInfo parent, Folder folder, +- List excludedPaths, File packagesFile) { +- List dependencies = []; +- FolderDisposition disposition = +- _computeFolderDisposition(folder, dependencies.add, packagesFile); +- ContextInfo info = new ContextInfo(this, parent, folder, packagesFile, +- normalizedPackageRoots[folder.path], disposition); +- +- File optionsFile = null; +- Map optionMap = null; +- try { +- AnalysisOptionsProvider provider = +- _createAnalysisOptionsProvider(disposition.packages); +- optionsFile = provider.getOptionsFile(info.folder, crawlUp: true); +- if (optionsFile != null) { +- optionMap = provider.getOptionsFromFile(optionsFile); +- } +- } catch (_) { +- // Parse errors are reported elsewhere. +- } +- AnalysisOptions options = +- new AnalysisOptionsImpl.from(defaultContextOptions); +- applyToAnalysisOptions(options, optionMap); +- +- info.setDependencies(dependencies); +- String includedPath = folder.path; +- List containedExcludedPaths = excludedPaths +- .where((String excludedPath) => +- pathContext.isWithin(includedPath, excludedPath)) +- .toList(); +- processOptionsForDriver(info, options, optionMap); +- ContextRoot contextRoot = +- new ContextRoot(folder.path, containedExcludedPaths); +- if (optionsFile != null) { +- contextRoot.optionsFilePath = optionsFile.path; +- } +- info.analysisDriver = +- callbacks.addAnalysisDriver(folder, contextRoot, options); +- if (optionsFile != null) { +- _analyzeAnalysisOptionsFile(info.analysisDriver, optionsFile.path); +- } +- return info; +- } +- +- /** +- * Potentially create a new context associated with the given [folder]. +- * +- * If there are subfolders with 'pubspec.yaml' files, separate contexts are +- * created for them and excluded from the context associated with the +- * [folder]. +- * +- * If [withPackageSpecOnly] is `true`, a context will be created only if there +- * is a 'pubspec.yaml' or '.packages' file in the [folder]. +- * +- * [parent] should be the parent of any contexts that are created. +- */ +- void _createContexts(ContextInfo parent, Folder folder, +- List excludedPaths, bool withPackageSpecOnly) { +- if (_isExcluded(folder.path) || +- folder.shortName.startsWith('.') || +- folder.shortName == 'packages') { +- return; +- } +- // Decide whether a context needs to be created for [folder] here, and if +- // so, create it. +- File packageSpec = _findPackageSpecFile(folder); +- bool createContext = packageSpec.exists || !withPackageSpecOnly; +- if (withPackageSpecOnly && +- packageSpec.exists && +- parent != null && +- parent.ignored(packageSpec.path)) { +- // Don't create a context if the package spec is required and ignored. +- createContext = false; +- } +- if (createContext) { +- parent = _createContext(parent, folder, excludedPaths, packageSpec); +- } +- +- // Try to find subfolders with pubspecs or .packages files. +- try { +- for (Resource child in folder.getChildren()) { +- if (child is Folder) { +- if (!parent.ignored(child.path)) { +- _createContexts(parent, child, excludedPaths, true); +- } +- } +- } +- } on FileSystemException { +- // The directory either doesn't exist or cannot be read. Either way, there +- // are no subfolders that need to be added. +- } +- +- if (createContext) { +- // Now that the child contexts have been created, add the sources that +- // don't belong to the children. +- ChangeSet changeSet = new ChangeSet(); +- _addSourceFiles(changeSet, folder, parent); +- callbacks.applyChangesToContext(folder, changeSet); +- } +- } +- +- /** +- * Set up a [SourceFactory] that resolves packages as appropriate for the +- * given [folder]. +- */ +- SourceFactory _createSourceFactory(AnalysisOptions options, Folder folder) { +- ContextBuilder builder = callbacks.createContextBuilder(folder, options); +- return builder.createSourceFactory(folder.path, options); +- } +- +- /** +- * Clean up and destroy the context associated with the given folder. +- */ +- void _destroyContext(ContextInfo info) { +- changeSubscriptions.remove(info.folder)?.cancel(); +- callbacks.removeContext(info.folder, _computeFlushedFiles(info)); +- bool wasRemoved = info.parent.children.remove(info); +- assert(wasRemoved); +- } +- +- /** +- * Extract a new [packagespecFile]-based context from [oldInfo]. +- */ +- void _extractContext(ContextInfo oldInfo, File packagespecFile) { +- Folder newFolder = packagespecFile.parent; +- ContextInfo newInfo = +- _createContext(oldInfo, newFolder, excludedPaths, packagespecFile); +- // prepare sources to extract +- Map extractedSources = new HashMap(); +- oldInfo.sources.forEach((path, source) { +- if (newFolder.contains(path)) { +- extractedSources[path] = source; +- } +- }); +- // update new context +- { +- ChangeSet changeSet = new ChangeSet(); +- extractedSources.forEach((path, source) { +- newInfo.sources[path] = source; +- changeSet.addedSource(source); +- }); +- callbacks.applyChangesToContext(newFolder, changeSet); +- } +- // update old context +- { +- ChangeSet changeSet = new ChangeSet(); +- extractedSources.forEach((path, source) { +- oldInfo.sources.remove(path); +- changeSet.removedSource(source); +- }); +- callbacks.applyChangesToContext(oldInfo.folder, changeSet); +- } +- // TODO(paulberry): every context that was previously a child of oldInfo is +- // is still a child of oldInfo. This is wrong--some of them ought to be +- // adopted by newInfo now. +- } +- +- /** +- * Find the file that should be used to determine whether a context needs to +- * be created here--this is either the ".packages" file or the "pubspec.yaml" +- * file. +- */ +- File _findPackageSpecFile(Folder folder) { +- // Decide whether a context needs to be created for [folder] here, and if +- // so, create it. +- File packageSpec; +- +- // Start by looking for .packages. +- packageSpec = folder.getChild(PACKAGE_SPEC_NAME); +- +- // Fall back to looking for a pubspec. +- if (packageSpec == null || !packageSpec.exists) { +- packageSpec = folder.getChild(PUBSPEC_NAME); +- } +- return packageSpec; +- } +- +- /// Get analysis options inherited from an `_embedder.yaml` (deprecated) +- /// and/or a package specified configuration. If more than one +- /// `_embedder.yaml` is associated with the given context, the embedder is +- /// skipped. +- /// +- /// Returns null if there are no embedded/configured options. +- Map _getEmbeddedOptions(ContextInfo info) { +- Map embeddedOptions = null; +- EmbedderYamlLocator locator = +- info.disposition.getEmbedderLocator(resourceProvider); +- Iterable maps = locator.embedderYamls.values; +- if (maps.length == 1) { +- embeddedOptions = maps.first; +- } +- return embeddedOptions; +- } +- +- /** +- * Return the [ContextInfo] for the "innermost" context whose associated +- * folder is or contains the given path. ("innermost" refers to the nesting +- * of contexts, so if there is a context for path /foo and a context for +- * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is +- * the context for /foo/bar.) +- * +- * If no context contains the given path, `null` is returned. +- */ +- ContextInfo _getInnermostContextInfoFor(String path) { +- ContextInfo info = rootInfo.findChildInfoFor(path); +- if (info == null) { +- return null; +- } +- while (true) { +- ContextInfo childInfo = info.findChildInfoFor(path); +- if (childInfo == null) { +- return info; +- } +- info = childInfo; +- } +- } +- +- /** +- * Return the parent for a new [ContextInfo] with the given [path] folder. +- */ +- ContextInfo _getParentForNewContext(String path) { +- ContextInfo parent = _getInnermostContextInfoFor(path); +- if (parent != null) { +- return parent; +- } +- return rootInfo; +- } +- +- void _handleWatchEvent(WatchEvent event) { +- callbacks.broadcastWatchEvent(event); +- _handleWatchEventImpl(event); +- callbacks.afterWatchEvent(event); +- } +- +- void _handleWatchEventImpl(WatchEvent event) { +- // Figure out which context this event applies to. +- // TODO(brianwilkerson) If a file is explicitly included in one context +- // but implicitly referenced in another context, we will only send a +- // changeSet to the context that explicitly includes the file (because +- // that's the only context that's watching the file). +- String path = event.path; +- ChangeType type = event.type; +- ContextInfo info = _getInnermostContextInfoFor(path); +- if (info == null) { +- // This event doesn't apply to any context. This could happen due to a +- // race condition (e.g. a context was removed while one of its events was +- // in the event loop). The event is inapplicable now, so just ignore it. +- return; +- } +- _instrumentationService.logWatchEvent( +- info.folder.path, path, type.toString()); +- // First handle changes that affect folderDisposition (since these need to +- // be processed regardless of whether they are part of an excluded/ignored +- // path). +- if (info.hasDependency(path)) { +- _recomputeFolderDisposition(info); +- } +- // maybe excluded globally +- if (_isExcluded(path) || +- _isContainedInDotFolder(info.folder.path, path) || +- _isInPackagesDir(info.folder.path, path) || +- _isInTopLevelDocDir(info.folder.path, path)) { +- return; +- } +- // maybe excluded from the context, so other context will handle it +- if (info.excludes(path)) { +- return; +- } +- if (info.ignored(path)) { +- return; +- } +- // handle the change +- switch (type) { +- case ChangeType.ADD: +- Resource resource = resourceProvider.getResource(path); +- +- String directoryPath = absolutePathContext.dirname(path); +- +- // Check to see if we need to create a new context. +- if (info.isTopLevel) { +- // Only create a new context if this is not the same directory +- // described by our info object. +- if (info.folder.path != directoryPath) { +- if (_isPubspec(path)) { +- // Check for a sibling .packages file. +- if (!resourceProvider +- .getFile(absolutePathContext.append( +- directoryPath, PACKAGE_SPEC_NAME)) +- .exists) { +- _extractContext(info, resource); +- return; +- } +- } +- if (_isPackagespec(path)) { +- // Check for a sibling pubspec.yaml file. +- if (!resourceProvider +- .getFile( +- absolutePathContext.append(directoryPath, PUBSPEC_NAME)) +- .exists) { +- _extractContext(info, resource); +- return; +- } +- } +- } +- } +- +- // If the file went away and was replaced by a folder before we +- // had a chance to process the event, resource might be a Folder. In +- // that case don't add it. +- if (resource is File) { +- File file = resource; +- if (_shouldFileBeAnalyzed(file)) { +- info.analysisDriver.addFile(path); +- } +- } +- break; +- case ChangeType.REMOVE: +- +- // If package spec info is removed, check to see if we can merge contexts. +- // Note that it's important to verify that there is NEITHER a .packages nor a +- // lingering pubspec.yaml before merging. +- if (!info.isTopLevel) { +- String directoryPath = absolutePathContext.dirname(path); +- +- // Only merge if this is the same directory described by our info object. +- if (info.folder.path == directoryPath) { +- if (_isPubspec(path)) { +- // Check for a sibling .packages file. +- if (!resourceProvider +- .getFile(absolutePathContext.append( +- directoryPath, PACKAGE_SPEC_NAME)) +- .exists) { +- _mergeContext(info); +- return; +- } +- } +- if (_isPackagespec(path)) { +- // Check for a sibling pubspec.yaml file. +- if (!resourceProvider +- .getFile( +- absolutePathContext.append(directoryPath, PUBSPEC_NAME)) +- .exists) { +- _mergeContext(info); +- return; +- } +- } +- } +- } +- +- callbacks.applyFileRemoved(info.analysisDriver, path); +- break; +- case ChangeType.MODIFY: +- for (AnalysisDriver driver in driverMap.values) { +- driver.changeFile(path); +- } +- break; +- } +- _checkForPackagespecUpdate(path, info, info.folder); +- _checkForAnalysisOptionsUpdate(path, info, type); +- } +- +- /** +- * Determine whether the given [path], when interpreted relative to the +- * context root [root], contains a folder whose name starts with '.'. +- */ +- bool _isContainedInDotFolder(String root, String path) { +- String pathDir = absolutePathContext.dirname(path); +- String suffixPath = absolutePathContext.suffix(root, pathDir); +- if (suffixPath == null) { +- return false; +- } +- for (String pathComponent in absolutePathContext.split(suffixPath)) { +- if (pathComponent.startsWith('.') && +- pathComponent != '.' && +- pathComponent != '..') { +- return true; +- } +- } +- return false; +- } +- +- /** +- * Returns `true` if the given [path] is excluded by [excludedPaths]. +- */ +- bool _isExcluded(String path) => _isExcludedBy(excludedPaths, path); +- +- /** +- * Returns `true` if the given [path] is excluded by [excludedPaths]. +- */ +- bool _isExcludedBy(List excludedPaths, String path) { +- return excludedPaths.any((excludedPath) { +- if (absolutePathContext.isWithin(excludedPath, path)) { +- return true; +- } +- return path == excludedPath; +- }); +- } +- +- /** +- * Determine whether the given [path], when interpreted relative to the +- * context root [root], contains a 'packages' folder. +- */ +- bool _isInPackagesDir(String root, String path) { +- String suffixPath = absolutePathContext.suffix(root, path); +- if (suffixPath == null) { +- return false; +- } +- List pathParts = absolutePathContext.split(suffixPath); +- return pathParts.contains(PACKAGES_NAME); +- } +- +- /** +- * Determine whether the given [path] is in the direct 'doc' folder of the +- * context root [root]. +- */ +- bool _isInTopLevelDocDir(String root, String path) { +- String suffixPath = absolutePathContext.suffix(root, path); +- if (suffixPath == null) { +- return false; +- } +- return suffixPath == DOC_DIR_NAME || +- suffixPath.startsWith(DOC_DIR_NAME + absolutePathContext.separator); +- } +- +- bool _isPackagespec(String path) => +- absolutePathContext.basename(path) == PACKAGE_SPEC_NAME; +- +- bool _isPubspec(String path) => +- absolutePathContext.basename(path) == PUBSPEC_NAME; +- +- /** +- * Merges [info] context into its parent. +- */ +- void _mergeContext(ContextInfo info) { +- // destroy the context +- _destroyContext(info); +- // add files to the parent context +- ContextInfo parentInfo = info.parent; +- if (parentInfo != null) { +- parentInfo.children.remove(info); +- ChangeSet changeSet = new ChangeSet(); +- info.sources.forEach((path, source) { +- parentInfo.sources[path] = source; +- changeSet.addedSource(source); +- }); +- callbacks.applyChangesToContext(parentInfo.folder, changeSet); +- } +- } +- +- Packages _readPackagespec(File specFile) { +- try { +- String contents = specFile.readAsStringSync(); +- Map map = +- pkgfile.parse(UTF8.encode(contents), new Uri.file(specFile.path)); +- return new MapPackages(map); +- } catch (_) { +- //TODO(pquitslund): consider creating an error for the spec file. +- return null; +- } +- } +- +- /** +- * Recompute the [FolderDisposition] for the context described by [info], +- * and update the client appropriately. +- */ +- void _recomputeFolderDisposition(ContextInfo info) { +- // TODO(paulberry): when computePackageMap is changed into an +- // asynchronous API call, we'll want to suspend analysis for this context +- // while we're rerunning "pub list", since any analysis we complete while +- // "pub list" is in progress is just going to get thrown away anyhow. +- List dependencies = []; +- info.setDependencies(dependencies); +- _updateContextPackageUriResolver(info.folder); +- } +- +- /** +- * Return `true` if the given [file] should be analyzed. +- */ +- bool _shouldFileBeAnalyzed(File file) { +- for (Glob glob in analyzedFilesGlobs) { +- if (glob.matches(file.path)) { +- // Emacs creates dummy links to track the fact that a file is open for +- // editing and has unsaved changes (e.g. having unsaved changes to +- // 'foo.dart' causes a link '.#foo.dart' to be created, which points to +- // the non-existent file 'username@hostname.pid'. To avoid these dummy +- // links causing the analyzer to thrash, just ignore links to +- // non-existent files. +- return file.exists; +- } +- } +- return false; +- } +- +- /** +- * If the given [object] is a map, and all of the keys in the map are strings, +- * return a map containing the same mappings. Otherwise, return `null`. +- */ +- Map _toStringMap(Object object) { +- if (object is Map) { +- Map stringMap = new HashMap(); +- for (var key in object.keys) { +- if (key is String) { +- stringMap[key] = object[key]; +- } else { +- return null; +- } +- } +- return stringMap; +- } +- return null; +- } +- +- void _updateContextPackageUriResolver(Folder contextFolder) { +- ContextInfo info = getContextInfoFor(contextFolder); +- AnalysisDriver driver = info.analysisDriver; +- SourceFactory sourceFactory = +- _createSourceFactory(driver.analysisOptions, contextFolder); +- driver.configure(sourceFactory: sourceFactory); +- } +- +- /** +- * Create and return a source representing the given [file] within the given +- * [driver]. +- */ +- static Source createSourceInContext(AnalysisDriver driver, File file) { +- // TODO(brianwilkerson) Optimize this, by allowing support for source +- // factories to restore URI's from a file path rather than a source. +- Source source = file.createSource(); +- if (driver == null) { +- return source; +- } +- Uri uri = driver.sourceFactory.restoreUri(source); +- return file.createSource(uri); +- } +-} +- +-/** +- * Concrete [FolderDisposition] object indicating that the context for a given +- * folder should resolve package URIs using a custom URI resolver. +- */ +-class CustomPackageResolverDisposition extends FolderDisposition { +- /** +- * The [UriResolver] that should be used to resolve package URIs. +- */ +- UriResolver resolver; +- +- CustomPackageResolverDisposition(this.resolver); +- +- @override +- String get packageRoot => null; +- +- @override +- Packages get packages => null; +- +- @override +- Iterable createPackageUriResolvers( +- ResourceProvider resourceProvider) => +- [resolver]; +- +- @override +- EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) => +- new EmbedderYamlLocator(null); +- +- @override +- SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) => +- new SdkExtensionFinder(null); +-} +- +-/** +- * An instance of the class [FolderDisposition] represents the information +- * gathered by the [ContextManagerImpl] to determine how to create an analysis +- * driver for a given folder. +- * +- * Note: [ContextManagerImpl] may use equality testing and hash codes to +- * determine when two folders should share the same context, so derived classes +- * may need to override operator== and hashCode() if object identity is +- * insufficient. +- * +- * TODO(paulberry): consider adding a flag to indicate that it is not necessary +- * to recurse into the given folder looking for additional contexts to create +- * or files to analyze (this could help avoid unnecessarily weighing down the +- * system with file watchers). +- */ +-abstract class FolderDisposition { +- /** +- * If this [FolderDisposition] was created based on a package root +- * folder, the absolute path to that folder. Otherwise `null`. +- */ +- String get packageRoot; +- +- /** +- * If contexts governed by this [FolderDisposition] should resolve packages +- * using the ".packages" file mechanism (DEP 5), retrieve the [Packages] +- * object that resulted from parsing the ".packages" file. +- */ +- Packages get packages; +- +- /** +- * Create all the [UriResolver]s which should be used to resolve packages in +- * contexts governed by this [FolderDisposition]. +- * +- * [resourceProvider] is provided since it is needed to construct most +- * [UriResolver]s. +- */ +- Iterable createPackageUriResolvers( +- ResourceProvider resourceProvider); +- +- /** +- * Return the locator used to locate the _embedder.yaml file used to configure +- * the SDK. The [resourceProvider] is used to access the file system in cases +- * where that is necessary. +- */ +- EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider); +- +- /** +- * Return the extension finder used to locate the `_sdkext` file used to add +- * extensions to the SDK. The [resourceProvider] is used to access the file +- * system in cases where that is necessary. +- */ +- SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider); +-} +- +-/** +- * Concrete [FolderDisposition] object indicating that the context for a given +- * folder should not resolve "package:" URIs at all. +- */ +-class NoPackageFolderDisposition extends FolderDisposition { +- @override +- final String packageRoot; +- +- NoPackageFolderDisposition({this.packageRoot}); +- +- @override +- Packages get packages => null; +- +- @override +- Iterable createPackageUriResolvers( +- ResourceProvider resourceProvider) => +- const []; +- +- @override +- EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) => +- new EmbedderYamlLocator(null); +- +- @override +- SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) => +- new SdkExtensionFinder(null); +-} +- +-/** +- * Concrete [FolderDisposition] object indicating that the context for a given +- * folder should resolve packages using a package map. +- */ +-class PackageMapDisposition extends FolderDisposition { +- final Map> packageMap; +- +- EmbedderYamlLocator _embedderLocator; +- SdkExtensionFinder _sdkExtensionFinder; +- +- @override +- final String packageRoot; +- +- PackageMapDisposition(this.packageMap, {this.packageRoot}); +- +- @override +- Packages get packages => null; +- +- @override +- Iterable createPackageUriResolvers( +- ResourceProvider resourceProvider) => +- [ +- new SdkExtUriResolver(packageMap), +- new PackageMapUriResolver(resourceProvider, packageMap) +- ]; +- +- @override +- EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) { +- if (_embedderLocator == null) { +- _embedderLocator = new EmbedderYamlLocator(packageMap); +- } +- return _embedderLocator; +- } +- +- @override +- SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) { +- return _sdkExtensionFinder ??= new SdkExtensionFinder(packageMap); +- } +-} +- +-/** +- * Concrete [FolderDisposition] object indicating that the context for a given +- * folder should resolve packages using a ".packages" file. +- */ +-class PackagesFileDisposition extends FolderDisposition { +- @override +- final Packages packages; +- +- Map> packageMap; +- +- EmbedderYamlLocator _embedderLocator; +- SdkExtensionFinder _sdkExtensionFinder; +- +- PackagesFileDisposition(this.packages); +- +- @override +- String get packageRoot => null; +- +- Map> buildPackageMap(ResourceProvider resourceProvider) { +- if (packageMap == null) { +- packageMap = >{}; +- if (packages != null) { +- packages.asMap().forEach((String name, Uri uri) { +- if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) { +- var path = resourceProvider.pathContext.fromUri(uri); +- packageMap[name] = [resourceProvider.getFolder(path)]; +- } +- }); +- } +- } +- return packageMap; +- } +- +- @override +- Iterable createPackageUriResolvers( +- ResourceProvider resourceProvider) { +- if (packages != null) { +- // Construct package map for the SdkExtUriResolver. +- Map> packageMap = buildPackageMap(resourceProvider); +- return [new SdkExtUriResolver(packageMap)]; +- } else { +- return const []; +- } +- } +- +- @override +- EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) { +- if (_embedderLocator == null) { +- _embedderLocator = +- new EmbedderYamlLocator(buildPackageMap(resourceProvider)); +- } +- return _embedderLocator; +- } +- +- @override +- SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) { +- return _sdkExtensionFinder ??= +- new SdkExtensionFinder(buildPackageMap(resourceProvider)); +- } +-} +diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/domain_abstract.dart +deleted file mode 100644 +index 65a2dd41902..00000000000 +--- a/pkg/analysis_server/lib/src/domain_abstract.dart ++++ /dev/null +@@ -1,78 +0,0 @@ +-// 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:convert'; +-import 'dart:math' as math; +- +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin; +- +-/** +- * An abstract implementation of a request handler. +- */ +-abstract class AbstractRequestHandler implements RequestHandler { +- /** +- * The analysis server that is using this handler to process requests. +- */ +- final AnalysisServer server; +- +- /** +- * Initialize a newly created request handler to be associated with the given +- * analysis [server]. +- */ +- AbstractRequestHandler(this.server); +- +- /** +- * Given a mapping from plugins to futures that will complete when the plugin +- * has responded to a request, wait for a finite amount of time for each of +- * the plugins to respond. Return a list of the responses from each of the +- * plugins. If a plugin fails to return a response, notify the plugin manager +- * associated with the server so that non-responsive plugins can be killed or +- * restarted. The [timeout] is the maximum amount of time that will be spent +- * waiting for plugins to respond. +- */ +- Future> waitForResponses( +- Map> futures, +- {plugin.RequestParams requestParameters, +- int timeout: 500}) async { +- // TODO(brianwilkerson) requestParameters might need to be required. +- int endTime = new DateTime.now().millisecondsSinceEpoch + timeout; +- List responses = []; +- for (PluginInfo pluginInfo in futures.keys) { +- Future future = futures[pluginInfo]; +- try { +- int startTime = new DateTime.now().millisecondsSinceEpoch; +- plugin.Response response = await future.timeout( +- new Duration(milliseconds: math.max(endTime - startTime, 0))); +- if (response.error != null) { +- // TODO(brianwilkerson) Report the error to the plugin manager. +- server.instrumentationService.logPluginError( +- pluginInfo.data, +- response.error.code.name, +- response.error.message, +- response.error.stackTrace); +- } else { +- responses.add(response); +- } +- } on TimeoutException { +- // TODO(brianwilkerson) Report the timeout to the plugin manager. +- server.instrumentationService.logPluginTimeout( +- pluginInfo.data, +- new JsonEncoder() +- .convert(requestParameters?.toRequest('-')?.toJson() ?? {})); +- } catch (exception, stackTrace) { +- // TODO(brianwilkerson) Report the exception to the plugin manager. +- server.instrumentationService +- .logPluginException(pluginInfo.data, exception, stackTrace); +- } +- } +- return responses; +- } +-} +diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart +deleted file mode 100644 +index dc826cc4bc1..00000000000 +--- a/pkg/analysis_server/lib/src/domain_analysis.dart ++++ /dev/null +@@ -1,432 +0,0 @@ +-// Copyright (c) 2014, 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:core'; +- +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/computer/computer_hover.dart'; +-import 'package:analysis_server/src/computer/imported_elements_computer.dart'; +-import 'package:analysis_server/src/domain_abstract.dart'; +-import 'package:analysis_server/src/domains/analysis/navigation_dart.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/plugin/request_converter.dart'; +-import 'package:analysis_server/src/plugin/result_merger.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart'; +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/engine.dart' as engine; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart'; +- +-/** +- * Instances of the class [AnalysisDomainHandler] implement a [RequestHandler] +- * that handles requests in the `analysis` domain. +- */ +-class AnalysisDomainHandler extends AbstractRequestHandler { +- /** +- * Initialize a newly created handler to handle requests for the given [server]. +- */ +- AnalysisDomainHandler(AnalysisServer server) : super(server); +- +- /** +- * Implement the `analysis.getErrors` request. +- */ +- Future getErrors(Request request) async { +- String file = new AnalysisGetErrorsParams.fromRequest(request).file; +- +- void send(engine.AnalysisOptions analysisOptions, LineInfo lineInfo, +- List errors) { +- if (lineInfo == null) { +- server.sendResponse(new Response.getErrorsInvalidFile(request)); +- } else { +- List protocolErrors = +- doAnalysisError_listFromEngine(analysisOptions, lineInfo, errors); +- server.sendResponse( +- new AnalysisGetErrorsResult(protocolErrors).toResponse(request.id)); +- } +- } +- +- AnalysisResult result = await server.getAnalysisResult(file); +- +- if (server.onResultErrorSupplementor != null) { +- if (result != null) { +- await server.onResultErrorSupplementor(file, result.errors); +- } else { +- server.onNoAnalysisResult(file, send); +- return; +- } +- } +- +- send(result?.driver?.analysisOptions, result?.lineInfo, result?.errors); +- } +- +- /** +- * Implement the `analysis.getHover` request. +- */ +- Future getHover(Request request) async { +- var params = new AnalysisGetHoverParams.fromRequest(request); +- +- // Prepare the resolved units. +- AnalysisResult result = await server.getAnalysisResult(params.file); +- CompilationUnit unit = result?.unit; +- +- // Prepare the hovers. +- List hovers = []; +- if (unit != null) { +- HoverInformation hoverInformation = +- new DartUnitHoverComputer(unit, params.offset).compute(); +- if (hoverInformation != null) { +- hovers.add(hoverInformation); +- } +- } +- +- // Send the response. +- server.sendResponse( +- new AnalysisGetHoverResult(hovers).toResponse(request.id)); +- } +- +- /** +- * Implement the `analysis.getImportedElements` request. +- */ +- Future getImportedElements(Request request) async { +- AnalysisGetImportedElementsParams params = +- new AnalysisGetImportedElementsParams.fromRequest(request); +- // +- // Prepare the resolved unit. +- // +- AnalysisResult result = await server.getAnalysisResult(params.file); +- if (result == null) { +- server.sendResponse(new Response.getImportedElementsInvalidFile(request)); +- } +- // +- // Compute the list of imported elements. +- // +- List elements = +- new ImportedElementsComputer(result.unit, params.offset, params.length) +- .compute(); +- // +- // Send the response. +- // +- server.sendResponse( +- new AnalysisGetImportedElementsResult(elements).toResponse(request.id)); +- } +- +- /** +- * Implement the `analysis.getLibraryDependencies` request. +- */ +- Response getLibraryDependencies(Request request) { +- return new Response.unsupportedFeature(request.id, +- 'Please contact the Dart analyzer team if you need this request.'); +-// server.onAnalysisComplete.then((_) { +-// LibraryDependencyCollector collector = +-// new LibraryDependencyCollector(server.analysisContexts); +-// Set libraries = collector.collectLibraryDependencies(); +-// Map>> packageMap = +-// collector.calculatePackageMap(server.folderMap); +-// server.sendResponse(new AnalysisGetLibraryDependenciesResult( +-// libraries.toList(growable: false), packageMap) +-// .toResponse(request.id)); +-// }).catchError((error, st) { +-// server.sendResponse(new Response.serverError(request, error, st)); +-// }); +-// // delay response +-// return Response.DELAYED_RESPONSE; +- } +- +- /** +- * Implement the `analysis.getNavigation` request. +- */ +- Future getNavigation(Request request) async { +- var params = new AnalysisGetNavigationParams.fromRequest(request); +- String file = params.file; +- int offset = params.offset; +- int length = params.length; +- +- AnalysisDriver driver = server.getAnalysisDriver(file); +- if (driver == null) { +- server.sendResponse(new Response.getNavigationInvalidFile(request)); +- } else { +- // +- // Allow plugins to start computing navigation data. +- // +- plugin.AnalysisGetNavigationParams requestParams = +- new plugin.AnalysisGetNavigationParams(file, offset, length); +- Map> pluginFutures = server +- .pluginManager +- .broadcastRequest(requestParams, contextRoot: driver.contextRoot); +- // +- // Compute navigation data generated by server. +- // +- List allResults = []; +- AnalysisResult result = await server.getAnalysisResult(file); +- CompilationUnit unit = result?.unit; +- if (unit != null && result.exists) { +- NavigationCollectorImpl collector = new NavigationCollectorImpl(); +- computeDartNavigation(collector, unit, offset, length); +- collector.createRegions(); +- allResults.add(new AnalysisNavigationParams( +- file, collector.regions, collector.targets, collector.files)); +- } +- // +- // Add the navigation data produced by plugins to the server-generated +- // navigation data. +- // +- if (pluginFutures != null) { +- List responses = await waitForResponses(pluginFutures, +- requestParameters: requestParams); +- for (plugin.Response response in responses) { +- plugin.AnalysisGetNavigationResult result = +- new plugin.AnalysisGetNavigationResult.fromResponse(response); +- allResults.add(new AnalysisNavigationParams( +- file, result.regions, result.targets, result.files)); +- } +- } +- // +- // Return the result. +- // +- ResultMerger merger = new ResultMerger(); +- AnalysisNavigationParams mergedResults = +- merger.mergeNavigation(allResults); +- if (mergedResults == null) { +- server.sendResponse(new AnalysisGetNavigationResult( +- [], [], []) +- .toResponse(request.id)); +- } else { +- server.sendResponse(new AnalysisGetNavigationResult(mergedResults.files, +- mergedResults.targets, mergedResults.regions) +- .toResponse(request.id)); +- } +- } +- } +- +- /** +- * Implement the `analysis.getReachableSources` request. +- */ +- Response getReachableSources(Request request) { +- return new Response.unsupportedFeature(request.id, +- 'Please contact the Dart analyzer team if you need this request.'); +-// AnalysisGetReachableSourcesParams params = +-// new AnalysisGetReachableSourcesParams.fromRequest(request); +-// ContextSourcePair pair = server.getContextSourcePair(params.file); +-// if (pair.context == null || pair.source == null) { +-// return new Response.getReachableSourcesInvalidFile(request); +-// } +-// Map> sources = +-// new ReachableSourceCollector(pair.source, pair.context) +-// .collectSources(); +-// return new AnalysisGetReachableSourcesResult(sources) +-// .toResponse(request.id); +- } +- +- @override +- Response handleRequest(Request request) { +- try { +- String requestName = request.method; +- if (requestName == ANALYSIS_REQUEST_GET_ERRORS) { +- getErrors(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == ANALYSIS_REQUEST_GET_HOVER) { +- getHover(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == ANALYSIS_REQUEST_GET_IMPORTED_ELEMENTS) { +- getImportedElements(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == ANALYSIS_REQUEST_GET_LIBRARY_DEPENDENCIES) { +- return getLibraryDependencies(request); +- } else if (requestName == ANALYSIS_REQUEST_GET_NAVIGATION) { +- getNavigation(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == ANALYSIS_REQUEST_GET_REACHABLE_SOURCES) { +- return getReachableSources(request); +- } else if (requestName == ANALYSIS_REQUEST_REANALYZE) { +- return reanalyze(request); +- } else if (requestName == ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS) { +- return setAnalysisRoots(request); +- } else if (requestName == ANALYSIS_REQUEST_SET_GENERAL_SUBSCRIPTIONS) { +- return setGeneralSubscriptions(request); +- } else if (requestName == ANALYSIS_REQUEST_SET_PRIORITY_FILES) { +- return setPriorityFiles(request); +- } else if (requestName == ANALYSIS_REQUEST_SET_SUBSCRIPTIONS) { +- return setSubscriptions(request); +- } else if (requestName == ANALYSIS_REQUEST_UPDATE_CONTENT) { +- return updateContent(request); +- } else if (requestName == ANALYSIS_REQUEST_UPDATE_OPTIONS) { +- return updateOptions(request); +- } +- } on RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +- +- /** +- * Implement the 'analysis.reanalyze' request. +- */ +- Response reanalyze(Request request) { +- server.options.analytics?.sendEvent('analysis', 'reanalyze'); +- +- AnalysisReanalyzeParams params = +- new AnalysisReanalyzeParams.fromRequest(request); +- List roots = params.roots; +- if (roots == null || roots.isNotEmpty) { +- List includedPaths = server.contextManager.includedPaths; +- List rootResources = null; +- if (roots != null) { +- rootResources = []; +- for (String rootPath in roots) { +- if (!includedPaths.contains(rootPath)) { +- return new Response.invalidAnalysisRoot(request, rootPath); +- } +- rootResources.add(server.resourceProvider.getResource(rootPath)); +- } +- } +- server.reanalyze(rootResources); +- } +- // +- // Restart all of the plugins. This is an async operation that will happen +- // in the background. +- // +- server.pluginManager.restartPlugins(); +- // +- // Send the response. +- // +- return new AnalysisReanalyzeResult().toResponse(request.id); +- } +- +- /** +- * Implement the 'analysis.setAnalysisRoots' request. +- */ +- Response setAnalysisRoots(Request request) { +- var params = new AnalysisSetAnalysisRootsParams.fromRequest(request); +- List includedPathList = params.included; +- List excludedPathList = params.excluded; +- +- server.options.analytics?.sendEvent('analysis', 'setAnalysisRoots', +- value: includedPathList.length); +- +- // validate +- for (String path in includedPathList) { +- if (!server.isValidFilePath(path)) { +- return new Response.invalidFilePathFormat(request, path); +- } +- } +- for (String path in excludedPathList) { +- if (!server.isValidFilePath(path)) { +- return new Response.invalidFilePathFormat(request, path); +- } +- } +- // continue in server +- server.setAnalysisRoots(request.id, includedPathList, excludedPathList, +- params.packageRoots ?? {}); +- return new AnalysisSetAnalysisRootsResult().toResponse(request.id); +- } +- +- /** +- * Implement the 'analysis.setGeneralSubscriptions' request. +- */ +- Response setGeneralSubscriptions(Request request) { +- AnalysisSetGeneralSubscriptionsParams params = +- new AnalysisSetGeneralSubscriptionsParams.fromRequest(request); +- server.setGeneralAnalysisSubscriptions(params.subscriptions); +- return new AnalysisSetGeneralSubscriptionsResult().toResponse(request.id); +- } +- +- /** +- * Implement the 'analysis.setPriorityFiles' request. +- */ +- Response setPriorityFiles(Request request) { +- var params = new AnalysisSetPriorityFilesParams.fromRequest(request); +- server.setPriorityFiles(request.id, params.files); +- // +- // Forward the request to the plugins. +- // +- RequestConverter converter = new RequestConverter(); +- server.pluginManager.setAnalysisSetPriorityFilesParams( +- converter.convertAnalysisSetPriorityFilesParams(params)); +- // +- // Send the response. +- // +- return new AnalysisSetPriorityFilesResult().toResponse(request.id); +- } +- +- /** +- * Implement the 'analysis.setSubscriptions' request. +- */ +- Response setSubscriptions(Request request) { +- var params = new AnalysisSetSubscriptionsParams.fromRequest(request); +- // parse subscriptions +- Map> subMap = mapMap(params.subscriptions, +- valueCallback: (List subscriptions) => subscriptions.toSet()); +- server.setAnalysisSubscriptions(subMap); +- // +- // Forward the request to the plugins. +- // +- RequestConverter converter = new RequestConverter(); +- server.pluginManager.setAnalysisSetSubscriptionsParams( +- converter.convertAnalysisSetSubscriptionsParams(params)); +- // +- // Send the response. +- // +- return new AnalysisSetSubscriptionsResult().toResponse(request.id); +- } +- +- /** +- * Implement the 'analysis.updateContent' request. +- */ +- Response updateContent(Request request) { +- var params = new AnalysisUpdateContentParams.fromRequest(request); +- server.updateContent(request.id, params.files); +- // +- // Forward the request to the plugins. +- // +- RequestConverter converter = new RequestConverter(); +- server.pluginManager.setAnalysisUpdateContentParams( +- converter.convertAnalysisUpdateContentParams(params)); +- // +- // Send the response. +- // +- return new AnalysisUpdateContentResult().toResponse(request.id); +- } +- +- /** +- * Implement the 'analysis.updateOptions' request. +- */ +- Response updateOptions(Request request) { +- // options +- var params = new AnalysisUpdateOptionsParams.fromRequest(request); +- AnalysisOptions newOptions = params.options; +- List updaters = new List(); +- if (newOptions.generateDart2jsHints != null) { +- updaters.add((engine.AnalysisOptionsImpl options) { +- options.dart2jsHint = newOptions.generateDart2jsHints; +- }); +- } +- if (newOptions.generateHints != null) { +- updaters.add((engine.AnalysisOptionsImpl options) { +- options.hint = newOptions.generateHints; +- }); +- } +- if (newOptions.generateLints != null) { +- updaters.add((engine.AnalysisOptionsImpl options) { +- options.lint = newOptions.generateLints; +- }); +- } +- if (newOptions.enableSuperMixins != null) { +- updaters.add((engine.AnalysisOptionsImpl options) { +- options.enableSuperMixins = newOptions.enableSuperMixins; +- }); +- } +- server.updateOptions(updaters); +- return new AnalysisUpdateOptionsResult().toResponse(request.id); +- } +-} +diff --git a/pkg/analysis_server/lib/src/domain_analytics.dart b/pkg/analysis_server/lib/src/domain_analytics.dart +deleted file mode 100644 +index f6ad37e675a..00000000000 +--- a/pkg/analysis_server/lib/src/domain_analytics.dart ++++ /dev/null +@@ -1,60 +0,0 @@ +-// 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:core'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +- +-/// Instances of the class [AnalyticsDomainHandler] implement a [RequestHandler] +-/// that handles requests in the `analytics` domain. +-class AnalyticsDomainHandler implements RequestHandler { +- final AnalysisServer server; +- +- bool enabled = false; +- +- AnalyticsDomainHandler(this.server); +- +- // TODO(devoncarew): This implementation is currently mocked out. +- Response handleEnable(Request request) { +- // TODO(devoncarew): Implement. +- AnalyticsEnableParams params = +- new AnalyticsEnableParams.fromRequest(request); +- enabled = params.value; +- return new AnalyticsEnableResult().toResponse(request.id); +- } +- +- Response handleIsEnabled(Request request) { +- // TODO(devoncarew): Implement. +- return new AnalyticsIsEnabledResult(enabled).toResponse(request.id); +- } +- +- @override +- Response handleRequest(Request request) { +- String requestName = request.method; +- if (requestName == ANALYTICS_REQUEST_IS_ENABLED) { +- return handleIsEnabled(request); +- } else if (requestName == ANALYTICS_REQUEST_ENABLE) { +- return handleEnable(request); +- } else if (requestName == ANALYTICS_REQUEST_SEND_EVENT) { +- return handleSendEvent(request); +- } else if (requestName == ANALYTICS_REQUEST_SEND_TIMING) { +- return handleSendTiming(request); +- } +- +- return null; +- } +- +- Response handleSendEvent(Request request) { +- // TODO(devoncarew): Implement. +- return new AnalyticsSendEventResult().toResponse(request.id); +- } +- +- Response handleSendTiming(Request request) { +- // TODO(devoncarew): Implement. +- return new AnalyticsSendTimingResult().toResponse(request.id); +- } +-} +diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart +deleted file mode 100644 +index 5e9f2a64b81..00000000000 +--- a/pkg/analysis_server/lib/src/domain_completion.dart ++++ /dev/null +@@ -1,298 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/collections.dart'; +-import 'package:analysis_server/src/domain_abstract.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/provisional/completion/completion_core.dart'; +-import 'package:analysis_server/src/services/completion/completion_core.dart'; +-import 'package:analysis_server/src/services/completion/completion_performance.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +- +-/** +- * Instances of the class [CompletionDomainHandler] implement a [RequestHandler] +- * that handles requests in the completion domain. +- */ +-class CompletionDomainHandler extends AbstractRequestHandler { +- /** +- * The maximum number of performance measurements to keep. +- */ +- static const int performanceListMaxLength = 50; +- +- /** +- * The next completion response id. +- */ +- int _nextCompletionId = 0; +- +- /** +- * Code completion performance for the last completion operation. +- */ +- CompletionPerformance performance; +- +- /** +- * A list of code completion performance measurements for the latest +- * completion operation up to [performanceListMaxLength] measurements. +- */ +- final RecentBuffer performanceList = +- new RecentBuffer(performanceListMaxLength); +- +- /** +- * Performance for the last priority change event. +- */ +- CompletionPerformance computeCachePerformance; +- +- /** +- * The current request being processed or `null` if none. +- */ +- CompletionRequestImpl _currentRequest; +- +- /** +- * Initialize a new request handler for the given [server]. +- */ +- CompletionDomainHandler(AnalysisServer server) : super(server); +- +- /** +- * Compute completion results for the given request and append them to the stream. +- * Clients should not call this method directly as it is automatically called +- * when a client listens to the stream returned by [results]. +- * Subclasses should override this method, append at least one result +- * to the [controller], and close the controller stream once complete. +- */ +- Future computeSuggestions(CompletionRequestImpl request, +- CompletionGetSuggestionsParams params) async { +- // +- // Allow plugins to start computing fixes. +- // +- Map> pluginFutures; +- plugin.CompletionGetSuggestionsParams requestParams; +- String file = params.file; +- int offset = params.offset; +- AnalysisDriver driver = server.getAnalysisDriver(file); +- if (driver != null) { +- requestParams = new plugin.CompletionGetSuggestionsParams(file, offset); +- pluginFutures = server.pluginManager +- .broadcastRequest(requestParams, contextRoot: driver.contextRoot); +- } +- // +- // Compute completions generated by server. +- // +- List suggestions = []; +- if (request.result != null) { +- const COMPUTE_SUGGESTIONS_TAG = 'computeSuggestions'; +- performance.logStartTime(COMPUTE_SUGGESTIONS_TAG); +- +- CompletionContributor contributor = new DartCompletionManager(); +- String contributorTag = 'computeSuggestions - ${contributor +- .runtimeType}'; +- performance.logStartTime(contributorTag); +- try { +- suggestions.addAll(await contributor.computeSuggestions(request)); +- } on AbortCompletion { +- suggestions.clear(); +- } +- performance.logElapseTime(contributorTag); +- performance.logElapseTime(COMPUTE_SUGGESTIONS_TAG); +- } +- // TODO (danrubel) if request is obsolete (processAnalysisRequest returns +- // false) then send empty results +- +- // +- // Add the fixes produced by plugins to the server-generated fixes. +- // +- if (pluginFutures != null) { +- List responses = await waitForResponses(pluginFutures, +- requestParameters: requestParams); +- for (plugin.Response response in responses) { +- plugin.CompletionGetSuggestionsResult result = +- new plugin.CompletionGetSuggestionsResult.fromResponse(response); +- if (result.results != null && result.results.isNotEmpty) { +- if (suggestions.isEmpty) { +- request.replacementOffset = result.replacementOffset; +- request.replacementLength = result.replacementLength; +- } else if (request.replacementOffset != result.replacementOffset && +- request.replacementLength != result.replacementLength) { +- server.instrumentationService +- .logError('Plugin completion-results dropped due to conflicting' +- ' replacement offset/length: ${result.toJson()}'); +- continue; +- } +- suggestions.addAll(result.results); +- } +- } +- } +- // +- // Return the result. +- // +- return new CompletionResult( +- request.replacementOffset, request.replacementLength, suggestions); +- } +- +- @override +- Response handleRequest(Request request) { +- return runZoned(() { +- String requestName = request.method; +- if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) { +- processRequest(request); +- return Response.DELAYED_RESPONSE; +- } +- return null; +- }, onError: (exception, stackTrace) { +- server.sendServerErrorNotification( +- 'Failed to handle completion domain request: ${request.toJson()}', +- exception, +- stackTrace); +- }); +- } +- +- void ifMatchesRequestClear(CompletionRequest completionRequest) { +- if (_currentRequest == completionRequest) { +- _currentRequest = null; +- } +- } +- +- /** +- * Process a `completion.getSuggestions` request. +- */ +- Future processRequest(Request request) async { +- performance = new CompletionPerformance(); +- +- // extract and validate params +- CompletionGetSuggestionsParams params = +- new CompletionGetSuggestionsParams.fromRequest(request); +- String filePath = params.file; +- int offset = params.offset; +- +- AnalysisResult result = await server.getAnalysisResult(filePath); +- Source source; +- +- if (result == null || !result.exists) { +- if (server.onNoAnalysisCompletion != null) { +- String completionId = (_nextCompletionId++).toString(); +- await server.onNoAnalysisCompletion( +- request, this, params, performance, completionId); +- return; +- } +- source = server.resourceProvider.getFile(filePath).createSource(); +- } else { +- if (offset < 0 || offset > result.content.length) { +- server.sendResponse(new Response.invalidParameter( +- request, +- 'params.offset', +- 'Expected offset between 0 and source length inclusive,' +- ' but found $offset')); +- return; +- } +- source = +- server.resourceProvider.getFile(result.path).createSource(result.uri); +- +- recordRequest(performance, source, result.content, offset); +- } +- CompletionRequestImpl completionRequest = new CompletionRequestImpl( +- result, server.resourceProvider, source, offset, performance); +- +- String completionId = (_nextCompletionId++).toString(); +- +- setNewRequest(completionRequest); +- +- // initial response without results +- server.sendResponse(new CompletionGetSuggestionsResult(completionId) +- .toResponse(request.id)); +- +- // Compute suggestions in the background +- computeSuggestions(completionRequest, params) +- .then((CompletionResult result) { +- const SEND_NOTIFICATION_TAG = 'send notification'; +- performance.logStartTime(SEND_NOTIFICATION_TAG); +- sendCompletionNotification(completionId, result.replacementOffset, +- result.replacementLength, result.suggestions); +- performance.logElapseTime(SEND_NOTIFICATION_TAG); +- performance.notificationCount = 1; +- performance.logFirstNotificationComplete('notification 1 complete'); +- performance.suggestionCountFirst = result.suggestions.length; +- performance.suggestionCountLast = result.suggestions.length; +- performance.complete(); +- }).whenComplete(() { +- ifMatchesRequestClear(completionRequest); +- }); +- } +- +- /** +- * If tracking code completion performance over time, then +- * record addition information about the request in the performance record. +- */ +- void recordRequest(CompletionPerformance performance, Source source, +- String content, int offset) { +- performance.source = source; +- if (performanceListMaxLength == 0 || source == null) { +- return; +- } +- performance.setContentsAndOffset(content, offset); +- performanceList.add(performance); +- } +- +- /** +- * Send completion notification results. +- */ +- void sendCompletionNotification(String completionId, int replacementOffset, +- int replacementLength, Iterable results) { +- server.sendNotification(new CompletionResultsParams( +- completionId, replacementOffset, replacementLength, results, true) +- .toNotification()); +- } +- +- void setNewRequest(CompletionRequest completionRequest) { +- _abortCurrentRequest(); +- _currentRequest = completionRequest; +- } +- +- /** +- * Abort the current completion request, if any. +- */ +- void _abortCurrentRequest() { +- if (_currentRequest != null) { +- _currentRequest.abort(); +- _currentRequest = null; +- } +- } +-} +- +-/** +- * The result of computing suggestions for code completion. +- */ +-class CompletionResult { +- /** +- * The length of the text to be replaced if the remainder of the identifier +- * containing the cursor is to be replaced when the suggestion is applied +- * (that is, the number of characters in the existing identifier). +- */ +- final int replacementLength; +- +- /** +- * The offset of the start of the text to be replaced. This will be different +- * than the offset used to request the completion suggestions if there was a +- * portion of an identifier before the original offset. In particular, the +- * replacementOffset will be the offset of the beginning of said identifier. +- */ +- final int replacementOffset; +- +- /** +- * The suggested completions. +- */ +- final List suggestions; +- +- CompletionResult( +- this.replacementOffset, this.replacementLength, this.suggestions); +-} +diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart +deleted file mode 100644 +index 81bff6b0d40..00000000000 +--- a/pkg/analysis_server/lib/src/domain_diagnostic.dart ++++ /dev/null +@@ -1,75 +0,0 @@ +-// Copyright (c) 2015, 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:core'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +- +-/// Instances of the class [DiagnosticDomainHandler] implement a +-/// [RequestHandler] that handles requests in the `diagnostic` domain. +-class DiagnosticDomainHandler implements RequestHandler { +- /// The analysis server that is using this handler to process requests. +- final AnalysisServer server; +- +- /// Initialize a newly created handler to handle requests for the given +- /// [server]. +- DiagnosticDomainHandler(this.server); +- +- /// Answer the `diagnostic.getDiagnostics` request. +- Response computeDiagnostics(Request request) { +- List contexts = +- server.driverMap.values.map(extractDataFromDriver).toList(); +- return new DiagnosticGetDiagnosticsResult(contexts).toResponse(request.id); +- } +- +- /// Extract context data from the given [driver]. +- ContextData extractDataFromDriver(AnalysisDriver driver) { +- int explicitFileCount = driver.addedFiles.length; +- int knownFileCount = driver.knownFiles.length; +- return new ContextData(driver.name, explicitFileCount, +- knownFileCount - explicitFileCount, driver.numberOfFilesToAnalyze, []); +- } +- +- /// Answer the `diagnostic.getServerPort` request. +- Future handleGetServerPort(Request request) async { +- try { +- // Open a port (or return the existing one). +- int port = await server.diagnosticServer.getServerPort(); +- server.sendResponse( +- new DiagnosticGetServerPortResult(port).toResponse(request.id)); +- } catch (error) { +- server +- .sendResponse(new Response.debugPortCouldNotBeOpened(request, error)); +- } +- } +- +- @override +- Response handleRequest(Request request) { +- try { +- String requestName = request.method; +- if (requestName == DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS) { +- return computeDiagnostics(request); +- } else if (requestName == DIAGNOSTIC_REQUEST_GET_SERVER_PORT) { +- handleGetServerPort(request); +- return Response.DELAYED_RESPONSE; +- } +- } on RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +-} +- +-class MemoryCpuSample { +- final DateTime time; +- final double cpuPercentage; +- final int memoryKB; +- +- MemoryCpuSample(this.time, this.cpuPercentage, this.memoryKB); +-} +diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart +deleted file mode 100644 +index ea17e60cefd..00000000000 +--- a/pkg/analysis_server/lib/src/domain_execution.dart ++++ /dev/null +@@ -1,147 +0,0 @@ +-// Copyright (c) 2014, 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 'dart:core'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * Instances of the class [ExecutionDomainHandler] implement a [RequestHandler] +- * that handles requests in the `execution` domain. +- */ +-class ExecutionDomainHandler implements RequestHandler { +- /** +- * The analysis server that is using this handler to process requests. +- */ +- final AnalysisServer server; +- +- /** +- * The next execution context identifier to be returned. +- */ +- int nextContextId = 0; +- +- /** +- * A table mapping execution context id's to the root of the context. +- */ +- Map contextMap = new HashMap(); +- +- /** +- * The subscription to the 'onAnalysisComplete' events, +- * used to send notifications when +- */ +- StreamSubscription onFileAnalyzed; +- +- /** +- * Initialize a newly created handler to handle requests for the given [server]. +- */ +- ExecutionDomainHandler(this.server); +- +- /** +- * Implement the `execution.createContext` request. +- */ +- Response createContext(Request request) { +- String file = +- new ExecutionCreateContextParams.fromRequest(request).contextRoot; +- String contextId = (nextContextId++).toString(); +- contextMap[contextId] = file; +- return new ExecutionCreateContextResult(contextId).toResponse(request.id); +- } +- +- /** +- * Implement the `execution.deleteContext` request. +- */ +- Response deleteContext(Request request) { +- String contextId = new ExecutionDeleteContextParams.fromRequest(request).id; +- contextMap.remove(contextId); +- return new ExecutionDeleteContextResult().toResponse(request.id); +- } +- +- @override +- Response handleRequest(Request request) { +- try { +- String requestName = request.method; +- if (requestName == EXECUTION_REQUEST_CREATE_CONTEXT) { +- return createContext(request); +- } else if (requestName == EXECUTION_REQUEST_DELETE_CONTEXT) { +- return deleteContext(request); +- } else if (requestName == EXECUTION_REQUEST_MAP_URI) { +- return mapUri(request); +- } else if (requestName == EXECUTION_REQUEST_SET_SUBSCRIPTIONS) { +- return setSubscriptions(request); +- } +- } on RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +- +- /** +- * Implement the 'execution.mapUri' request. +- */ +- Response mapUri(Request request) { +- ExecutionMapUriParams params = +- new ExecutionMapUriParams.fromRequest(request); +- String contextId = params.id; +- String path = contextMap[contextId]; +- if (path == null) { +- return new Response.invalidParameter(request, 'id', +- 'There is no execution context with an id of $contextId'); +- } +- +- AnalysisDriver driver = server.getAnalysisDriver(path); +- if (driver == null) { +- return new Response.invalidExecutionContext(request, contextId); +- } +- SourceFactory sourceFactory = driver.sourceFactory; +- +- String file = params.file; +- String uri = params.uri; +- if (file != null) { +- if (uri != null) { +- return new Response.invalidParameter(request, 'file', +- 'Either file or uri must be provided, but not both'); +- } +- Resource resource = server.resourceProvider.getResource(file); +- if (!resource.exists) { +- return new Response.invalidParameter(request, 'file', 'Must exist'); +- } else if (resource is! File) { +- return new Response.invalidParameter( +- request, 'file', 'Must not refer to a directory'); +- } +- +- Source source = driver.fsState.getFileForPath(file).source; +- if (source.uriKind != UriKind.FILE_URI) { +- uri = source.uri.toString(); +- } else { +- uri = sourceFactory.restoreUri(source).toString(); +- } +- return new ExecutionMapUriResult(uri: uri).toResponse(request.id); +- } else if (uri != null) { +- Source source = sourceFactory.forUri(uri); +- if (source == null) { +- return new Response.invalidParameter(request, 'uri', 'Invalid URI'); +- } +- file = source.fullName; +- return new ExecutionMapUriResult(file: file).toResponse(request.id); +- } +- return new Response.invalidParameter( +- request, 'file', 'Either file or uri must be provided'); +- } +- +- /** +- * Implement the 'execution.setSubscriptions' request. +- */ +- Response setSubscriptions(Request request) { +- // Under the analysis driver, setSubscriptions() becomes a no-op. +- return new ExecutionSetSubscriptionsResult().toResponse(request.id); +- } +-} +diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart +deleted file mode 100644 +index 895bd82119d..00000000000 +--- a/pkg/analysis_server/lib/src/domain_kythe.dart ++++ /dev/null +@@ -1,114 +0,0 @@ +-// 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:core'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/domain_abstract.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/plugin/result_merger.dart'; +-import 'package:analysis_server/src/services/kythe/kythe_visitors.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +- +-/** +- * Instances of the class [KytheDomainHandler] implement a [RequestHandler] +- * that handles requests in the `kythe` domain. +- */ +-class KytheDomainHandler extends AbstractRequestHandler { +- /** +- * Initialize a newly created handler to handle requests for the given [server]. +- */ +- KytheDomainHandler(AnalysisServer server) : super(server); +- +- /** +- * Implement the `kythe.getKytheEntries` request. +- */ +- Future getKytheEntries(Request request) async { +- String file = new KytheGetKytheEntriesParams.fromRequest(request).file; +- AnalysisDriver driver = server.getAnalysisDriver(file); +- if (driver == null) { +- server.sendResponse(new Response.getKytheEntriesInvalidFile(request)); +- } else { +- // +- // Allow plugins to start computing entries. +- // +- plugin.KytheGetKytheEntriesParams requestParams = +- new plugin.KytheGetKytheEntriesParams(file); +- Map> pluginFutures = server +- .pluginManager +- .broadcastRequest(requestParams, contextRoot: driver.contextRoot); +- // +- // Compute entries generated by server. +- // +- List allResults = +- []; +- AnalysisResult result = await server.getAnalysisResult(file); +- CompilationUnit unit = result?.unit; +- if (unit != null && result.exists) { +- List entries = []; +- // TODO(brianwilkerson) Figure out how to get the list of files. +- List files = []; +- result.unit.accept(new KytheDartVisitor( +- server.resourceProvider, +- entries, +- file, +- new InheritanceManager(result.libraryElement), +- result.content)); +- allResults.add(new KytheGetKytheEntriesResult(entries, files)); +- } +- // +- // Add the entries produced by plugins to the server-generated entries. +- // +- if (pluginFutures != null) { +- List responses = await waitForResponses(pluginFutures, +- requestParameters: requestParams); +- for (plugin.Response response in responses) { +- plugin.KytheGetKytheEntriesResult result = +- new plugin.KytheGetKytheEntriesResult.fromResponse(response); +- allResults.add( +- new KytheGetKytheEntriesResult(result.entries, result.files)); +- } +- } +- // +- // Return the result. +- // +- ResultMerger merger = new ResultMerger(); +- KytheGetKytheEntriesResult mergedResults = +- merger.mergeKytheEntries(allResults); +- if (mergedResults == null) { +- server.sendResponse( +- new KytheGetKytheEntriesResult([], []) +- .toResponse(request.id)); +- } else { +- server.sendResponse(new KytheGetKytheEntriesResult( +- mergedResults.entries, mergedResults.files) +- .toResponse(request.id)); +- } +- } +- } +- +- @override +- Response handleRequest(Request request) { +- try { +- String requestName = request.method; +- if (requestName == KYTHE_REQUEST_GET_KYTHE_ENTRIES) { +- getKytheEntries(request); +- return Response.DELAYED_RESPONSE; +- } +- } on RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/domain_server.dart b/pkg/analysis_server/lib/src/domain_server.dart +deleted file mode 100644 +index ccd12bc9dbc..00000000000 +--- a/pkg/analysis_server/lib/src/domain_server.dart ++++ /dev/null +@@ -1,74 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +- +-/** +- * Instances of the class [ServerDomainHandler] implement a [RequestHandler] +- * that handles requests in the server domain. +- */ +-class ServerDomainHandler implements RequestHandler { +- /** +- * The analysis server that is using this handler to process requests. +- */ +- final AnalysisServer server; +- +- /** +- * Initialize a newly created handler to handle requests for the given [server]. +- */ +- ServerDomainHandler(this.server); +- +- /** +- * Return the version number of the analysis server. +- */ +- Response getVersion(Request request) { +- return new ServerGetVersionResult(AnalysisServer.VERSION) +- .toResponse(request.id); +- } +- +- @override +- Response handleRequest(Request request) { +- try { +- String requestName = request.method; +- if (requestName == SERVER_REQUEST_GET_VERSION) { +- return getVersion(request); +- } else if (requestName == SERVER_REQUEST_SET_SUBSCRIPTIONS) { +- return setSubscriptions(request); +- } else if (requestName == SERVER_REQUEST_SHUTDOWN) { +- shutdown(request); +- return Response.DELAYED_RESPONSE; +- } +- } on RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +- +- /** +- * Subscribe for services. +- * +- * All previous subscriptions are replaced by the given set of subscriptions. +- */ +- Response setSubscriptions(Request request) { +- server.serverServices = +- new ServerSetSubscriptionsParams.fromRequest(request) +- .subscriptions +- .toSet(); +- return new ServerSetSubscriptionsResult().toResponse(request.id); +- } +- +- /** +- * Cleanly shutdown the analysis server. +- */ +- Future shutdown(Request request) async { +- await server.shutdown(); +- Response response = new ServerShutdownResult().toResponse(request.id); +- server.sendResponse(response); +- } +-} +diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart +deleted file mode 100644 +index 54f99734920..00000000000 +--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart ++++ /dev/null +@@ -1,79 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-class ImplementedComputer { +- final SearchEngine searchEngine; +- final CompilationUnitElement unitElement; +- +- List classes = []; +- List members = []; +- +- Set subtypeMembers; +- +- ImplementedComputer(this.searchEngine, this.unitElement); +- +- compute() async { +- for (ClassElement type in unitElement.types) { +- // Always include Object and its members. +- if (type.supertype == null) { +- _addImplementedClass(type); +- type.accessors.forEach(_addImplementedMember); +- type.fields.forEach(_addImplementedMember); +- type.methods.forEach(_addImplementedMember); +- continue; +- } +- +- // Analyze subtypes. +- subtypeMembers = await searchEngine.membersOfSubtypes(type); +- if (subtypeMembers != null) { +- _addImplementedClass(type); +- type.accessors.forEach(_addMemberIfImplemented); +- type.fields.forEach(_addMemberIfImplemented); +- type.methods.forEach(_addMemberIfImplemented); +- } +- } +- } +- +- void _addImplementedClass(ClassElement type) { +- int offset = type.nameOffset; +- int length = type.nameLength; +- classes.add(new protocol.ImplementedClass(offset, length)); +- } +- +- void _addImplementedMember(Element member) { +- int offset = member.nameOffset; +- int length = member.nameLength; +- members.add(new protocol.ImplementedMember(offset, length)); +- } +- +- void _addMemberIfImplemented(Element element) { +- if (element.isSynthetic || _isStatic(element)) { +- return; +- } +- if (_hasOverride(element)) { +- _addImplementedMember(element); +- } +- } +- +- bool _hasOverride(Element element) { +- String name = element.displayName; +- return subtypeMembers.contains(name); +- } +- +- /** +- * Return `true` if the given [element] is a static element. +- */ +- static bool _isStatic(Element element) { +- if (element is ExecutableElement) { +- return element.isStatic; +- } else if (element is PropertyInducingElement) { +- return element.isStatic; +- } +- return false; +- } +-} +diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart +deleted file mode 100644 +index 5ed3bcefafe..00000000000 +--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart ++++ /dev/null +@@ -1,360 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/element.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/navigation/navigation.dart'; +- +-NavigationCollector computeDartNavigation(NavigationCollector collector, +- CompilationUnit unit, int offset, int length) { +- _DartNavigationCollector dartCollector = +- new _DartNavigationCollector(collector); +- _DartNavigationComputerVisitor visitor = +- new _DartNavigationComputerVisitor(dartCollector); +- if (offset == null || length == null) { +- unit.accept(visitor); +- } else { +- AstNode node = _getNodeForRange(unit, offset, length); +- node?.accept(visitor); +- } +- return collector; +-} +- +-AstNode _getNodeForRange(CompilationUnit unit, int offset, int length) { +- AstNode node = new NodeLocator(offset, offset + length).searchWithin(unit); +- for (AstNode n = node; n != null; n = n.parent) { +- if (n is Directive) { +- return n; +- } +- } +- return node; +-} +- +-/** +- * A Dart specific wrapper around [NavigationCollector]. +- */ +-class _DartNavigationCollector { +- final NavigationCollector collector; +- +- _DartNavigationCollector(this.collector); +- +- void _addRegion(int offset, int length, Element element) { +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- if (element == null || element == DynamicElementImpl.instance) { +- return; +- } +- if (element.location == null) { +- return; +- } +- protocol.ElementKind kind = protocol.convertElementKind(element.kind); +- protocol.Location location = protocol.newLocation_fromElement(element); +- if (location == null) { +- return; +- } +- collector.addRegion(offset, length, kind, location); +- } +- +- void _addRegion_nodeStart_nodeEnd(AstNode a, AstNode b, Element element) { +- int offset = a.offset; +- int length = b.end - offset; +- _addRegion(offset, length, element); +- } +- +- void _addRegionForNode(AstNode node, Element element) { +- if (node == null) { +- return; +- } +- int offset = node.offset; +- int length = node.length; +- _addRegion(offset, length, element); +- } +- +- void _addRegionForToken(Token token, Element element) { +- int offset = token.offset; +- int length = token.length; +- _addRegion(offset, length, element); +- } +-} +- +-class _DartNavigationComputerVisitor extends RecursiveAstVisitor { +- final _DartNavigationCollector computer; +- +- _DartNavigationComputerVisitor(this.computer); +- +- @override +- visitAnnotation(Annotation node) { +- Element element = node.element; +- if (element is ConstructorElement && element.isSynthetic) { +- element = element.enclosingElement; +- } +- Identifier name = node.name; +- if (name is PrefixedIdentifier) { +- // use constructor in: @PrefixClass.constructorName +- Element prefixElement = name.prefix.staticElement; +- if (prefixElement is ClassElement) { +- prefixElement = element; +- } +- computer._addRegionForNode(name.prefix, prefixElement); +- // always constructor +- computer._addRegionForNode(name.identifier, element); +- } else { +- computer._addRegionForNode(name, element); +- } +- computer._addRegionForNode(node.constructorName, element); +- // arguments +- node.arguments?.accept(this); +- } +- +- @override +- visitAssignmentExpression(AssignmentExpression node) { +- node.leftHandSide?.accept(this); +- computer._addRegionForToken(node.operator, node.bestElement); +- node.rightHandSide?.accept(this); +- } +- +- @override +- visitBinaryExpression(BinaryExpression node) { +- node.leftOperand?.accept(this); +- computer._addRegionForToken(node.operator, node.bestElement); +- node.rightOperand?.accept(this); +- } +- +- @override +- visitCompilationUnit(CompilationUnit unit) { +- // prepare top-level nodes sorted by their offsets +- List nodes = []; +- nodes.addAll(unit.directives); +- nodes.addAll(unit.declarations); +- nodes.sort((a, b) { +- return a.offset - b.offset; +- }); +- // visit sorted nodes +- for (AstNode node in nodes) { +- node.accept(this); +- } +- } +- +- @override +- visitConstructorDeclaration(ConstructorDeclaration node) { +- // associate constructor with "T" or "T.name" +- { +- AstNode firstNode = node.returnType; +- AstNode lastNode = node.name; +- if (lastNode == null) { +- lastNode = firstNode; +- } +- if (firstNode != null && lastNode != null) { +- computer._addRegion_nodeStart_nodeEnd( +- firstNode, lastNode, node.element); +- } +- } +- super.visitConstructorDeclaration(node); +- } +- +- @override +- visitConstructorName(ConstructorName node) { +- AstNode parent = node.parent; +- if (parent is InstanceCreationExpression && +- parent.constructorName == node) { +- _addConstructorName(parent, node); +- } else if (parent is ConstructorDeclaration && +- parent.redirectedConstructor == node) { +- _addConstructorName(node, node); +- } +- } +- +- @override +- visitDeclaredIdentifier(DeclaredIdentifier node) { +- if (node.type == null) { +- Token token = node.keyword; +- if (token?.keyword == Keyword.VAR) { +- DartType inferredType = node.identifier?.bestType; +- Element element = inferredType?.element; +- if (element != null) { +- computer._addRegionForToken(token, element); +- } +- } +- } +- super.visitDeclaredIdentifier(node); +- } +- +- @override +- visitExportDirective(ExportDirective node) { +- ExportElement exportElement = node.element; +- if (exportElement != null) { +- Element libraryElement = exportElement.exportedLibrary; +- _addUriDirectiveRegion(node, libraryElement); +- } +- super.visitExportDirective(node); +- } +- +- @override +- visitImportDirective(ImportDirective node) { +- ImportElement importElement = node.element; +- if (importElement != null) { +- Element libraryElement = importElement.importedLibrary; +- _addUriDirectiveRegion(node, libraryElement); +- } +- super.visitImportDirective(node); +- } +- +- @override +- visitIndexExpression(IndexExpression node) { +- super.visitIndexExpression(node); +- MethodElement element = node.bestElement; +- computer._addRegionForToken(node.leftBracket, element); +- computer._addRegionForToken(node.rightBracket, element); +- } +- +- @override +- visitLibraryDirective(LibraryDirective node) { +- computer._addRegionForNode(node.name, node.element); +- } +- +- @override +- visitPartDirective(PartDirective node) { +- _addUriDirectiveRegion(node, node.element); +- super.visitPartDirective(node); +- } +- +- @override +- visitPartOfDirective(PartOfDirective node) { +- computer._addRegionForNode(node.libraryName, node.element); +- super.visitPartOfDirective(node); +- } +- +- @override +- visitPostfixExpression(PostfixExpression node) { +- super.visitPostfixExpression(node); +- computer._addRegionForToken(node.operator, node.bestElement); +- } +- +- @override +- visitPrefixExpression(PrefixExpression node) { +- computer._addRegionForToken(node.operator, node.bestElement); +- super.visitPrefixExpression(node); +- } +- +- @override +- visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) { +- Element element = node.staticElement; +- if (element != null && element.isSynthetic) { +- element = element.enclosingElement; +- } +- // add region +- computer._addRegionForToken(node.thisKeyword, element); +- computer._addRegionForNode(node.constructorName, element); +- // process arguments +- node.argumentList?.accept(this); +- } +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- if (node.parent is ConstructorDeclaration) { +- return; +- } +- Element element = node.bestElement; +- computer._addRegionForNode(node, element); +- } +- +- @override +- visitSuperConstructorInvocation(SuperConstructorInvocation node) { +- Element element = node.staticElement; +- if (element != null && element.isSynthetic) { +- element = element.enclosingElement; +- } +- // add region +- computer._addRegionForToken(node.superKeyword, element); +- computer._addRegionForNode(node.constructorName, element); +- // process arguments +- node.argumentList?.accept(this); +- } +- +- @override +- visitVariableDeclarationList(VariableDeclarationList node) { +- /** +- * Return the element for the type inferred for each of the variables in the +- * given list of [variables], or `null` if not all variable have the same +- * inferred type. +- */ +- Element getCommonElement(List variables) { +- Element firstElement = variables[0].name?.bestType?.element; +- if (firstElement == null) { +- return null; +- } +- for (int i = 1; i < variables.length; i++) { +- Element element = variables[1].name?.bestType?.element; +- if (element != firstElement) { +- return null; +- } +- } +- return firstElement; +- } +- +- if (node.type == null) { +- Token token = node.keyword; +- if (token?.keyword == Keyword.VAR) { +- Element element = getCommonElement(node.variables); +- if (element != null) { +- computer._addRegionForToken(token, element); +- } +- } +- } +- super.visitVariableDeclarationList(node); +- } +- +- void _addConstructorName(AstNode parent, ConstructorName node) { +- Element element = node.staticElement; +- if (element == null) { +- return; +- } +- // if a synthetic constructor, navigate to the class +- if (element.isSynthetic) { +- element = element.enclosingElement; +- } +- // add regions +- TypeName typeName = node.type; +- // [prefix].ClassName +- { +- Identifier name = typeName.name; +- Identifier className = name; +- if (name is PrefixedIdentifier) { +- name.prefix.accept(this); +- className = name.identifier; +- } +- computer._addRegionForNode(className, element); +- } +- // +- TypeArgumentList typeArguments = typeName.typeArguments; +- if (typeArguments != null) { +- typeArguments.accept(this); +- } +- // optional "name" +- if (node.name != null) { +- computer._addRegionForNode(node.name, element); +- } +- } +- +- /** +- * If the source of the given [element] (referenced by the [node]) exists, +- * then add the navigation region from the [node] to the [element]. +- */ +- void _addUriDirectiveRegion(UriBasedDirective node, Element element) { +- if (element != null) { +- Source source = element.source; +- if (element.context.exists(source)) { +- computer._addRegionForNode(node.uri, element); +- } +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart +deleted file mode 100644 +index 3862078c0e0..00000000000 +--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences.dart ++++ /dev/null +@@ -1,33 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +- +-/** +- * A concrete implementation of [OccurrencesCollector]. +- */ +-class OccurrencesCollectorImpl implements OccurrencesCollector { +- Map elementOccurrences = +- {}; +- +- List get allOccurrences { +- return elementOccurrences.values.toList(); +- } +- +- @override +- void addOccurrences(protocol.Occurrences current) { +- protocol.Element element = current.element; +- protocol.Occurrences existing = elementOccurrences[element]; +- if (existing != null) { +- List offsets = _merge(existing.offsets, current.offsets); +- current = new protocol.Occurrences(element, offsets, existing.length); +- } +- elementOccurrences[element] = current; +- } +- +- static List _merge(List a, List b) { +- return []..addAll(a)..addAll(b); +- } +-} +diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart +deleted file mode 100644 +index f9774ab457a..00000000000 +--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart ++++ /dev/null +@@ -1,63 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/member.dart'; +- +-void addDartOccurrences(OccurrencesCollector collector, CompilationUnit unit) { +- _DartUnitOccurrencesComputerVisitor visitor = +- new _DartUnitOccurrencesComputerVisitor(); +- unit.accept(visitor); +- visitor.elementsOffsets.forEach((engineElement, offsets) { +- int length = engineElement.nameLength; +- protocol.Element serverElement = protocol.convertElement(engineElement); +- protocol.Occurrences occurrences = +- new protocol.Occurrences(serverElement, offsets, length); +- collector.addOccurrences(occurrences); +- }); +-} +- +-class _DartUnitOccurrencesComputerVisitor extends RecursiveAstVisitor { +- final Map> elementsOffsets = >{}; +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- Element element = node.bestElement; +- if (element != null) { +- _addOccurrence(element, node.offset); +- } +- return super.visitSimpleIdentifier(node); +- } +- +- void _addOccurrence(Element element, int offset) { +- element = _canonicalizeElement(element); +- if (element == null || element == DynamicElementImpl.instance) { +- return; +- } +- List offsets = elementsOffsets[element]; +- if (offsets == null) { +- offsets = []; +- elementsOffsets[element] = offsets; +- } +- offsets.add(offset); +- } +- +- Element _canonicalizeElement(Element element) { +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- if (element is PropertyAccessorElement) { +- element = (element as PropertyAccessorElement).variable; +- } +- if (element is Member) { +- element = (element as Member).baseElement; +- } +- return element; +- } +-} +diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart +deleted file mode 100644 +index c1fd4e5b28a..00000000000 +--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart ++++ /dev/null +@@ -1,1062 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +-import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; +-import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +-import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/collections.dart'; +-import 'package:analysis_server/src/computer/import_elements_computer.dart'; +-import 'package:analysis_server/src/domain_abstract.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/plugin/result_converter.dart'; +-import 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/completion/postfix/postfix_completion.dart'; +-import 'package:analysis_server/src/services/completion/statement/statement_completion.dart'; +-import 'package:analysis_server/src/services/correction/assist_internal.dart'; +-import 'package:analysis_server/src/services/correction/fix_internal.dart'; +-import 'package:analysis_server/src/services/correction/organize_directives.dart'; +-import 'package:analysis_server/src/services/correction/sort_members.dart'; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/dart/scanner/scanner.dart' as engine; +-import 'package:analyzer/src/error/codes.dart' as engine; +-import 'package:analyzer/src/generated/engine.dart' as engine; +-import 'package:analyzer/src/generated/parser.dart' as engine; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:dart_style/dart_style.dart'; +- +-int test_resetCount = 0; +- +-bool test_simulateRefactoringException_change = false; +-bool test_simulateRefactoringException_final = false; +-bool test_simulateRefactoringException_init = false; +- +-bool test_simulateRefactoringReset_afterCreateChange = false; +-bool test_simulateRefactoringReset_afterFinalConditions = false; +-bool test_simulateRefactoringReset_afterInitialConditions = false; +- +-/** +- * Instances of the class [EditDomainHandler] implement a [RequestHandler] +- * that handles requests in the edit domain. +- */ +-class EditDomainHandler extends AbstractRequestHandler { +- /** +- * The [SearchEngine] for this server. +- */ +- SearchEngine searchEngine; +- +- /** +- * The object used to manage uncompleted refactorings. +- */ +- _RefactoringManager refactoringManager; +- +- /** +- * Initialize a newly created handler to handle requests for the given [server]. +- */ +- EditDomainHandler(AnalysisServer server) : super(server) { +- searchEngine = server.searchEngine; +- _newRefactoringManager(); +- } +- +- Response format(Request request) { +- server.options.analytics?.sendEvent('edit', 'format'); +- +- EditFormatParams params = new EditFormatParams.fromRequest(request); +- String file = params.file; +- +- String unformattedSource; +- try { +- Source source = server.resourceProvider.getFile(file).createSource(); +- unformattedSource = +- server.fileContentOverlay[file] ?? source.contents.data; +- } catch (e) { +- return new Response.formatInvalidFile(request); +- } +- +- int start = params.selectionOffset; +- int length = params.selectionLength; +- +- // No need to preserve 0,0 selection +- if (start == 0 && length == 0) { +- start = null; +- length = null; +- } +- +- SourceCode code = new SourceCode(unformattedSource, +- uri: null, +- isCompilationUnit: true, +- selectionStart: start, +- selectionLength: length); +- DartFormatter formatter = new DartFormatter(pageWidth: params.lineLength); +- SourceCode formattedResult; +- try { +- formattedResult = formatter.formatSource(code); +- } on FormatterException { +- return new Response.formatWithErrors(request); +- } +- String formattedSource = formattedResult.text; +- +- List edits = []; +- +- if (formattedSource != unformattedSource) { +- //TODO: replace full replacements with smaller, more targeted edits +- SourceEdit edit = +- new SourceEdit(0, unformattedSource.length, formattedSource); +- edits.add(edit); +- } +- +- int newStart = formattedResult.selectionStart; +- int newLength = formattedResult.selectionLength; +- +- // Sending null start/length values would violate protocol, so convert back +- // to 0. +- if (newStart == null) { +- newStart = 0; +- } +- if (newLength == null) { +- newLength = 0; +- } +- +- return new EditFormatResult(edits, newStart, newLength) +- .toResponse(request.id); +- } +- +- Future getAssists(Request request) async { +- EditGetAssistsParams params = new EditGetAssistsParams.fromRequest(request); +- String file = params.file; +- int offset = params.offset; +- int length = params.length; +- +- List changes = []; +- // +- // Allow plugins to start computing assists. +- // +- Map> pluginFutures; +- plugin.EditGetAssistsParams requestParams = +- new plugin.EditGetAssistsParams(file, offset, length); +- AnalysisDriver driver = server.getAnalysisDriver(file); +- if (driver == null) { +- pluginFutures = >{}; +- } else { +- pluginFutures = server.pluginManager +- .broadcastRequest(requestParams, contextRoot: driver.contextRoot); +- } +- // +- // Compute fixes associated with server-generated errors. +- // +- AnalysisResult result = await server.getAnalysisResult(file); +- if (result != null) { +- CompilationUnit unit = result.unit; +- CompilationUnitElement compilationUnitElement = +- resolutionMap.elementDeclaredByCompilationUnit(unit); +- DartAssistContext dartAssistContext = new _DartAssistContextForValues( +- compilationUnitElement.source, +- offset, +- length, +- driver, +- new AstProviderForDriver(driver), +- unit); +- try { +- AssistProcessor processor = new AssistProcessor(dartAssistContext); +- List assists = await processor.compute(); +- for (Assist assist in assists) { +- changes.add(assist.change); +- } +- } catch (_) {} +- } +- // +- // Add the fixes produced by plugins to the server-generated fixes. +- // +- List responses = +- await waitForResponses(pluginFutures, requestParameters: requestParams); +- ResultConverter converter = new ResultConverter(); +- List pluginChanges = +- []; +- for (plugin.Response response in responses) { +- plugin.EditGetAssistsResult result = +- new plugin.EditGetAssistsResult.fromResponse(response); +- pluginChanges.addAll(result.assists); +- } +- pluginChanges +- .sort((first, second) => first.priority.compareTo(second.priority)); +- changes.addAll(pluginChanges.map(converter.convertPrioritizedSourceChange)); +- // +- // Send the response. +- // +- server +- .sendResponse(new EditGetAssistsResult(changes).toResponse(request.id)); +- } +- +- Future getFixes(Request request) async { +- var params = new EditGetFixesParams.fromRequest(request); +- String file = params.file; +- int offset = params.offset; +- +- List errorFixesList = []; +- // +- // Allow plugins to start computing fixes. +- // +- Map> pluginFutures; +- plugin.EditGetFixesParams requestParams = +- new plugin.EditGetFixesParams(file, offset); +- AnalysisDriver driver = server.getAnalysisDriver(file); +- if (driver == null) { +- pluginFutures = >{}; +- } else { +- pluginFutures = server.pluginManager +- .broadcastRequest(requestParams, contextRoot: driver.contextRoot); +- } +- // +- // Compute fixes associated with server-generated errors. +- // +- AnalysisResult result = await server.getAnalysisResult(file); +- if (result != null) { +- CompilationUnit unit = result.unit; +- LineInfo lineInfo = result.lineInfo; +- int requestLine = lineInfo.getLocation(offset).lineNumber; +- for (engine.AnalysisError error in result.errors) { +- int errorLine = lineInfo.getLocation(error.offset).lineNumber; +- if (errorLine == requestLine) { +- var context = new _DartFixContextImpl(server.resourceProvider, +- result.driver, new AstProviderForDriver(driver), unit, error); +- List fixes = +- await new DefaultFixContributor().internalComputeFixes(context); +- if (fixes.isNotEmpty) { +- fixes.sort(Fix.SORT_BY_RELEVANCE); +- AnalysisError serverError = +- newAnalysisError_fromEngine(lineInfo, error); +- AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError); +- errorFixesList.add(errorFixes); +- fixes.forEach((fix) { +- errorFixes.fixes.add(fix.change); +- }); +- } +- } +- } +- } +- // +- // Add the fixes produced by plugins to the server-generated fixes. +- // +- List responses = +- await waitForResponses(pluginFutures, requestParameters: requestParams); +- ResultConverter converter = new ResultConverter(); +- for (plugin.Response response in responses) { +- plugin.EditGetFixesResult result = +- new plugin.EditGetFixesResult.fromResponse(response); +- errorFixesList +- .addAll(result.fixes.map(converter.convertAnalysisErrorFixes)); +- } +- // +- // Send the response. +- // +- server.sendResponse( +- new EditGetFixesResult(errorFixesList).toResponse(request.id)); +- } +- +- Future getPostfixCompletion(Request request) async { +- server.options.analytics?.sendEvent('edit', 'getPostfixCompletion'); +- +- var params = new EditGetPostfixCompletionParams.fromRequest(request); +- SourceChange change; +- +- AnalysisResult result = await server.getAnalysisResult(params.file); +- if (result != null) { +- CompilationUnit unit = result.unit; +- CompilationUnitElement unitElement = +- resolutionMap.elementDeclaredByCompilationUnit(unit); +- if (unitElement.context != null) { +- PostfixCompletionContext context = new PostfixCompletionContext( +- params.file, +- result.lineInfo, +- params.offset, +- params.key, +- result.driver, +- unit, +- unitElement, +- result.errors); +- PostfixCompletionProcessor processor = +- new PostfixCompletionProcessor(context); +- PostfixCompletion completion = await processor.compute(); +- change = completion?.change; +- } +- } +- if (change == null) { +- change = new SourceChange("", edits: []); +- } +- +- Response response = +- new EditGetPostfixCompletionResult(change).toResponse(request.id); +- server.sendResponse(response); +- } +- +- Future getStatementCompletion(Request request) async { +- var params = new EditGetStatementCompletionParams.fromRequest(request); +- SourceChange change; +- +- AnalysisResult result = await server.getAnalysisResult(params.file); +- if (result != null) { +- CompilationUnit unit = result.unit; +- CompilationUnitElement unitElement = +- resolutionMap.elementDeclaredByCompilationUnit(unit); +- if (unitElement.context != null) { +- StatementCompletionContext context = new StatementCompletionContext( +- params.file, +- result.lineInfo, +- params.offset, +- unit, +- unitElement, +- result.errors); +- StatementCompletionProcessor processor = +- new StatementCompletionProcessor(context); +- StatementCompletion completion = await processor.compute(); +- change = completion.change; +- } +- } +- if (change == null) { +- change = new SourceChange("", edits: []); +- } +- +- Response response = new EditGetStatementCompletionResult(change, false) +- .toResponse(request.id); +- server.sendResponse(response); +- } +- +- @override +- Response handleRequest(Request request) { +- try { +- String requestName = request.method; +- if (requestName == EDIT_REQUEST_FORMAT) { +- return format(request); +- } else if (requestName == EDIT_REQUEST_GET_ASSISTS) { +- getAssists(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS) { +- return _getAvailableRefactorings(request); +- } else if (requestName == EDIT_REQUEST_GET_FIXES) { +- getFixes(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_GET_REFACTORING) { +- return _getRefactoring(request); +- } else if (requestName == EDIT_REQUEST_IMPORT_ELEMENTS) { +- importElements(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_ORGANIZE_DIRECTIVES) { +- organizeDirectives(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_SORT_MEMBERS) { +- sortMembers(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_GET_STATEMENT_COMPLETION) { +- getStatementCompletion(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE) { +- isPostfixCompletionApplicable(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == EDIT_REQUEST_GET_POSTFIX_COMPLETION) { +- getPostfixCompletion(request); +- return Response.DELAYED_RESPONSE; +- } else if (requestName == +- EDIT_REQUEST_LIST_POSTFIX_COMPLETION_TEMPLATES) { +- listPostfixCompletionTemplates(request); +- return Response.DELAYED_RESPONSE; +- } +- } on RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +- +- /** +- * Implement the `edit.importElements` request. +- */ +- Future importElements(Request request) async { +- EditImportElementsParams params = +- new EditImportElementsParams.fromRequest(request); +- // +- // Prepare the resolved unit. +- // +- AnalysisResult result = await server.getAnalysisResult(params.file); +- if (result == null) { +- server.sendResponse(new Response.importElementsInvalidFile(request)); +- } +- CompilationUnitElement libraryUnit = +- result.libraryElement.definingCompilationUnit; +- if (libraryUnit != result.unit.element) { +- // The file in the request is a part of a library. We need to pass the +- // defining compilation unit to the computer, not the part. +- result = await server.getAnalysisResult(libraryUnit.source.fullName); +- if (result == null) { +- server.sendResponse(new Response.importElementsInvalidFile(request)); +- } +- } +- // +- // Compute the edits required to import the required elements. +- // +- ImportElementsComputer computer = +- new ImportElementsComputer(server.resourceProvider, result); +- SourceChange change = await computer.createEdits(params.elements); +- // +- // Send the response. +- // +- server.sendResponse( +- new EditImportElementsResult(change.edits[0]).toResponse(request.id)); +- } +- +- Future isPostfixCompletionApplicable(Request request) async { +- var params = new EditGetPostfixCompletionParams.fromRequest(request); +- bool value = false; +- +- AnalysisResult result = await server.getAnalysisResult(params.file); +- if (result != null) { +- CompilationUnit unit = result.unit; +- CompilationUnitElement unitElement = +- resolutionMap.elementDeclaredByCompilationUnit(unit); +- if (unitElement.context != null) { +- PostfixCompletionContext context = new PostfixCompletionContext( +- params.file, +- result.lineInfo, +- params.offset, +- params.key, +- result.driver, +- unit, +- unitElement, +- result.errors); +- PostfixCompletionProcessor processor = +- new PostfixCompletionProcessor(context); +- value = await processor.isApplicable(); +- } +- } +- +- Response response = new EditIsPostfixCompletionApplicableResult(value) +- .toResponse(request.id); +- server.sendResponse(response); +- } +- +- Future listPostfixCompletionTemplates(Request request) async { +- var templates = DartPostfixCompletion.ALL_TEMPLATES +- .map((pfc) => +- new PostfixTemplateDescriptor(pfc.name, pfc.key, pfc.example)) +- .toList(); +- +- Response response = new EditListPostfixCompletionTemplatesResult(templates) +- .toResponse(request.id); +- server.sendResponse(response); +- } +- +- Future organizeDirectives(Request request) async { +- server.options.analytics?.sendEvent('edit', 'organizeDirectives'); +- +- var params = new EditOrganizeDirectivesParams.fromRequest(request); +- // prepare file +- String file = params.file; +- if (!engine.AnalysisEngine.isDartFileName(file)) { +- server.sendResponse(new Response.fileNotAnalyzed(request, file)); +- return; +- } +- // Prepare the file information. +- AnalysisResult result = await server.getAnalysisResult(file); +- if (result == null) { +- server.sendResponse(new Response.fileNotAnalyzed(request, file)); +- return; +- } +- int fileStamp = -1; +- String code = result.content; +- CompilationUnit unit = result.unit; +- List errors = result.errors; +- // check if there are scan/parse errors in the file +- int numScanParseErrors = _getNumberOfScanParseErrors(errors); +- if (numScanParseErrors != 0) { +- server.sendResponse(new Response.organizeDirectivesError( +- request, 'File has $numScanParseErrors scan/parse errors.')); +- return; +- } +- // do organize +- DirectiveOrganizer sorter = new DirectiveOrganizer(code, unit, errors); +- List edits = sorter.organize(); +- SourceFileEdit fileEdit = new SourceFileEdit(file, fileStamp, edits: edits); +- server.sendResponse( +- new EditOrganizeDirectivesResult(fileEdit).toResponse(request.id)); +- } +- +- Future sortMembers(Request request) async { +- var params = new EditSortMembersParams.fromRequest(request); +- // prepare file +- String file = params.file; +- if (!engine.AnalysisEngine.isDartFileName(file)) { +- server.sendResponse(new Response.sortMembersInvalidFile(request)); +- return; +- } +- // Prepare the file information. +- AnalysisDriver driver = server.getAnalysisDriver(file); +- ParseResult result = await driver?.parseFile(file); +- if (result == null) { +- server.sendResponse(new Response.fileNotAnalyzed(request, file)); +- return; +- } +- int fileStamp = -1; +- String code = result.content; +- CompilationUnit unit = result.unit; +- List errors = result.errors; +- // Check if there are scan/parse errors in the file. +- int numScanParseErrors = _getNumberOfScanParseErrors(errors); +- if (numScanParseErrors != 0) { +- server.sendResponse( +- new Response.sortMembersParseErrors(request, numScanParseErrors)); +- return; +- } +- // Do sort. +- MemberSorter sorter = new MemberSorter(code, unit); +- List edits = sorter.sort(); +- SourceFileEdit fileEdit = new SourceFileEdit(file, fileStamp, edits: edits); +- server.sendResponse( +- new EditSortMembersResult(fileEdit).toResponse(request.id)); +- } +- +- Response _getAvailableRefactorings(Request request) { +- _getAvailableRefactoringsImpl(request); +- return Response.DELAYED_RESPONSE; +- } +- +- Future _getAvailableRefactoringsImpl(Request request) async { +- // prepare parameters +- var params = new EditGetAvailableRefactoringsParams.fromRequest(request); +- String file = params.file; +- int offset = params.offset; +- int length = params.length; +- // add refactoring kinds +- List kinds = []; +- // try EXTRACT_* +- if (length != 0) { +- kinds.add(RefactoringKind.EXTRACT_LOCAL_VARIABLE); +- kinds.add(RefactoringKind.EXTRACT_METHOD); +- } +- // check elements +- { +- Element element = await server.getElementAtOffset(file, offset); +- if (element != null) { +- // try CONVERT_METHOD_TO_GETTER +- if (element is ExecutableElement) { +- Refactoring refactoring = new ConvertMethodToGetterRefactoring( +- searchEngine, server.getAstProvider(file), element); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- if (!status.hasFatalError) { +- kinds.add(RefactoringKind.CONVERT_METHOD_TO_GETTER); +- } +- } +- // try RENAME +- { +- RenameRefactoring renameRefactoring = new RenameRefactoring( +- searchEngine, server.getAstProvider(file), element); +- if (renameRefactoring != null) { +- kinds.add(RefactoringKind.RENAME); +- } +- } +- } +- } +- // respond +- var result = new EditGetAvailableRefactoringsResult(kinds); +- server.sendResponse(result.toResponse(request.id)); +- } +- +- Response _getRefactoring(Request request) { +- if (refactoringManager.hasPendingRequest) { +- refactoringManager.cancel(); +- _newRefactoringManager(); +- } +- refactoringManager.getRefactoring(request); +- return Response.DELAYED_RESPONSE; +- } +- +- /** +- * Initializes [refactoringManager] with a new instance. +- */ +- void _newRefactoringManager() { +- refactoringManager = new _RefactoringManager(server, searchEngine); +- } +- +- static int _getNumberOfScanParseErrors(List errors) { +- int numScanParseErrors = 0; +- for (engine.AnalysisError error in errors) { +- if (error.errorCode is engine.ScannerErrorCode || +- error.errorCode is engine.ParserErrorCode) { +- numScanParseErrors++; +- } +- } +- return numScanParseErrors; +- } +-} +- +-/** +- * Implementation of [DartAssistContext] that is based on the values passed +- * in the constructor, as opposite to be partially based on [AssistContext]. +- */ +-class _DartAssistContextForValues implements DartAssistContext { +- @override +- final Source source; +- +- @override +- final int selectionOffset; +- +- @override +- final int selectionLength; +- +- @override +- final AnalysisDriver analysisDriver; +- +- @override +- final AstProvider astProvider; +- +- @override +- final CompilationUnit unit; +- +- _DartAssistContextForValues(this.source, this.selectionOffset, +- this.selectionLength, this.analysisDriver, this.astProvider, this.unit); +-} +- +-/** +- * And implementation of [DartFixContext]. +- */ +-class _DartFixContextImpl implements DartFixContext { +- @override +- final ResourceProvider resourceProvider; +- +- @override +- final AnalysisDriver analysisDriver; +- +- @override +- final AstProvider astProvider; +- +- @override +- final CompilationUnit unit; +- +- @override +- final engine.AnalysisError error; +- +- _DartFixContextImpl(this.resourceProvider, this.analysisDriver, +- this.astProvider, this.unit, this.error); +- +- @override +- GetTopLevelDeclarations get getTopLevelDeclarations => +- analysisDriver.getTopLevelNameDeclarations; +-} +- +-/** +- * An object managing a single [Refactoring] instance. +- * +- * The instance is identified by its kind, file, offset and length. +- * It is initialized when the a set of parameters is given for the first time. +- * All subsequent requests are performed on this [Refactoring] instance. +- * +- * Once new set of parameters is received, the previous [Refactoring] instance +- * is invalidated and a new one is created and initialized. +- */ +-class _RefactoringManager { +- static const List EMPTY_PROBLEM_LIST = +- const []; +- +- final AnalysisServer server; +- final SearchEngine searchEngine; +- StreamSubscription subscriptionToReset; +- +- RefactoringKind kind; +- String file; +- int offset; +- int length; +- Refactoring refactoring; +- RefactoringFeedback feedback; +- RefactoringStatus initStatus; +- RefactoringStatus optionsStatus; +- RefactoringStatus finalStatus; +- +- Request request; +- EditGetRefactoringResult result; +- +- _RefactoringManager(this.server, this.searchEngine) { +- _reset(); +- } +- +- /** +- * Returns `true` if a response for the current request has not yet been sent. +- */ +- bool get hasPendingRequest => request != null; +- +- bool get _hasFatalError { +- return initStatus.hasFatalError || +- optionsStatus.hasFatalError || +- finalStatus.hasFatalError; +- } +- +- /** +- * Checks if [refactoring] requires options. +- */ +- bool get _requiresOptions { +- return refactoring is ExtractLocalRefactoring || +- refactoring is ExtractMethodRefactoring || +- refactoring is InlineMethodRefactoring || +- refactoring is RenameRefactoring; +- } +- +- /** +- * Cancels processing of the current request and cleans up. +- */ +- void cancel() { +- if (request != null) { +- server.sendResponse(new Response.refactoringRequestCancelled(request)); +- request = null; +- } +- _reset(); +- } +- +- void getRefactoring(Request _request) { +- // prepare for processing the request +- request = _request; +- result = new EditGetRefactoringResult( +- EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST); +- // process the request +- var params = new EditGetRefactoringParams.fromRequest(_request); +- +- if (params.kind != null) { +- server.options.analytics +- ?.sendEvent('refactor', params.kind.name.toLowerCase()); +- } +- +- runZoned(() async { +- await _init(params.kind, params.file, params.offset, params.length); +- if (initStatus.hasFatalError) { +- feedback = null; +- _sendResultResponse(); +- return; +- } +- // set options +- if (_requiresOptions) { +- if (params.options == null) { +- optionsStatus = new RefactoringStatus(); +- _sendResultResponse(); +- return; +- } +- optionsStatus = _setOptions(params); +- if (_hasFatalError) { +- _sendResultResponse(); +- return; +- } +- } +- // done if just validation +- if (params.validateOnly) { +- finalStatus = new RefactoringStatus(); +- _sendResultResponse(); +- return; +- } +- // simulate an exception +- if (test_simulateRefactoringException_final) { +- throw 'A simulated refactoring exception - final.'; +- } +- // validation and create change +- finalStatus = await refactoring.checkFinalConditions(); +- _checkForReset_afterFinalConditions(); +- if (_hasFatalError) { +- _sendResultResponse(); +- return; +- } +- // simulate an exception +- if (test_simulateRefactoringException_change) { +- throw 'A simulated refactoring exception - change.'; +- } +- // create change +- result.change = await refactoring.createChange(); +- result.potentialEdits = nullIfEmpty(refactoring.potentialEditIds); +- _checkForReset_afterCreateChange(); +- _sendResultResponse(); +- }, onError: (exception, stackTrace) { +- if (exception is _ResetError) { +- cancel(); +- } else { +- server.instrumentationService.logException(exception, stackTrace); +- server.sendResponse( +- new Response.serverError(_request, exception, stackTrace)); +- } +- _reset(); +- }); +- } +- +- void _checkForReset_afterCreateChange() { +- if (test_simulateRefactoringReset_afterCreateChange) { +- _reset(); +- } +- if (refactoring == null) { +- throw new _ResetError(); +- } +- } +- +- void _checkForReset_afterFinalConditions() { +- if (test_simulateRefactoringReset_afterFinalConditions) { +- _reset(); +- } +- if (refactoring == null) { +- throw new _ResetError(); +- } +- } +- +- void _checkForReset_afterInitialConditions() { +- if (test_simulateRefactoringReset_afterInitialConditions) { +- _reset(); +- } +- if (refactoring == null) { +- throw new _ResetError(); +- } +- } +- +- /** +- * Initializes this context to perform a refactoring with the specified +- * parameters. The existing [Refactoring] is reused or created as needed. +- */ +- Future _init( +- RefactoringKind kind, String file, int offset, int length) async { +- // check if we can continue with the existing Refactoring instance +- if (this.kind == kind && +- this.file == file && +- this.offset == offset && +- this.length == length) { +- return; +- } +- _reset(); +- _resetOnAnalysisSetChanged(); +- this.kind = kind; +- this.file = file; +- this.offset = offset; +- this.length = length; +- // simulate an exception +- if (test_simulateRefactoringException_init) { +- throw 'A simulated refactoring exception - init.'; +- } +- // create a new Refactoring instance +- if (kind == RefactoringKind.CONVERT_GETTER_TO_METHOD) { +- Element element = await server.getElementAtOffset(file, offset); +- if (element != null) { +- if (element is ExecutableElement) { +- refactoring = new ConvertGetterToMethodRefactoring( +- searchEngine, server.getAstProvider(file), element); +- } +- } +- } +- if (kind == RefactoringKind.CONVERT_METHOD_TO_GETTER) { +- Element element = await server.getElementAtOffset(file, offset); +- if (element != null) { +- if (element is ExecutableElement) { +- refactoring = new ConvertMethodToGetterRefactoring( +- searchEngine, server.getAstProvider(file), element); +- } +- } +- } +- if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) { +- CompilationUnit unit = await server.getResolvedCompilationUnit(file); +- if (unit != null) { +- refactoring = new ExtractLocalRefactoring(unit, offset, length); +- feedback = new ExtractLocalVariableFeedback( +- [], [], [], +- coveringExpressionOffsets: [], +- coveringExpressionLengths: []); +- } +- } +- if (kind == RefactoringKind.EXTRACT_METHOD) { +- CompilationUnit unit = await server.getResolvedCompilationUnit(file); +- if (unit != null) { +- refactoring = new ExtractMethodRefactoring( +- searchEngine, server.getAstProvider(file), unit, offset, length); +- feedback = new ExtractMethodFeedback(offset, length, '', [], +- false, [], [], []); +- } +- } +- if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) { +- CompilationUnit unit = await server.getResolvedCompilationUnit(file); +- if (unit != null) { +- refactoring = new InlineLocalRefactoring( +- searchEngine, server.getAstProvider(file), unit, offset); +- } +- } +- if (kind == RefactoringKind.INLINE_METHOD) { +- CompilationUnit unit = await server.getResolvedCompilationUnit(file); +- if (unit != null) { +- refactoring = new InlineMethodRefactoring( +- searchEngine, server.getAstProvider(file), unit, offset); +- } +- } +- if (kind == RefactoringKind.MOVE_FILE) { +- // TODO(brianwilkerson) Re-implement this refactoring under the new analysis driver +-// _resetOnAnalysisStarted(); +-// ContextSourcePair contextSource = server.getContextSourcePair(file); +-// engine.AnalysisContext context = contextSource.context; +-// Source source = contextSource.source; +-// refactoring = new MoveFileRefactoring( +-// server.resourceProvider, searchEngine, context, source, file); +- } +- if (kind == RefactoringKind.RENAME) { +- AstNode node = await server.getNodeAtOffset(file, offset); +- Element element = server.getElementOfNode(node); +- if (node != null && element != null) { +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- // climb from "Class" in "new Class.named()" to "Class.named" +- if (node.parent is TypeName && node.parent.parent is ConstructorName) { +- ConstructorName constructor = node.parent.parent; +- node = constructor; +- element = constructor.staticElement; +- } +- // do create the refactoring +- refactoring = new RenameRefactoring( +- searchEngine, server.getAstProvider(file), element); +- feedback = +- new RenameFeedback(node.offset, node.length, 'kind', 'oldName'); +- } +- } +- if (refactoring == null) { +- initStatus = +- new RefactoringStatus.fatal('Unable to create a refactoring'); +- return; +- } +- // check initial conditions +- initStatus = await refactoring.checkInitialConditions(); +- _checkForReset_afterInitialConditions(); +- if (refactoring is ExtractLocalRefactoring) { +- ExtractLocalRefactoring refactoring = this.refactoring; +- ExtractLocalVariableFeedback feedback = this.feedback; +- feedback.names = refactoring.names; +- feedback.offsets = refactoring.offsets; +- feedback.lengths = refactoring.lengths; +- feedback.coveringExpressionOffsets = +- refactoring.coveringExpressionOffsets; +- feedback.coveringExpressionLengths = +- refactoring.coveringExpressionLengths; +- } +- if (refactoring is ExtractMethodRefactoring) { +- ExtractMethodRefactoring refactoring = this.refactoring; +- ExtractMethodFeedback feedback = this.feedback; +- feedback.canCreateGetter = refactoring.canCreateGetter; +- feedback.returnType = refactoring.returnType; +- feedback.names = refactoring.names; +- feedback.parameters = refactoring.parameters; +- feedback.offsets = refactoring.offsets; +- feedback.lengths = refactoring.lengths; +- } +- if (refactoring is InlineLocalRefactoring) { +- InlineLocalRefactoring refactoring = this.refactoring; +- if (!initStatus.hasFatalError) { +- feedback = new InlineLocalVariableFeedback( +- refactoring.variableName, refactoring.referenceCount); +- } +- } +- if (refactoring is InlineMethodRefactoring) { +- InlineMethodRefactoring refactoring = this.refactoring; +- if (!initStatus.hasFatalError) { +- feedback = new InlineMethodFeedback( +- refactoring.methodName, refactoring.isDeclaration, +- className: refactoring.className); +- } +- } +- if (refactoring is RenameRefactoring) { +- RenameRefactoring refactoring = this.refactoring; +- RenameFeedback feedback = this.feedback; +- feedback.elementKindName = refactoring.elementKindName; +- feedback.oldName = refactoring.oldName; +- } +- } +- +- void _reset() { +- test_resetCount++; +- kind = null; +- offset = null; +- length = null; +- refactoring = null; +- feedback = null; +- initStatus = new RefactoringStatus(); +- optionsStatus = new RefactoringStatus(); +- finalStatus = new RefactoringStatus(); +- subscriptionToReset?.cancel(); +- subscriptionToReset = null; +- } +- +- void _resetOnAnalysisSetChanged() { +- subscriptionToReset?.cancel(); +- subscriptionToReset = server.onAnalysisSetChanged.listen((_) { +- _reset(); +- }); +- } +- +- void _sendResultResponse() { +- // ignore if was cancelled +- if (request == null) { +- return; +- } +- // set feedback +- result.feedback = feedback; +- // set problems +- result.initialProblems = initStatus.problems; +- result.optionsProblems = optionsStatus.problems; +- result.finalProblems = finalStatus.problems; +- // send the response +- server.sendResponse(result.toResponse(request.id)); +- // done with this request +- request = null; +- result = null; +- } +- +- RefactoringStatus _setOptions(EditGetRefactoringParams params) { +- if (refactoring is ExtractLocalRefactoring) { +- ExtractLocalRefactoring extractRefactoring = refactoring; +- ExtractLocalVariableOptions extractOptions = params.options; +- extractRefactoring.name = extractOptions.name; +- extractRefactoring.extractAll = extractOptions.extractAll; +- return extractRefactoring.checkName(); +- } +- if (refactoring is ExtractMethodRefactoring) { +- ExtractMethodRefactoring extractRefactoring = this.refactoring; +- ExtractMethodOptions extractOptions = params.options; +- extractRefactoring.createGetter = extractOptions.createGetter; +- extractRefactoring.extractAll = extractOptions.extractAll; +- extractRefactoring.name = extractOptions.name; +- if (extractOptions.parameters != null) { +- extractRefactoring.parameters = extractOptions.parameters; +- } +- extractRefactoring.returnType = extractOptions.returnType; +- return extractRefactoring.checkName(); +- } +- if (refactoring is InlineMethodRefactoring) { +- InlineMethodRefactoring inlineRefactoring = this.refactoring; +- InlineMethodOptions inlineOptions = params.options; +- inlineRefactoring.deleteSource = inlineOptions.deleteSource; +- inlineRefactoring.inlineAll = inlineOptions.inlineAll; +- return new RefactoringStatus(); +- } +- if (refactoring is RenameRefactoring) { +- RenameRefactoring renameRefactoring = refactoring; +- RenameOptions renameOptions = params.options; +- renameRefactoring.newName = renameOptions.newName; +- return renameRefactoring.checkNewName(); +- } +- return new RefactoringStatus(); +- } +-} +- +-/** +- * [_RefactoringManager] throws instances of this class internally to stop +- * processing in a manager that was reset. +- */ +-class _ResetError {} +diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart +deleted file mode 100644 +index 60bfdae9c11..00000000000 +--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart ++++ /dev/null +@@ -1,164 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/computer/computer_closingLabels.dart'; +-import 'package:analysis_server/src/computer/computer_highlights.dart'; +-import 'package:analysis_server/src/computer/computer_highlights2.dart'; +-import 'package:analysis_server/src/computer/computer_outline.dart'; +-import 'package:analysis_server/src/computer/computer_overrides.dart'; +-import 'package:analysis_server/src/domains/analysis/implemented_dart.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-Future scheduleImplementedNotification( +- AnalysisServer server, Iterable files) async { +- SearchEngine searchEngine = server.searchEngine; +- if (searchEngine == null) { +- return; +- } +- for (String file in files) { +- CompilationUnit unit = server.getCachedAnalysisResult(file)?.unit; +- CompilationUnitElement unitElement = unit?.element; +- if (unitElement != null) { +- try { +- ImplementedComputer computer = +- new ImplementedComputer(searchEngine, unitElement); +- await computer.compute(); +- var params = new protocol.AnalysisImplementedParams( +- file, computer.classes, computer.members); +- server.sendNotification(params.toNotification()); +- } catch (exception, stackTrace) { +- server.sendServerErrorNotification( +- 'Failed to send analysis.implemented notification.', +- exception, +- stackTrace); +- } +- } +- } +-} +- +-void sendAnalysisNotificationAnalyzedFiles(AnalysisServer server) { +- _sendNotification(server, () { +- Set analyzedFiles = server.driverMap.values +- .map((driver) => driver.knownFiles) +- .expand((files) => files) +- .toSet(); +- +- // Exclude *.yaml files because IDEA Dart plugin attempts to index +- // all the files in folders which contain analyzed files. +- analyzedFiles.removeWhere((file) => file.endsWith('.yaml')); +- +- Set prevAnalyzedFiles = server.prevAnalyzedFiles; +- if (prevAnalyzedFiles != null && +- prevAnalyzedFiles.length == analyzedFiles.length && +- prevAnalyzedFiles.difference(analyzedFiles).isEmpty) { +- // No change to the set of analyzed files. No need to send another +- // notification. +- return; +- } +- server.prevAnalyzedFiles = analyzedFiles; +- protocol.AnalysisAnalyzedFilesParams params = +- new protocol.AnalysisAnalyzedFilesParams(analyzedFiles.toList()); +- server.sendNotification(params.toNotification()); +- }); +-} +- +-void sendAnalysisNotificationClosingLabels(AnalysisServer server, String file, +- LineInfo lineInfo, CompilationUnit dartUnit) { +- _sendNotification(server, () { +- var labels = +- new DartUnitClosingLabelsComputer(lineInfo, dartUnit).compute(); +- var params = new protocol.AnalysisClosingLabelsParams(file, labels); +- server.sendNotification(params.toNotification()); +- }); +-} +- +-void sendAnalysisNotificationFlushResults( +- AnalysisServer server, List files) { +- _sendNotification(server, () { +- if (files != null && files.isNotEmpty) { +- var params = new protocol.AnalysisFlushResultsParams(files); +- server.sendNotification(params.toNotification()); +- } +- }); +-} +- +-void sendAnalysisNotificationHighlights( +- AnalysisServer server, String file, CompilationUnit dartUnit) { +- _sendNotification(server, () { +- List regions; +- if (server.options.useAnalysisHighlight2) { +- regions = new DartUnitHighlightsComputer2(dartUnit).compute(); +- } else { +- regions = new DartUnitHighlightsComputer(dartUnit).compute(); +- } +- var params = new protocol.AnalysisHighlightsParams(file, regions); +- server.sendNotification(params.toNotification()); +- }); +-} +- +-void sendAnalysisNotificationOutline(AnalysisServer server, String file, +- LineInfo lineInfo, SourceKind sourceKind, CompilationUnit dartUnit) { +- _sendNotification(server, () { +- // compute FileKind +- protocol.FileKind fileKind = protocol.FileKind.LIBRARY; +- if (sourceKind == SourceKind.LIBRARY) { +- fileKind = protocol.FileKind.LIBRARY; +- } else if (sourceKind == SourceKind.PART) { +- fileKind = protocol.FileKind.PART; +- } +- // compute library name +- String libraryName = _computeLibraryName(dartUnit); +- // compute Outline +- var computer = new DartUnitOutlineComputer(file, lineInfo, dartUnit); +- protocol.Outline outline = computer.compute(); +- // send notification +- var params = new protocol.AnalysisOutlineParams(file, fileKind, outline, +- libraryName: libraryName); +- server.sendNotification(params.toNotification()); +- }); +-} +- +-void sendAnalysisNotificationOverrides( +- AnalysisServer server, String file, CompilationUnit dartUnit) { +- _sendNotification(server, () { +- var overrides = new DartUnitOverridesComputer(dartUnit).compute(); +- var params = new protocol.AnalysisOverridesParams(file, overrides); +- server.sendNotification(params.toNotification()); +- }); +-} +- +-String _computeLibraryName(CompilationUnit unit) { +- for (Directive directive in unit.directives) { +- if (directive is LibraryDirective && directive.name != null) { +- return directive.name.name; +- } +- } +- for (Directive directive in unit.directives) { +- if (directive is PartOfDirective && directive.libraryName != null) { +- return directive.libraryName.name; +- } +- } +- return null; +-} +- +-/** +- * Runs the given notification producing function [f], catching exceptions. +- */ +-void _sendNotification(AnalysisServer server, f()) { +- ServerPerformanceStatistics.notices.makeCurrentWhile(() { +- try { +- f(); +- } catch (exception, stackTrace) { +- server.sendServerErrorNotification( +- 'Failed to send notification', exception, stackTrace); +- } +- }); +-} +diff --git a/pkg/analysis_server/lib/src/plugin/notification_manager.dart b/pkg/analysis_server/lib/src/plugin/notification_manager.dart +deleted file mode 100644 +index 9aad4d53e86..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/notification_manager.dart ++++ /dev/null +@@ -1,365 +0,0 @@ +-// 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:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analysis_server/src/channel/channel.dart'; +-import 'package:analysis_server/src/plugin/result_collector.dart'; +-import 'package:analysis_server/src/plugin/result_converter.dart'; +-import 'package:analysis_server/src/plugin/result_merger.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +- +-/** +- * The object used to coordinate the results of notifications from the analysis +- * server and multiple plugins. +- */ +-class NotificationManager { +- /** +- * The identifier used to identify results from the server. +- */ +- static const String serverId = 'server'; +- +- /** +- * The channel used to send notifications to the client. +- */ +- final ServerCommunicationChannel channel; +- +- /** +- * The resource provider used to get the path context. +- */ +- final ResourceProvider provider; +- +- /** +- * A list of the paths of files and directories that are included for analysis. +- */ +- List includedPaths = []; +- +- /** +- * A list of the paths of files and directories that are excluded from +- * analysis. +- */ +- List excludedPaths = []; +- +- /** +- * The current set of subscriptions to which the client has subscribed. +- */ +- Map> currentSubscriptions = +- >{}; +- +- /** +- * The collector being used to collect the analysis errors from the plugins. +- */ +- ResultCollector> errors; +- +- /** +- * The collector being used to collect the folding regions from the plugins. +- */ +- ResultCollector> folding; +- +- /** +- * The collector being used to collect the highlight regions from the plugins. +- */ +- ResultCollector> highlights; +- +- /** +- * The collector being used to collect the navigation parameters from the +- * plugins. +- */ +- ResultCollector navigation; +- +- /** +- * The collector being used to collect the occurrences from the plugins. +- */ +- ResultCollector> occurrences; +- +- /** +- * The collector being used to collect the outlines from the plugins. +- */ +- ResultCollector> outlines; +- +- /** +- * The object used to convert results. +- */ +- ResultConverter converter = new ResultConverter(); +- +- /** +- * The object used to merge results. +- */ +- ResultMerger merger = new ResultMerger(); +- +- /** +- * Initialize a newly created notification manager. +- */ +- NotificationManager(this.channel, this.provider) { +- errors = new ResultCollector>(serverId, +- predicate: _isIncluded); +- folding = new ResultCollector>(serverId); +- highlights = new ResultCollector>(serverId); +- navigation = new ResultCollector(serverId); +- occurrences = new ResultCollector>(serverId); +- outlines = new ResultCollector>(serverId); +- } +- +- /** +- * Handle the given [notification] from the plugin with the given [pluginId]. +- */ +- void handlePluginNotification( +- String pluginId, plugin.Notification notification) { +- String event = notification.event; +- switch (event) { +- case plugin.ANALYSIS_NOTIFICATION_ERRORS: +- plugin.AnalysisErrorsParams params = +- new plugin.AnalysisErrorsParams.fromNotification(notification); +- recordAnalysisErrors(pluginId, params.file, params.errors); +- break; +- case plugin.ANALYSIS_NOTIFICATION_FOLDING: +- plugin.AnalysisFoldingParams params = +- new plugin.AnalysisFoldingParams.fromNotification(notification); +- recordFoldingRegions(pluginId, params.file, params.regions); +- break; +- case plugin.ANALYSIS_NOTIFICATION_HIGHLIGHTS: +- plugin.AnalysisHighlightsParams params = +- new plugin.AnalysisHighlightsParams.fromNotification(notification); +- recordHighlightRegions(pluginId, params.file, params.regions); +- break; +- case plugin.ANALYSIS_NOTIFICATION_NAVIGATION: +- plugin.AnalysisNavigationParams params = +- new plugin.AnalysisNavigationParams.fromNotification(notification); +- recordNavigationParams(pluginId, params.file, +- converter.convertAnalysisNavigationParams(params)); +- break; +- case plugin.ANALYSIS_NOTIFICATION_OCCURRENCES: +- plugin.AnalysisOccurrencesParams params = +- new plugin.AnalysisOccurrencesParams.fromNotification(notification); +- recordOccurrences(pluginId, params.file, params.occurrences); +- break; +- case plugin.ANALYSIS_NOTIFICATION_OUTLINE: +- plugin.AnalysisOutlineParams params = +- new plugin.AnalysisOutlineParams.fromNotification(notification); +- recordOutlines(pluginId, params.file, params.outline); +- break; +- case plugin.PLUGIN_NOTIFICATION_ERROR: +- plugin.PluginErrorParams params = +- new plugin.PluginErrorParams.fromNotification(notification); +- // TODO(brianwilkerson) There is no indication for the client as to the +- // fact that the error came from a plugin, let alone which plugin it +- // came from. We should consider whether we really want to send them to +- // the client. +- channel.sendNotification(new server.ServerErrorParams( +- params.isFatal, params.message, params.stackTrace) +- .toNotification()); +- break; +- } +- } +- +- /** +- * Record error information from the plugin with the given [pluginId] for the +- * file with the given [filePath]. +- */ +- void recordAnalysisErrors( +- String pluginId, String filePath, List errorData) { +- if (errors.isCollectingFor(filePath)) { +- errors.putResults(filePath, pluginId, errorData); +- List> unmergedErrors = errors.getResults(filePath); +- List mergedErrors = +- merger.mergeAnalysisErrors(unmergedErrors); +- channel.sendNotification( +- new server.AnalysisErrorsParams(filePath, mergedErrors) +- .toNotification()); +- } +- } +- +- /** +- * Record folding information from the plugin with the given [pluginId] for +- * the file with the given [filePath]. +- */ +- void recordFoldingRegions( +- String pluginId, String filePath, List foldingData) { +- if (folding.isCollectingFor(filePath)) { +- folding.putResults(filePath, pluginId, foldingData); +- List> unmergedFolding = folding.getResults(filePath); +- List mergedFolding = +- merger.mergeFoldingRegions(unmergedFolding); +- channel.sendNotification( +- new server.AnalysisFoldingParams(filePath, mergedFolding) +- .toNotification()); +- } +- } +- +- /** +- * Record highlight information from the plugin with the given [pluginId] for +- * the file with the given [filePath]. +- */ +- void recordHighlightRegions( +- String pluginId, String filePath, List highlightData) { +- if (highlights.isCollectingFor(filePath)) { +- highlights.putResults(filePath, pluginId, highlightData); +- List> unmergedHighlights = +- highlights.getResults(filePath); +- List mergedHighlights = +- merger.mergeHighlightRegions(unmergedHighlights); +- channel.sendNotification( +- new server.AnalysisHighlightsParams(filePath, mergedHighlights) +- .toNotification()); +- } +- } +- +- /** +- * Record navigation information from the plugin with the given [pluginId] for +- * the file with the given [filePath]. +- */ +- void recordNavigationParams(String pluginId, String filePath, +- server.AnalysisNavigationParams navigationData) { +- if (navigation.isCollectingFor(filePath)) { +- navigation.putResults(filePath, pluginId, navigationData); +- List unmergedNavigations = +- navigation.getResults(filePath); +- server.AnalysisNavigationParams mergedNavigations = +- merger.mergeNavigation(unmergedNavigations); +- channel.sendNotification(mergedNavigations.toNotification()); +- } +- } +- +- /** +- * Record occurrences information from the plugin with the given [pluginId] +- * for the file with the given [filePath]. +- */ +- void recordOccurrences( +- String pluginId, String filePath, List occurrencesData) { +- if (occurrences.isCollectingFor(filePath)) { +- occurrences.putResults(filePath, pluginId, occurrencesData); +- List> unmergedOccurrences = +- occurrences.getResults(filePath); +- List mergedOccurrences = +- merger.mergeOccurrences(unmergedOccurrences); +- channel.sendNotification( +- new server.AnalysisOccurrencesParams(filePath, mergedOccurrences) +- .toNotification()); +- } +- } +- +- /** +- * Record outline information from the plugin with the given [pluginId] for +- * the file with the given [filePath]. +- */ +- void recordOutlines( +- String pluginId, String filePath, List outlineData) { +- if (outlines.isCollectingFor(filePath)) { +- outlines.putResults(filePath, pluginId, outlineData); +- List> unmergedOutlines = outlines.getResults(filePath); +- List mergedOutlines = merger.mergeOutline(unmergedOutlines); +- channel.sendNotification(new server.AnalysisOutlineParams( +- filePath, server.FileKind.LIBRARY, mergedOutlines[0]) +- .toNotification()); +- } +- } +- +- /** +- * Set the lists of [included] and [excluded] files. +- */ +- void setAnalysisRoots(List included, List excluded) { +- includedPaths = included; +- excludedPaths = excluded; +- } +- +- /** +- * Set the current subscriptions to the given set of [newSubscriptions]. +- */ +- void setSubscriptions( +- Map> newSubscriptions) { +- /** +- * Return the collector associated with the given service, or `null` if the +- * service is not handled by this manager. +- */ +- ResultCollector collectorFor(server.AnalysisService service) { +- switch (service) { +- case server.AnalysisService.FOLDING: +- return folding; +- case server.AnalysisService.HIGHLIGHTS: +- return highlights; +- case server.AnalysisService.NAVIGATION: +- return navigation; +- case server.AnalysisService.OCCURRENCES: +- return occurrences; +- case server.AnalysisService.OUTLINE: +- return outlines; +- } +- return null; +- } +- +- Set services = +- new HashSet(); +- services.addAll(currentSubscriptions.keys); +- services.addAll(newSubscriptions.keys); +- services.forEach((server.AnalysisService service) { +- ResultCollector collector = collectorFor(service); +- if (collector != null) { +- Set currentPaths = currentSubscriptions[service]; +- Set newPaths = newSubscriptions[service]; +- if (currentPaths == null) { +- if (newPaths == null) { +- // This should not happen. +- return; +- } +- // All of the [newPaths] need to be added. +- newPaths.forEach((String filePath) { +- collector.startCollectingFor(filePath); +- }); +- } else if (newPaths == null) { +- // All of the [currentPaths] need to be removed. +- currentPaths.forEach((String filePath) { +- collector.stopCollectingFor(filePath); +- }); +- } else { +- // Compute the difference of the two sets. +- newPaths.forEach((String filePath) { +- if (!currentPaths.contains(filePath)) { +- collector.startCollectingFor(filePath); +- } +- }); +- currentPaths.forEach((String filePath) { +- if (!newPaths.contains(filePath)) { +- collector.stopCollectingFor(filePath); +- } +- }); +- } +- } +- }); +- currentSubscriptions = newSubscriptions; +- } +- +- /** +- * Return `true` if errors should be collected for the file with the given +- * [path] (because it is being analyzed). +- */ +- bool _isIncluded(String path) { +- bool isIncluded() { +- for (String includedPath in includedPaths) { +- if (provider.pathContext.isWithin(includedPath, path) || +- provider.pathContext.equals(includedPath, path)) { +- return true; +- } +- } +- return false; +- } +- +- bool isExcluded() { +- for (String excludedPath in excludedPaths) { +- if (provider.pathContext.isWithin(excludedPath, path)) { +- return true; +- } +- } +- return false; +- } +- +- // TODO(brianwilkerson) Return false if error notifications are globally +- // disabled. +- return isIncluded() && !isExcluded(); +- } +-} +diff --git a/pkg/analysis_server/lib/src/plugin/plugin_locator.dart b/pkg/analysis_server/lib/src/plugin/plugin_locator.dart +deleted file mode 100644 +index ba53ab348cb..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/plugin_locator.dart ++++ /dev/null +@@ -1,105 +0,0 @@ +-// 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 'package:analyzer/file_system/file_system.dart'; +- +-/** +- * An object used to locate a plugin within a package. +- */ +-class PluginLocator { +- /** +- * The key used in the `pubspec.yaml` file to specify the location of the +- * analysis plugin. +- */ +- static const String analyzerPluginKey = 'analyzer_plugin'; +- +- /** +- * The name of the default plugin directory, located within the `tools` +- * directory. +- */ +- static const String defaultPluginFolderName = 'analyzer_plugin'; +- +- /** +- * The name of the `pubspec.yaml` file. +- */ +- static const String pubspecFileName = 'pubspec.yaml'; +- +- /** +- * The name of the `tools` directory, in which the default plugin directory is +- * located. +- */ +- static const String toolsFolderName = 'tools'; +- +- /** +- * The resource provider used to access the file system. +- */ +- final ResourceProvider resourceProvider; +- +- final Map pluginMap = {}; +- +- /** +- * Initialize a newly created plugin locator to use the given +- * [resourceProvider] to access the file system. +- */ +- PluginLocator(this.resourceProvider); +- +- /** +- * Given the root directory of a package (the [packageRoot]), return the path +- * to the plugin associated with the package, or `null` if there is no plugin +- * associated with the package. +- * +- * This will look first in the `pubspec.yaml` file in the package root for a +- * top-level key (`analysis_plugin`) indicating where the plugin is located. +- * The value associated with the key is expected to be the path of the plugin +- * relative to the package root. If the directory exists, the it is returned. +- * +- * If the key is not defined in the `pubspec.yaml` file, or if the directory +- * given does not exist, then this method will look for the directory +- * `tools/analysis_plugin` relative to the package root. If the directory +- * exists, then it is returned. +- * +- * This method does not validate the content of the plugin directory before +- * returning it. +- */ +- String findPlugin(String packageRoot) { +- return pluginMap.putIfAbsent(packageRoot, () => _findPlugin(packageRoot)); +- } +- +- /** +- * The implementation of [findPlugin]. +- */ +- String _findPlugin(String packageRoot) { +- Folder packageFolder = resourceProvider.getFolder(packageRoot); +- // TODO(brianwilkerson) Re-enable this after deciding how we want to deal +- // with discovery of plugins. +-// import 'package:yaml/yaml.dart'; +-// File pubspecFile = packageFolder.getChildAssumingFile(pubspecFileName); +-// if (pubspecFile.exists) { +-// try { +-// YamlDocument document = loadYamlDocument(pubspecFile.readAsStringSync(), +-// sourceUrl: pubspecFile.toUri()); +-// YamlNode contents = document.contents; +-// if (contents is YamlMap) { +-// String pluginPath = contents[analyzerPluginKey]; +-// if (pluginPath != null) { +-// Folder pluginFolder = +-// packageFolder.getChildAssumingFolder(pluginPath); +-// if (pluginFolder.exists) { +-// return pluginFolder.path; +-// } +-// } +-// } +-// } catch (exception) { +-// // If we can't read the file, or if it isn't valid YAML, then ignore it. +-// } +-// } +- Folder pluginFolder = packageFolder +- .getChildAssumingFolder(toolsFolderName) +- .getChildAssumingFolder(defaultPluginFolderName); +- if (pluginFolder.exists) { +- return pluginFolder.path; +- } +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart +deleted file mode 100644 +index cf271e5a00f..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart ++++ /dev/null +@@ -1,1102 +0,0 @@ +-// 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 'dart:convert'; +-import 'dart:io' show Platform, Process, ProcessResult; +- +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analyzer/context/context_root.dart' as analyzer; +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/generated/bazel.dart'; +-import 'package:analyzer/src/generated/gn.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/workspace.dart'; +-import 'package:analyzer/src/util/glob.dart'; +-import 'package:analyzer_plugin/channel/channel.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/src/channel/isolate_channel.dart'; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'; +-import 'package:convert/convert.dart'; +-import 'package:crypto/crypto.dart'; +-import 'package:meta/meta.dart'; +-import 'package:path/path.dart' as path; +-import 'package:watcher/watcher.dart' as watcher; +-import 'package:yaml/yaml.dart'; +- +-/** +- * Information about a plugin that is built-in. +- */ +-class BuiltInPluginInfo extends PluginInfo { +- /** +- * The entry point function that will be executed in the plugin's isolate. +- */ +- final EntryPoint entryPoint; +- +- @override +- final String pluginId; +- +- /** +- * Initialize a newly created built-in plugin. +- */ +- BuiltInPluginInfo( +- this.entryPoint, +- this.pluginId, +- NotificationManager notificationManager, +- InstrumentationService instrumentationService) +- : super(notificationManager, instrumentationService); +- +- @override +- ServerCommunicationChannel _createChannel() { +- return new ServerIsolateChannel.builtIn( +- entryPoint, pluginId, instrumentationService); +- } +-} +- +-/** +- * Information about a plugin that was discovered. +- */ +-class DiscoveredPluginInfo extends PluginInfo { +- /** +- * The path to the root directory of the definition of the plugin on disk (the +- * directory containing the 'pubspec.yaml' file and the 'bin' directory). +- */ +- final String path; +- +- /** +- * The path to the 'plugin.dart' file that will be executed in an isolate. +- */ +- final String executionPath; +- +- /** +- * The path to the '.packages' file used to control the resolution of +- * 'package:' URIs. +- */ +- final String packagesPath; +- +- /** +- * Initialize the newly created information about a plugin. +- */ +- DiscoveredPluginInfo( +- this.path, +- this.executionPath, +- this.packagesPath, +- NotificationManager notificationManager, +- InstrumentationService instrumentationService) +- : super(notificationManager, instrumentationService); +- +- @override +- bool get canBeStarted => executionPath != null; +- +- @override +- String get pluginId => path; +- +- @override +- ServerCommunicationChannel _createChannel() { +- return new ServerIsolateChannel.discovered( +- new Uri.file(executionPath, windows: Platform.isWindows), +- new Uri.file(packagesPath, windows: Platform.isWindows), +- instrumentationService); +- } +-} +- +-/** +- * An indication of a problem with the execution of a plugin that occurs prior +- * to the execution of the plugin's entry point in an isolate. +- */ +-class PluginException implements Exception { +- /** +- * A message describing the problem. +- */ +- final String message; +- +- /** +- * Initialize a newly created exception to have the given [message]. +- */ +- PluginException(this.message); +- +- @override +- String toString() => message; +-} +- +-/** +- * Information about a single plugin. +- */ +-abstract class PluginInfo { +- /** +- * The object used to manage the receiving and sending of notifications. +- */ +- final NotificationManager notificationManager; +- +- /** +- * The instrumentation service that is being used by the analysis server. +- */ +- final InstrumentationService instrumentationService; +- +- /** +- * The context roots that are currently using the results produced by the +- * plugin. +- */ +- Set contextRoots = new HashSet(); +- +- /** +- * The current execution of the plugin, or `null` if the plugin is not +- * currently being executed. +- */ +- PluginSession currentSession; +- +- /** +- * The exception that occurred that prevented the plugin from being started, +- * or `null` if there was no exception (possibly because no attempt has yet +- * been made to start the plugin). +- */ +- CaughtException exception; +- +- /** +- * Initialize the newly created information about a plugin. +- */ +- PluginInfo(this.notificationManager, this.instrumentationService); +- +- /** +- * Return `true` if this plugin can be started, or `false` if there is a +- * reason why it cannot be started. For example, a plugin cannot be started if +- * there was an error with a previous attempt to start running it or if the +- * plugin is not correctly configured. +- */ +- bool get canBeStarted => true; +- +- /** +- * Return the data known about this plugin. +- */ +- PluginData get data => +- new PluginData(pluginId, currentSession?.name, currentSession?.version); +- +- /** +- * Return the id of this plugin, used to identify the plugin to users. +- */ +- String get pluginId; +- +- /** +- * Add the given [contextRoot] to the set of context roots being analyzed by +- * this plugin. +- */ +- void addContextRoot(analyzer.ContextRoot contextRoot) { +- if (contextRoots.add(contextRoot)) { +- _updatePluginRoots(); +- } +- } +- +- /** +- * Add the given context [roots] to the set of context roots being analyzed by +- * this plugin. +- */ +- void addContextRoots(Iterable roots) { +- bool changed = false; +- for (analyzer.ContextRoot contextRoot in roots) { +- if (contextRoots.add(contextRoot)) { +- changed = true; +- } +- } +- if (changed) { +- _updatePluginRoots(); +- } +- } +- +- /** +- * Return `true` if at least one of the context roots being analyzed contains +- * the file with the given [filePath]. +- */ +- bool isAnalyzing(String filePath) { +- for (var contextRoot in contextRoots) { +- if (contextRoot.containsFile(filePath)) { +- return true; +- } +- } +- return false; +- } +- +- /** +- * Remove the given [contextRoot] from the set of context roots being analyzed +- * by this plugin. +- */ +- void removeContextRoot(analyzer.ContextRoot contextRoot) { +- if (contextRoots.remove(contextRoot)) { +- _updatePluginRoots(); +- } +- } +- +- /** +- * If the plugin is currently running, send a request based on the given +- * [params] to the plugin. If the plugin is not running, the request will +- * silently be dropped. +- */ +- void sendRequest(RequestParams params) { +- currentSession?.sendRequest(params); +- } +- +- /** +- * Start a new isolate that is running the plugin. Return the state object +- * used to interact with the plugin, or `null` if the plugin could not be run. +- */ +- Future start(String byteStorePath, String sdkPath) async { +- if (currentSession != null) { +- throw new StateError('Cannot start a plugin that is already running.'); +- } +- currentSession = new PluginSession(this); +- bool isRunning = await currentSession.start(byteStorePath, sdkPath); +- if (!isRunning) { +- currentSession = null; +- } +- return currentSession; +- } +- +- /** +- * Request that the plugin shutdown. +- */ +- Future stop() { +- if (currentSession == null) { +- throw new StateError('Cannot stop a plugin that is not running.'); +- } +- Future doneFuture = currentSession.stop(); +- currentSession = null; +- return doneFuture; +- } +- +- /** +- * Create and return the channel used to communicate with the server. +- */ +- ServerCommunicationChannel _createChannel(); +- +- /** +- * Update the context roots that the plugin should be analyzing. +- */ +- void _updatePluginRoots() { +- if (currentSession != null) { +- AnalysisSetContextRootsParams params = new AnalysisSetContextRootsParams( +- contextRoots +- .map((analyzer.ContextRoot contextRoot) => new ContextRoot( +- contextRoot.root, contextRoot.exclude, +- optionsFile: contextRoot.optionsFilePath)) +- .toList()); +- currentSession.sendRequest(params); +- } +- } +-} +- +-/** +- * An object used to manage the currently running plugins. +- */ +-class PluginManager { +- /** +- * A table, keyed by both a plugin and a request method, to a list of the +- * times that it took the plugin to return a response to requests with the +- * method. +- */ +- static Map>> pluginResponseTimes = +- >>{}; +- +- /** +- * The resource provider used to access the file system. +- */ +- final ResourceProvider resourceProvider; +- +- /** +- * The absolute path of the directory containing the on-disk byte store, or +- * `null` if there is no on-disk store. +- */ +- final String byteStorePath; +- +- /** +- * The absolute path of the directory containing the SDK. +- */ +- final String sdkPath; +- +- /** +- * The object used to manage the receiving and sending of notifications. +- */ +- final NotificationManager notificationManager; +- +- /** +- * The instrumentation service that is being used by the analysis server. +- */ +- final InstrumentationService instrumentationService; +- +- /** +- * A table mapping the paths of plugins to information about those plugins. +- */ +- Map _pluginMap = {}; +- +- /** +- * The parameters for the last 'analysis.setPriorityFiles' request that was +- * received from the client. Because plugins are lazily discovered, this needs +- * to be retained so that it can be sent after a plugin has been started. +- */ +- AnalysisSetPriorityFilesParams _analysisSetPriorityFilesParams; +- +- /** +- * The parameters for the last 'analysis.setSubscriptions' request that was +- * received from the client. Because plugins are lazily discovered, this needs +- * to be retained so that it can be sent after a plugin has been started. +- */ +- AnalysisSetSubscriptionsParams _analysisSetSubscriptionsParams; +- +- /** +- * The current state of content overlays. Because plugins are lazily +- * discovered, the state needs to be retained so that it can be sent after a +- * plugin has been started. +- */ +- Map _overlayState = {}; +- +- /** +- * Initialize a newly created plugin manager. The notifications from the +- * running plugins will be handled by the given [notificationManager]. +- */ +- PluginManager(this.resourceProvider, this.byteStorePath, this.sdkPath, +- this.notificationManager, this.instrumentationService); +- +- /** +- * Return a list of all of the plugins that are currently known. +- */ +- @visibleForTesting +- List get plugins => _pluginMap.values.toList(); +- +- /** +- * Add the plugin with the given [path] to the list of plugins that should be +- * used when analyzing code for the given [contextRoot]. If the plugin had not +- * yet been started, then it will be started by this method. +- */ +- Future addPluginToContextRoot( +- analyzer.ContextRoot contextRoot, String path) async { +- PluginInfo plugin = _pluginMap[path]; +- bool isNew = plugin == null; +- if (isNew) { +- List pluginPaths; +- try { +- pluginPaths = pathsFor(path); +- } catch (exception, stackTrace) { +- plugin = new DiscoveredPluginInfo( +- path, null, null, notificationManager, instrumentationService); +- plugin.exception = new CaughtException(exception, stackTrace); +- _pluginMap[path] = plugin; +- return; +- } +- plugin = new DiscoveredPluginInfo(path, pluginPaths[0], pluginPaths[1], +- notificationManager, instrumentationService); +- _pluginMap[path] = plugin; +- if (pluginPaths[0] != null) { +- try { +- PluginSession session = await plugin.start(byteStorePath, sdkPath); +- session?.onDone?.then((_) { +- _pluginMap.remove(path); +- }); +- } catch (exception, stackTrace) { +- // Record the exception (for debugging purposes) and record the fact +- // that we should not try to communicate with the plugin. +- plugin.exception = new CaughtException(exception, stackTrace); +- isNew = false; +- } +- } +- } +- plugin.addContextRoot(contextRoot); +- if (isNew) { +- if (_analysisSetSubscriptionsParams != null) { +- plugin.sendRequest(_analysisSetSubscriptionsParams); +- } +- if (_overlayState.isNotEmpty) { +- plugin.sendRequest(new AnalysisUpdateContentParams(_overlayState)); +- } +- if (_analysisSetPriorityFilesParams != null) { +- plugin.sendRequest(_analysisSetPriorityFilesParams); +- } +- } +- } +- +- /** +- * Broadcast a request built from the given [params] to all of the plugins +- * that are currently associated with the given [contextRoot]. Return a list +- * containing futures that will complete when each of the plugins have sent a +- * response. +- */ +- Map> broadcastRequest(RequestParams params, +- {analyzer.ContextRoot contextRoot}) { +- List plugins = pluginsForContextRoot(contextRoot); +- Map> responseMap = +- >{}; +- for (PluginInfo plugin in plugins) { +- responseMap[plugin] = plugin.currentSession?.sendRequest(params); +- } +- return responseMap; +- } +- +- /** +- * Broadcast the given [watchEvent] to all of the plugins that are analyzing +- * in contexts containing the file associated with the event. Return a list +- * containing futures that will complete when each of the plugins have sent a +- * response. +- */ +- Future>> broadcastWatchEvent( +- watcher.WatchEvent watchEvent) async { +- String filePath = watchEvent.path; +- +- /** +- * Return `true` if the given glob [pattern] matches the file being watched. +- */ +- bool matches(String pattern) => +- new Glob(resourceProvider.pathContext.separator, pattern) +- .matches(filePath); +- +- WatchEvent event = null; +- List> responses = >[]; +- for (PluginInfo plugin in _pluginMap.values) { +- PluginSession session = plugin.currentSession; +- if (session != null && +- plugin.isAnalyzing(filePath) && +- session.interestingFiles != null && +- session.interestingFiles.any(matches)) { +- // The list of interesting file globs is `null` if the plugin has not +- // yet responded to the plugin.versionCheck request. If that happens +- // then the plugin hasn't had a chance to analyze anything yet, and +- // hence it does not needed to get watch events. +- event ??= _convertWatchEvent(watchEvent); +- AnalysisHandleWatchEventsParams params = +- new AnalysisHandleWatchEventsParams([event]); +- responses.add(session.sendRequest(params)); +- } +- } +- return responses; +- } +- +- /** +- * Return the execution path and .packages path associated with the plugin at +- * the given [path]. Throw a [PluginException] if there is a problem that +- * prevents the plugin from being executing. +- */ +- @visibleForTesting +- List pathsFor(String pluginPath) { +- Folder pluginFolder = resourceProvider.getFolder(pluginPath); +- File pubspecFile = pluginFolder.getChildAssumingFile('pubspec.yaml'); +- if (!pubspecFile.exists) { +- // If there's no pubspec file, then we don't need to copy the package +- // because we won't be running pub. +- return _computePaths(pluginFolder); +- } +- Workspace workspace = +- BazelWorkspace.find(resourceProvider, pluginFolder.path) ?? +- GnWorkspace.find(resourceProvider, pluginFolder.path); +- if (workspace != null) { +- // Similarly, we won't be running pub if we're in a workspace because +- // there is exactly one version of each package. +- return _computePaths(pluginFolder, workspace: workspace); +- } +- // +- // Copy the plugin directory to a unique subdirectory of the plugin +- // manager's state location. The subdirectory's name is selected such that +- // it will be invariant across sessions, reducing the number of times the +- // plugin will need to be copied and pub will need to be run. +- // +- Folder stateFolder = resourceProvider.getStateLocation('.plugin_manager'); +- String stateName = _uniqueDirectoryName(pluginPath); +- Folder parentFolder = stateFolder.getChildAssumingFolder(stateName); +- if (parentFolder.exists) { +- Folder executionFolder = +- parentFolder.getChildAssumingFolder(pluginFolder.shortName); +- return _computePaths(executionFolder); +- } +- Folder executionFolder = pluginFolder.copyTo(parentFolder); +- return _computePaths(executionFolder, runPub: true); +- } +- +- /** +- * Return a list of all of the plugins that are currently associated with the +- * given [contextRoot]. +- */ +- @visibleForTesting +- List pluginsForContextRoot(analyzer.ContextRoot contextRoot) { +- if (contextRoot == null) { +- return _pluginMap.values.toList(); +- } +- List plugins = []; +- for (PluginInfo plugin in _pluginMap.values) { +- if (plugin.contextRoots.contains(contextRoot)) { +- plugins.add(plugin); +- } +- } +- return plugins; +- } +- +- /** +- * Record a failure to run the plugin associated with the host package with +- * the given [hostPackageName]. The failure is described by the [message], and +- * is expected to have occurred before a path could be computed, and hence +- * before [addPluginToContextRoot] could be invoked. +- */ +- void recordPluginFailure(String hostPackageName, String message) { +- try { +- throw new PluginException(message); +- } catch (exception, stackTrace) { +- String pluginPath = +- path.join(hostPackageName, 'tools', 'analyzer_plugin'); +- DiscoveredPluginInfo plugin = new DiscoveredPluginInfo( +- pluginPath, null, null, notificationManager, instrumentationService); +- plugin.exception = new CaughtException(exception, stackTrace); +- _pluginMap[pluginPath] = plugin; +- } +- } +- +- /** +- * The given [contextRoot] is no longer being analyzed. +- */ +- void removedContextRoot(analyzer.ContextRoot contextRoot) { +- List plugins = _pluginMap.values.toList(); +- for (PluginInfo plugin in plugins) { +- plugin.removeContextRoot(contextRoot); +- if (plugin is DiscoveredPluginInfo && plugin.contextRoots.isEmpty) { +- _pluginMap.remove(plugin.path); +- plugin.stop(); +- } +- } +- } +- +- /** +- * Restart all currently running plugins. +- */ +- Future restartPlugins() async { +- for (PluginInfo plugin in _pluginMap.values.toList()) { +- if (plugin.currentSession != null) { +- // +- // Capture needed state. +- // +- Set contextRoots = plugin.contextRoots; +- String path = plugin.pluginId; +- // +- // Stop the plugin. +- // +- await plugin.stop(); +- // +- // Restart the plugin. +- // +- _pluginMap[path] = plugin; +- PluginSession session = await plugin.start(byteStorePath, sdkPath); +- session?.onDone?.then((_) { +- _pluginMap.remove(path); +- }); +- // +- // Re-initialize the plugin. +- // +- plugin.addContextRoots(contextRoots); +- if (_analysisSetSubscriptionsParams != null) { +- plugin.sendRequest(_analysisSetSubscriptionsParams); +- } +- if (_overlayState.isNotEmpty) { +- plugin.sendRequest(new AnalysisUpdateContentParams(_overlayState)); +- } +- if (_analysisSetPriorityFilesParams != null) { +- plugin.sendRequest(_analysisSetPriorityFilesParams); +- } +- } +- } +- } +- +- /** +- * Send a request based on the given [params] to existing plugins to set the +- * priority files to those specified by the [params]. As a side-effect, record +- * the parameters so that they can be sent to any newly started plugins. +- */ +- void setAnalysisSetPriorityFilesParams( +- AnalysisSetPriorityFilesParams params) { +- for (PluginInfo plugin in _pluginMap.values) { +- plugin.sendRequest(params); +- } +- _analysisSetPriorityFilesParams = params; +- } +- +- /** +- * Send a request based on the given [params] to existing plugins to set the +- * subscriptions to those specified by the [params]. As a side-effect, record +- * the parameters so that they can be sent to any newly started plugins. +- */ +- void setAnalysisSetSubscriptionsParams( +- AnalysisSetSubscriptionsParams params) { +- for (PluginInfo plugin in _pluginMap.values) { +- plugin.sendRequest(params); +- } +- _analysisSetSubscriptionsParams = params; +- } +- +- /** +- * Send a request based on the given [params] to existing plugins to set the +- * content overlays to those specified by the [params]. As a side-effect, +- * update the overlay state so that it can be sent to any newly started +- * plugins. +- */ +- void setAnalysisUpdateContentParams(AnalysisUpdateContentParams params) { +- for (PluginInfo plugin in _pluginMap.values) { +- plugin.sendRequest(params); +- } +- Map files = params.files; +- for (String file in files.keys) { +- Object overlay = files[file]; +- if (overlay is RemoveContentOverlay) { +- _overlayState.remove(file); +- } else if (overlay is AddContentOverlay) { +- _overlayState[file] = overlay; +- } else if (overlay is ChangeContentOverlay) { +- AddContentOverlay previousOverlay = _overlayState[file]; +- String newContent = +- SourceEdit.applySequence(previousOverlay.content, overlay.edits); +- _overlayState[file] = new AddContentOverlay(newContent); +- } else { +- throw new ArgumentError( +- 'Invalid class of overlay: ${overlay.runtimeType}'); +- } +- } +- } +- +- /** +- * Stop all of the plugins that are currently running. +- */ +- Future> stopAll() { +- return Future.wait(_pluginMap.values.map((PluginInfo info) => info.stop())); +- } +- +- /** +- * Compute the paths to be returned by the enclosing method given that the +- * plugin should exist in the given [pluginFolder]. +- */ +- List _computePaths(Folder pluginFolder, +- {bool runPub: false, Workspace workspace}) { +- File pluginFile = pluginFolder +- .getChildAssumingFolder('bin') +- .getChildAssumingFile('plugin.dart'); +- if (!pluginFile.exists) { +- throw new PluginException('File "${pluginFile.path}" does not exist.'); +- } +- String reason; +- File packagesFile = pluginFolder.getChildAssumingFile('.packages'); +- if (!packagesFile.exists) { +- if (runPub) { +- String vmPath = Platform.executable; +- String pubPath = path.join(path.dirname(vmPath), 'pub'); +- ProcessResult result = Process.runSync(pubPath, ['get'], +- stderrEncoding: UTF8, +- stdoutEncoding: UTF8, +- workingDirectory: pluginFolder.path); +- if (result.exitCode != 0) { +- StringBuffer buffer = new StringBuffer(); +- buffer.writeln('Failed to run pub get'); +- buffer.writeln(' pluginFolder = ${pluginFolder.path}'); +- buffer.writeln(' exitCode = ${result.exitCode}'); +- buffer.writeln(' stdout = ${result.stdout}'); +- buffer.writeln(' stderr = ${result.stderr}'); +- reason = buffer.toString(); +- instrumentationService.logError(reason); +- } +- if (!packagesFile.exists) { +- reason ??= 'File "${packagesFile.path}" does not exist.'; +- packagesFile = null; +- } +- } else if (workspace != null) { +- packagesFile = +- _createPackagesFile(pluginFolder, workspace.packageUriResolver); +- if (packagesFile == null) { +- reason = 'Could not create .packages file in workspace $workspace.'; +- } +- } else { +- reason = 'Could not create "${packagesFile.path}".'; +- packagesFile = null; +- } +- } +- if (packagesFile == null) { +- throw new PluginException(reason); +- } +- return [pluginFile.path, packagesFile.path]; +- } +- +- WatchEventType _convertChangeType(watcher.ChangeType type) { +- switch (type) { +- case watcher.ChangeType.ADD: +- return WatchEventType.ADD; +- case watcher.ChangeType.MODIFY: +- return WatchEventType.MODIFY; +- case watcher.ChangeType.REMOVE: +- return WatchEventType.REMOVE; +- default: +- throw new StateError('Unknown change type: $type'); +- } +- } +- +- WatchEvent _convertWatchEvent(watcher.WatchEvent watchEvent) { +- return new WatchEvent(_convertChangeType(watchEvent.type), watchEvent.path); +- } +- +- /** +- * Return a temporary `.packages` file that is appropriate for the plugin in +- * the given [pluginFolder]. The [packageUriResolver] is used to determine the +- * location of the packages that need to be included in the packages file. +- */ +- File _createPackagesFile( +- Folder pluginFolder, UriResolver packageUriResolver) { +- String pluginPath = pluginFolder.path; +- Folder stateFolder = resourceProvider.getStateLocation('.plugin_manager'); +- String stateName = _uniqueDirectoryName(pluginPath) + '.packages'; +- File packagesFile = stateFolder.getChildAssumingFile(stateName); +- if (!packagesFile.exists) { +- File pluginPubspec = pluginFolder.getChildAssumingFile('pubspec.yaml'); +- if (!pluginPubspec.exists) { +- return null; +- } +- +- try { +- Map visitedPackages = {}; +- path.Context context = resourceProvider.pathContext; +- visitedPackages[context.basename(pluginPath)] = +- context.join(pluginFolder.path, 'lib'); +- List pubspecFiles = []; +- pubspecFiles.add(pluginPubspec); +- while (pubspecFiles.isNotEmpty) { +- File pubspecFile = pubspecFiles.removeLast(); +- for (String packageName in _readDependecies(pubspecFile)) { +- if (!visitedPackages.containsKey(packageName)) { +- Uri uri = Uri.parse('package:$packageName/$packageName.dart'); +- Source packageSource = packageUriResolver.resolveAbsolute(uri); +- String libDirPath = context.dirname(packageSource.fullName); +- visitedPackages[packageName] = libDirPath; +- String pubspecPath = +- context.join(context.dirname(libDirPath), 'pubspec.yaml'); +- pubspecFiles.add(resourceProvider.getFile(pubspecPath)); +- } +- } +- } +- +- StringBuffer buffer = new StringBuffer(); +- visitedPackages.forEach((String name, String path) { +- buffer.write(name); +- buffer.write(':'); +- buffer.writeln(new Uri.file(path)); +- }); +- packagesFile.writeAsStringSync(buffer.toString()); +- } catch (exception) { +- // If we are not able to produce a .packages file, return null so that +- // callers will not try to load the plugin. +- return null; +- } +- } +- return packagesFile; +- } +- +- /** +- * Return the names of packages that are listed as dependencies in the given +- * [pubspecFile]. +- */ +- Iterable _readDependecies(File pubspecFile) { +- YamlDocument document = loadYamlDocument(pubspecFile.readAsStringSync(), +- sourceUrl: pubspecFile.toUri()); +- YamlNode contents = document.contents; +- if (contents is YamlMap) { +- YamlNode dependencies = contents['dependencies']; +- if (dependencies is YamlMap) { +- return dependencies.keys; +- } +- } +- return const []; +- } +- +- /** +- * Return a hex-encoded MD5 signature of the given file [path]. +- */ +- String _uniqueDirectoryName(String path) { +- List bytes = md5.convert(path.codeUnits).bytes; +- return hex.encode(bytes); +- } +- +- /** +- * Record the fact that the given [plugin] responded to a request with the +- * given [method] in the given [time]. +- */ +- static void recordResponseTime(PluginInfo plugin, String method, int time) { +- pluginResponseTimes +- .putIfAbsent(plugin, () => >{}) +- .putIfAbsent(method, () => []) +- .add(time); +- } +-} +- +-/** +- * Information about the execution a single plugin. +- */ +-@visibleForTesting +-class PluginSession { +- /** +- * The maximum number of milliseconds that server should wait for a response +- * from a plugin before deciding that the plugin is hung. +- */ +- static const Duration MAXIMUM_RESPONSE_TIME = const Duration(minutes: 2); +- +- /** +- * The length of time to wait after sending a 'plugin.shutdown' request before +- * a failure to terminate will cause the isolate to be killed. +- */ +- static const Duration WAIT_FOR_SHUTDOWN_DURATION = +- const Duration(seconds: 10); +- +- /** +- * The information about the plugin being executed. +- */ +- final PluginInfo info; +- +- /** +- * The completer used to signal when the plugin has stopped. +- */ +- Completer pluginStoppedCompleter = new Completer(); +- +- /** +- * The channel used to communicate with the plugin. +- */ +- ServerCommunicationChannel channel; +- +- /** +- * The index of the next request to be sent to the plugin. +- */ +- int requestId = 0; +- +- /** +- * A table mapping the id's of requests to the functions used to handle the +- * response to those requests. +- */ +- Map pendingRequests = {}; +- +- /** +- * A boolean indicating whether the plugin is compatible with the version of +- * the plugin API being used by this server. +- */ +- bool isCompatible = true; +- +- /** +- * The contact information to include when reporting problems related to the +- * plugin. +- */ +- String contactInfo; +- +- /** +- * The glob patterns of files that the plugin is interested in knowing about. +- */ +- List interestingFiles; +- +- /** +- * The name to be used when reporting problems related to the plugin. +- */ +- String name; +- +- /** +- * The version number to be used when reporting problems related to the +- * plugin. +- */ +- String version; +- +- /** +- * Initialize the newly created information about the execution of a plugin. +- */ +- PluginSession(this.info); +- +- /** +- * Return the next request id, encoded as a string and increment the id so +- * that a different result will be returned on each invocation. +- */ +- String get nextRequestId => (requestId++).toString(); +- +- /** +- * Return a future that will complete when the plugin has stopped. +- */ +- Future get onDone => pluginStoppedCompleter.future; +- +- /** +- * Handle the given [notification]. +- */ +- void handleNotification(Notification notification) { +- if (notification.event == PLUGIN_NOTIFICATION_ERROR) { +- PluginErrorParams params = +- new PluginErrorParams.fromNotification(notification); +- if (params.isFatal) { +- info.stop(); +- stop(); +- } +- } +- info.notificationManager +- .handlePluginNotification(info.pluginId, notification); +- } +- +- /** +- * Handle the fact that the plugin has stopped. +- */ +- void handleOnDone() { +- if (channel != null) { +- channel.close(); +- channel = null; +- } +- pluginStoppedCompleter.complete(null); +- } +- +- /** +- * Handle the fact that an unhandled error has occurred in the plugin. +- */ +- void handleOnError(List errorPair) { +- StackTrace stackTrace = new StackTrace.fromString(errorPair[1]); +- info.exception = +- new CaughtException(new PluginException(errorPair[0]), stackTrace); +- info.instrumentationService +- .logPluginException(info.data, errorPair[0], stackTrace); +- } +- +- /** +- * Handle a [response] from the plugin by completing the future that was +- * created when the request was sent. +- */ +- void handleResponse(Response response) { +- _PendingRequest requestData = pendingRequests.remove(response.id); +- int responseTime = new DateTime.now().millisecondsSinceEpoch; +- int duration = responseTime - requestData.requestTime; +- PluginManager.recordResponseTime(info, requestData.method, duration); +- Completer completer = requestData.completer; +- if (completer != null) { +- completer.complete(response); +- } +- } +- +- /** +- * Return `true` if there are any requests that have not been responded to +- * within the maximum allowed amount of time. +- */ +- bool isNonResponsive() { +- // TODO(brianwilkerson) Figure out when to invoke this method in order to +- // identify non-responsive plugins and kill them. +- int cutOffTime = new DateTime.now().millisecondsSinceEpoch - +- MAXIMUM_RESPONSE_TIME.inMilliseconds; +- for (var requestData in pendingRequests.values) { +- if (requestData.requestTime < cutOffTime) { +- return true; +- } +- } +- return false; +- } +- +- /** +- * Send a request, based on the given [parameters]. Return a future that will +- * complete when a response is received. +- */ +- Future sendRequest(RequestParams parameters) { +- if (channel == null) { +- throw new StateError( +- 'Cannot send a request to a plugin that has stopped.'); +- } +- String id = nextRequestId; +- Completer completer = new Completer(); +- int requestTime = new DateTime.now().millisecondsSinceEpoch; +- Request request = parameters.toRequest(id); +- pendingRequests[id] = +- new _PendingRequest(request.method, requestTime, completer); +- channel.sendRequest(request); +- return completer.future; +- } +- +- /** +- * Start a new isolate that is running this plugin. The plugin will be sent +- * the given [byteStorePath]. Return `true` if the plugin is compatible and +- * running. +- */ +- Future start(String byteStorePath, String sdkPath) async { +- if (channel != null) { +- throw new StateError('Cannot start a plugin that is already running.'); +- } +- if (byteStorePath == null || byteStorePath.isEmpty) { +- throw new StateError('Missing byte store path'); +- } +- if (!isCompatible) { +- info.exception = new CaughtException( +- new PluginException('Plugin is not compatible.'), null); +- return false; +- } +- if (!info.canBeStarted) { +- info.exception = new CaughtException( +- new PluginException('Plugin cannot be started.'), null); +- return false; +- } +- channel = info._createChannel(); +- await channel.listen(handleResponse, handleNotification, +- onDone: handleOnDone, onError: handleOnError); +- if (channel == null) { +- // If there is an error when starting the isolate, the channel will invoke +- // handleOnDone, which will cause `channel` to be set to `null`. +- info.exception ??= new CaughtException( +- new PluginException('Unrecorded error while starting the plugin.'), +- null); +- return false; +- } +- Response response = await sendRequest(new PluginVersionCheckParams( +- byteStorePath ?? '', sdkPath, '1.0.0-alpha.0')); +- PluginVersionCheckResult result = +- new PluginVersionCheckResult.fromResponse(response); +- isCompatible = result.isCompatible; +- contactInfo = result.contactInfo; +- interestingFiles = result.interestingFiles; +- name = result.name; +- version = result.version; +- if (!isCompatible) { +- sendRequest(new PluginShutdownParams()); +- info.exception = new CaughtException( +- new PluginException('Plugin is not compatible.'), null); +- return false; +- } +- return true; +- } +- +- /** +- * Request that the plugin shutdown. +- */ +- Future stop() { +- if (channel == null) { +- throw new StateError('Cannot stop a plugin that is not running.'); +- } +- sendRequest(new PluginShutdownParams()); +- new Future.delayed(WAIT_FOR_SHUTDOWN_DURATION, () { +- if (channel != null) { +- channel.kill(); +- channel = null; +- } +- }); +- return pluginStoppedCompleter.future; +- } +-} +- +-/** +- * Information about a request that has been sent but for which a response has +- * not yet been received. +- */ +-class _PendingRequest { +- /** +- * The method of the request. +- */ +- final String method; +- +- /** +- * The time at which the request was sent to the plugin. +- */ +- final int requestTime; +- +- /** +- * The completer that will be used to complete the future when the response is +- * received from the plugin. +- */ +- final Completer completer; +- +- /** +- * Initialize a pending request. +- */ +- _PendingRequest(this.method, this.requestTime, this.completer); +-} +diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart +deleted file mode 100644 +index 8de5ea28564..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart ++++ /dev/null +@@ -1,134 +0,0 @@ +-// 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 'package:analysis_server/src/plugin/plugin_locator.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/util/absolute_path.dart'; +-import 'package:front_end/src/base/source.dart'; +-import 'package:path/src/context.dart'; +- +-/** +- * An object that watches the results produced by analysis drivers to identify +- * references to previously unseen packages and, if those packages have plugins +- * associated with them, causes the plugin to be associated with the driver's +- * context root (which in turn might cause the plugin to be started). +- */ +-class PluginWatcher implements DriverWatcher { +- /** +- * The resource provider used to access the file system. +- */ +- final ResourceProvider resourceProvider; +- +- /** +- * The object managing the execution of plugins. +- */ +- final PluginManager manager; +- +- /** +- * The object used to locate plugins within packages. +- */ +- final PluginLocator _locator; +- +- /** +- * A table mapping analysis drivers to information related to the driver. +- */ +- Map _driverInfo = +- {}; +- +- /** +- * Initialize a newly created plugin watcher. +- */ +- PluginWatcher(this.resourceProvider, this.manager) +- : _locator = new PluginLocator(resourceProvider); +- +- /** +- * The context manager has just added the given analysis [driver]. This method +- * must be called before the driver has been allowed to perform any analysis. +- */ +- void addedDriver(AnalysisDriver driver, ContextRoot contextRoot) { +- _driverInfo[driver] = new _DriverInfo( +- contextRoot, [contextRoot.root, _getSdkPath(driver)]); +- List enabledPlugins = driver.analysisOptions.enabledPluginNames; +- for (String hostPackageName in enabledPlugins) { +- // +- // Determine whether the package exists and defines a plugin. +- // +- String uri = 'package:$hostPackageName/$hostPackageName.dart'; +- Source source = driver.sourceFactory.forUri(uri); +- if (source == null) { +- manager.recordPluginFailure(hostPackageName, +- 'Could not resolve "$uri" in ${contextRoot.root}.'); +- } else { +- Context context = resourceProvider.pathContext; +- String packageRoot = context.dirname(context.dirname(source.fullName)); +- String pluginPath = _locator.findPlugin(packageRoot); +- if (pluginPath == null) { +- manager.recordPluginFailure( +- hostPackageName, 'Could not find plugin in "$packageRoot".'); +- } else { +- // +- // Add the plugin to the context root. +- // +- // TODO(brianwilkerson) Do we need to wait for the plugin to be added? +- // If we don't, then tests don't have any way to know when to expect +- // that the list of plugins has been updated. +- manager.addPluginToContextRoot(contextRoot, pluginPath); +- } +- } +- } +- } +- +- /** +- * The context manager has just removed the given analysis [driver]. +- */ +- void removedDriver(AnalysisDriver driver) { +- _DriverInfo info = _driverInfo[driver]; +- if (info == null) { +- throw new StateError('Cannot remove a driver that was not added'); +- } +- manager.removedContextRoot(info.contextRoot); +- _driverInfo.remove(driver); +- } +- +- /** +- * Return the path to the root of the SDK being used by the given analysis +- * [driver]. +- */ +- String _getSdkPath(AnalysisDriver driver) { +- AbsolutePathContext context = resourceProvider.absolutePathContext; +- String sdkRoot = driver.sourceFactory.forUri('dart:core').fullName; +- while (context.basename(sdkRoot) != 'lib') { +- String parent = context.dirname(sdkRoot); +- if (parent == sdkRoot) { +- break; +- } +- sdkRoot = parent; +- } +- return sdkRoot; +- } +-} +- +-/** +- * Information related to an analysis driver. +- */ +-class _DriverInfo { +- /** +- * The context root representing the context being analyzed by the driver. +- */ +- final ContextRoot contextRoot; +- +- /** +- * A list of the absolute paths of directories inside of which we have already +- * searched for a plugin. +- */ +- final List packageRoots; +- +- /** +- * Initialize a newly created information holder. +- */ +- _DriverInfo(this.contextRoot, this.packageRoots); +-} +diff --git a/pkg/analysis_server/lib/src/plugin/request_converter.dart b/pkg/analysis_server/lib/src/plugin/request_converter.dart +deleted file mode 100644 +index 5caa0710217..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/request_converter.dart ++++ /dev/null +@@ -1,46 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analysis_server/src/protocol/protocol_internal.dart' as server; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +- +-/** +- * An object used to convert between similar objects defined by both the plugin +- * protocol and the server protocol. +- */ +-class RequestConverter { +- plugin.AnalysisService convertAnalysisService( +- server.AnalysisService service) { +- return new plugin.AnalysisService(service.name); +- } +- +- plugin.AnalysisSetPriorityFilesParams convertAnalysisSetPriorityFilesParams( +- server.AnalysisSetPriorityFilesParams params) { +- return new plugin.AnalysisSetPriorityFilesParams(params.files); +- } +- +- plugin.AnalysisSetSubscriptionsParams convertAnalysisSetSubscriptionsParams( +- server.AnalysisSetSubscriptionsParams params) { +- Map> serverSubscriptions = +- params.subscriptions; +- Map> pluginSubscriptions = +- >{}; +- for (server.AnalysisService service in serverSubscriptions.keys) { +- try { +- pluginSubscriptions[convertAnalysisService(service)] = +- serverSubscriptions[service]; +- } catch (exception) { +- // Ignore the exception. It indicates that the service isn't one that +- // should be passed along to plugins. +- } +- } +- return new plugin.AnalysisSetSubscriptionsParams(pluginSubscriptions); +- } +- +- plugin.AnalysisUpdateContentParams convertAnalysisUpdateContentParams( +- server.AnalysisUpdateContentParams params) { +- return new plugin.AnalysisUpdateContentParams(params.files); +- } +-} +diff --git a/pkg/analysis_server/lib/src/plugin/result_collector.dart b/pkg/analysis_server/lib/src/plugin/result_collector.dart +deleted file mode 100644 +index c2e32742943..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/result_collector.dart ++++ /dev/null +@@ -1,124 +0,0 @@ +-// 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. +- +-/** +- * A function used to determine whether results should be collected for the +- * file with the given [path]. +- */ +-typedef bool ShouldCollectPredicate(String path); +- +-/** +- * An object used to collect partial results (of type [E]) where the partial +- * results are contributed by plugins. +- */ +-class ResultCollector { +- /** +- * The id used as a plugin id for contributions from the server. +- */ +- final String serverId; +- +- /** +- * A function used to determine whether results should be collected for the +- * file whose path is passed in as an argument. +- */ +- final ShouldCollectPredicate _shouldCollect; +- +- /** +- * A multi-keyed map, where the first key is the (normalized and absolute) +- * path to the file associated with the results, and the second is the id of +- * the plugin that provided the partial results. The value is the partial +- * results contributed by the plugin for the file. +- */ +- Map> resultMap = >{}; +- +- /** +- * Initialize a newly created result manager. +- */ +- ResultCollector(this.serverId, {ShouldCollectPredicate predicate}) +- : _shouldCollect = predicate; +- +- /** +- * Clear any results that have been contributed for the file with the given +- * [filePath], but continue to collect results for the file. This is used when +- * the results for the specified file are known to be invalid, typically +- * because the content of the file has been modified. +- */ +- void clearResultsForFile(String filePath) { +- resultMap[filePath]?.clear(); +- } +- +- /** +- * Clear any results that have been contributed by the plugin with the given +- * [pluginId]. +- */ +- void clearResultsFromPlugin(String pluginId) { +- for (Map partialResults in resultMap.values) { +- partialResults.remove(pluginId); +- } +- } +- +- /** +- * Return an iterator producing the partial results that have been contributed +- * for the given [filePath]. +- */ +- List getResults(String filePath) { +- Map partialResultMap = resultMap[filePath]; +- if (partialResultMap == null) { +- return []; +- } +- List values = partialResultMap.values.toList(); +- // +- // Ensure that the server's contributions are always first in the list. +- // +- E serverContributions = partialResultMap[serverId]; +- if (serverContributions != null && values.remove(serverContributions)) { +- values.insert(0, serverContributions); +- } +- return values; +- } +- +- /** +- * Return `true` if this collector is collecting results associated with the +- * given [filePath]. +- */ +- bool isCollectingFor(String filePath) { +- if (_shouldCollect != null) { +- return _shouldCollect(filePath); +- } +- return resultMap.containsKey(filePath); +- } +- +- /** +- * Record the [partialResults] as having been contributed for the given +- * [filePath] by the plugin with the given [pluginId]. +- */ +- void putResults(String filePath, String pluginId, E partialResults) { +- Map fileResults = resultMap[filePath]; +- if (fileResults == null) { +- if (_shouldCollect != null && _shouldCollect(filePath)) { +- resultMap[filePath] = {pluginId: partialResults}; +- } +- } else { +- fileResults[pluginId] = partialResults; +- } +- } +- +- /** +- * Start collecting results contributed for the file with the given +- * [filePath]. Unless the collector is told to collect results for a file, any +- * results that are contributed for that file are discarded. +- */ +- void startCollectingFor(String filePath) { +- resultMap.putIfAbsent(filePath, () => {}); +- } +- +- /** +- * Stop collecting results contributed for the file with the given [filePath]. +- * Until the collector is told to start collecting results for the file, any +- * results that are contributed for the file are discarded. +- */ +- void stopCollectingFor(String filePath) { +- resultMap.remove(filePath); +- } +-} +diff --git a/pkg/analysis_server/lib/src/plugin/result_converter.dart b/pkg/analysis_server/lib/src/plugin/result_converter.dart +deleted file mode 100644 +index 40a5d2b8035..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/result_converter.dart ++++ /dev/null +@@ -1,46 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analysis_server/src/protocol/protocol_internal.dart' as server; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +- +-/** +- * An object used to convert between similar objects defined by both the plugin +- * protocol and the server protocol. +- */ +-class ResultConverter { +- /** +- * The decoder used to decode Json representations of server objects. +- */ +- static final server.ResponseDecoder decoder = +- new server.ResponseDecoder(null); +- +- server.AnalysisErrorFixes convertAnalysisErrorFixes( +- plugin.AnalysisErrorFixes fixes) { +- List changes = fixes.fixes +- .map((plugin.PrioritizedSourceChange change) => +- convertPrioritizedSourceChange(change)) +- .toList(); +- return new server.AnalysisErrorFixes(fixes.error, fixes: changes); +- } +- +- server.AnalysisNavigationParams convertAnalysisNavigationParams( +- plugin.AnalysisNavigationParams params) { +- return new server.AnalysisNavigationParams.fromJson( +- decoder, '', params.toJson()); +- } +- +- server.EditGetRefactoringResult convertEditGetRefactoringResult( +- RefactoringKind kind, plugin.EditGetRefactoringResult result) { +- return new server.EditGetRefactoringResult.fromJson( +- new server.ResponseDecoder(kind), '', result.toJson()); +- } +- +- SourceChange convertPrioritizedSourceChange( +- plugin.PrioritizedSourceChange change) { +- return change.change; +- } +-} +diff --git a/pkg/analysis_server/lib/src/plugin/result_merger.dart b/pkg/analysis_server/lib/src/plugin/result_merger.dart +deleted file mode 100644 +index 06f08405ee2..00000000000 +--- a/pkg/analysis_server/lib/src/plugin/result_merger.dart ++++ /dev/null +@@ -1,846 +0,0 @@ +-// 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:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:meta/meta.dart'; +- +-/** +- * An object used to merge partial lists of results that were contributed by +- * plugins. +- * +- * All of the methods in this class assume that the contributions from the +- * analysis server are the first partial result in the list of partial results +- * to be merged. +- */ +-class ResultMerger { +- /** +- * Return a list of fixes composed by merging the lists of fixes in the +- * [partialResultList]. +- * +- * The resulting list of fixes will contain exactly one fix for every analysis +- * error for which there are fixes. If two or more plugins contribute the same +- * fix for a given error, the resulting list will contain duplications. +- */ +- List mergeAnalysisErrorFixes( +- List> partialResultList) { +- /** +- * Return a key encoding the unique attributes of the given [error]. +- */ +- String computeKey(AnalysisError error) { +- StringBuffer buffer = new StringBuffer(); +- buffer.write(error.location.offset); +- buffer.write(';'); +- buffer.write(error.code); +- buffer.write(';'); +- buffer.write(error.message); +- buffer.write(';'); +- buffer.write(error.correction); +- return buffer.toString(); +- } +- +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- Map fixesMap = +- {}; +- for (plugin.AnalysisErrorFixes fix in partialResultList[0]) { +- fixesMap[computeKey(fix.error)] = fix; +- } +- for (int i = 1; i < count; i++) { +- for (plugin.AnalysisErrorFixes fix in partialResultList[i]) { +- String key = computeKey(fix.error); +- plugin.AnalysisErrorFixes mergedFix = fixesMap[key]; +- if (mergedFix == null) { +- fixesMap[key] = fix; +- } else { +- // If more than two plugins contribute fixes for the same error, this +- // will result in extra copy operations. +- List mergedChanges = +- mergedFix.fixes.toList(); +- mergedChanges.addAll(fix.fixes); +- plugin.AnalysisErrorFixes copiedFix = new plugin.AnalysisErrorFixes( +- mergedFix.error, +- fixes: mergedChanges); +- fixesMap[key] = copiedFix; +- } +- } +- } +- List mergedFixes = fixesMap.values.toList(); +- for (plugin.AnalysisErrorFixes fixes in mergedFixes) { +- fixes.fixes.sort((first, second) => first.priority - second.priority); +- } +- return mergedFixes; +- } +- +- /** +- * Return a list of errors composed by merging the lists of errors in the +- * [partialResultList]. +- * +- * The resulting list will contain all of the analysis errors from all of the +- * plugins. If two or more plugins contribute the same error the resulting +- * list will contain duplications. +- */ +- List mergeAnalysisErrors( +- List> partialResultList) { +- // TODO(brianwilkerson) Consider merging duplicate errors (same code, +- // location, and messages). If we do that, we should return the logical-or +- // of the hasFix fields from the merged errors. +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedErrors = []; +- for (List partialResults in partialResultList) { +- mergedErrors.addAll(partialResults); +- } +- return mergedErrors; +- } +- +- /** +- * Return a list of suggestions composed by merging the lists of suggestions +- * in the [partialResultList]. +- * +- * The resulting list will contain all of the suggestions from all of the +- * plugins. If two or more plugins contribute the same suggestion the +- * resulting list will contain duplications. +- */ +- List mergeCompletionSuggestions( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedSuggestions = []; +- for (List partialResults in partialResultList) { +- mergedSuggestions.addAll(partialResults); +- } +- return mergedSuggestions; +- } +- +- /** +- * Return a list of regions composed by merging the lists of regions in the +- * [partialResultList]. +- * +- * The resulting list will contain all of the folding regions from all of the +- * plugins. If a plugin contributes a folding region that overlaps a region +- * from a previous plugin, the overlapping region will be omitted. (For these +- * purposes, if either region is fully contained within the other they are not +- * considered to be overlapping.) +- */ +- List mergeFoldingRegions( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedRegions = partialResultList[0].toList(); +- +- /** +- * Return `true` if the [newRegion] does not overlap any of the regions in +- * the collection of [mergedRegions]. +- */ +- bool isNonOverlapping(FoldingRegion newRegion) { +- int newStart = newRegion.offset; +- int newEnd = newStart + newRegion.length; +- for (FoldingRegion existingRegion in mergedRegions) { +- int existingStart = existingRegion.offset; +- int existingEnd = existingStart + existingRegion.length; +- if (overlaps(newStart, newEnd, existingStart, existingEnd, +- allowNesting: true)) { +- return false; +- } +- } +- return true; +- } +- +- for (int i = 1; i < count; i++) { +- List partialResults = partialResultList[i]; +- for (FoldingRegion region in partialResults) { +- if (isNonOverlapping(region)) { +- mergedRegions.add(region); +- } +- } +- } +- return mergedRegions; +- } +- +- /** +- * Return a list of regions composed by merging the lists of regions in the +- * [partialResultList]. +- * +- * The resulting list will contain all of the highlight regions from all of +- * the plugins. If two or more plugins contribute the same highlight region +- * the resulting list will contain duplications. +- */ +- List mergeHighlightRegions( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedRegions = []; +- for (List partialResults in partialResultList) { +- mergedRegions.addAll(partialResults); +- } +- return mergedRegions; +- } +- +- /** +- * Return kythe entry result parameters composed by merging the parameters in +- * the [partialResultList]. +- * +- * The resulting list will contain all of the kythe entries from all of the +- * plugins. If a plugin contributes a kythe entry that is the same as the +- * entry from a different plugin, the entry will appear twice in the list. +- */ +- KytheGetKytheEntriesResult mergeKytheEntries( +- List partialResultList) { +- List mergedEntries = []; +- Set mergedFiles = new Set(); +- for (KytheGetKytheEntriesResult partialResult in partialResultList) { +- mergedEntries.addAll(partialResult.entries); +- mergedFiles.addAll(partialResult.files); +- } +- return new KytheGetKytheEntriesResult(mergedEntries, mergedFiles.toList()); +- } +- +- /** +- * Return navigation notification parameters composed by merging the +- * parameters in the [partialResultList]. +- * +- * The resulting list will contain all of the navigation regions from all of +- * the plugins. If a plugin contributes a navigation region that overlaps a +- * region from a previous plugin, the overlapping region will be omitted. (For +- * these purposes, nested regions are considered to be overlapping.) +- */ +- AnalysisNavigationParams mergeNavigation( +- List partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return null; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- AnalysisNavigationParams base = partialResultList[0]; +- String file = base.file; +- List mergedRegions = base.regions.toList(); +- List mergedTargets = base.targets.toList(); +- List mergedFiles = base.files.toList(); +- +- /** +- * Return `true` if the [newRegion] does not overlap any of the regions in +- * the collection of [mergedRegions]. +- */ +- bool isNonOverlapping(NavigationRegion newRegion) { +- int newStart = newRegion.offset; +- int newEnd = newStart + newRegion.length; +- for (NavigationRegion mergedRegion in mergedRegions) { +- int mergedStart = mergedRegion.offset; +- int mergedEnd = mergedStart + mergedRegion.length; +- if (overlaps(newStart, newEnd, mergedStart, mergedEnd)) { +- return false; +- } +- } +- return true; +- } +- +- /** +- * Return the index of the region in the collection of [mergedRegions] that +- * covers exactly the same region as the [newRegion], or `-1` if there is no +- * such region. +- */ +- int matchingRegion(newRegion) { +- int newOffset = newRegion.offset; +- int newLength = newRegion.length; +- for (int i = 0; i < mergedRegions.length; i++) { +- NavigationRegion mergedRegion = mergedRegions[i]; +- if (newOffset == mergedRegion.offset && +- newLength == mergedRegion.length) { +- return i; +- } +- } +- return -1; +- } +- +- for (int i = 1; i < count; i++) { +- // For now we take the optimistic approach of assuming that most or all of +- // the regions will not overlap and that we therefore don't need to remove +- // any unreferenced files or targets from the lists. If that isn't true +- // then this could result in server sending more data to the client than +- // is necessary. +- AnalysisNavigationParams result = partialResultList[i]; +- List regions = result.regions; +- List targets = result.targets; +- List files = result.files; +- // +- // Merge the file data. +- // +- Map fileMap = {}; +- for (int j = 0; j < files.length; j++) { +- String file = files[j]; +- int index = mergedFiles.indexOf(file); +- if (index < 0) { +- index = mergedFiles.length; +- mergedFiles.add(file); +- } +- fileMap[j] = index; +- } +- // +- // Merge the target data. +- // +- Map targetMap = {}; +- for (int j = 0; j < targets.length; j++) { +- NavigationTarget target = targets[j]; +- int newIndex = fileMap[target.fileIndex]; +- if (target.fileIndex != newIndex) { +- target = new NavigationTarget(target.kind, newIndex, target.offset, +- target.length, target.startLine, target.startColumn); +- } +- int index = mergedTargets.indexOf(target); +- if (index < 0) { +- index = mergedTargets.length; +- mergedTargets.add(target); +- } +- targetMap[j] = index; +- } +- // +- // Merge the region data. +- // +- for (int j = 0; j < regions.length; j++) { +- NavigationRegion region = regions[j]; +- List newTargets = region.targets +- .map((int oldTarget) => targetMap[oldTarget]) +- .toList(); +- if (region.targets != newTargets) { +- region = +- new NavigationRegion(region.offset, region.length, newTargets); +- } +- int index = matchingRegion(region); +- if (index >= 0) { +- NavigationRegion mergedRegion = mergedRegions[index]; +- List mergedTargets = mergedRegion.targets; +- bool added = false; +- for (int target in region.targets) { +- if (!mergedTargets.contains(target)) { +- if (added) { +- mergedTargets.add(target); +- } else { +- // +- // This is potentially inefficient. If a merged region matches +- // regions from multiple plugins it will be copied multiple +- // times. The likelihood seems small enough to not warrant +- // optimizing this further. +- // +- mergedTargets = mergedTargets.toList(); +- mergedTargets.add(target); +- mergedRegion = new NavigationRegion( +- mergedRegion.offset, mergedRegion.length, mergedTargets); +- mergedRegions[index] = mergedRegion; +- added = true; +- } +- } +- } +- if (added) { +- mergedTargets.sort(); +- } +- } else if (isNonOverlapping(region)) { +- mergedRegions.add(region); +- } +- } +- } +- return new AnalysisNavigationParams( +- file, mergedRegions, mergedTargets, mergedFiles); +- } +- +- /** +- * Return a list of occurrences composed by merging the lists of occurrences +- * in the [partialResultList]. +- * +- * The resulting list of occurrences will contain exactly one occurrences for +- * every element for which there is at least one occurrences. If two or more +- * plugins contribute an occurrences for the same element, the resulting +- * occurrences for that element will include all of the locations from all of +- * the plugins without duplications. +- */ +- List mergeOccurrences( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- Map> elementMap = >{}; +- for (List partialResults in partialResultList) { +- for (Occurrences occurances in partialResults) { +- Element element = occurances.element; +- Set offsets = +- elementMap.putIfAbsent(element, () => new HashSet()); +- offsets.addAll(occurances.offsets); +- } +- } +- List mergedOccurrences = []; +- elementMap.forEach((Element element, Set offsets) { +- List sortedOffsets = offsets.toList(); +- sortedOffsets.sort(); +- mergedOccurrences +- .add(new Occurrences(element, sortedOffsets, element.name.length)); +- }); +- return mergedOccurrences; +- } +- +- /** +- * Return a list of outlines composed by merging the lists of outlines in the +- * [partialResultList]. +- * +- * The resulting list of outlines will contain ... +- * +- * Throw an exception if any of the outlines are associated with an element +- * that does not have a location. +- * +- * Throw an exception if any outline has children that are also children of +- * another outline. No exception is thrown if a plugin contributes a top-level +- * outline that is a child of an outline contributed by a different plugin. +- */ +- List mergeOutline(List> partialResultList) { +- /** +- * Return a key encoding the unique attributes of the given [element]. +- */ +- String computeKey(Element element) { +- Location location = element.location; +- if (location == null) { +- throw new StateError( +- 'Elements in an outline are expected to have a location'); +- } +- StringBuffer buffer = new StringBuffer(); +- buffer.write(location.offset); +- buffer.write(';'); +- buffer.write(element.kind.name); +- return buffer.toString(); +- } +- +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedOutlines = partialResultList[0].toList(); +- Map outlineMap = {}; +- Map copyMap = {}; +- +- /** +- * Add the given [outline] and all of its children to the [outlineMap]. +- */ +- void addToMap(Outline outline) { +- String key = computeKey(outline.element); +- if (outlineMap.containsKey(key)) { +- // TODO(brianwilkerson) Decide how to handle this more gracefully. +- throw new StateError('Inconsistent outlines'); +- } +- outlineMap[key] = outline; +- outline.children?.forEach(addToMap); +- } +- +- /** +- * Merge the children of the [newOutline] into the list of children of the +- * [mergedOutline]. +- */ +- void mergeChildren(Outline mergedOutline, Outline newOutline) { +- for (Outline newChild in newOutline.children) { +- Outline mergedChild = outlineMap[computeKey(newChild.element)]; +- if (mergedChild == null) { +- // The [newChild] isn't in the existing list. +- Outline copiedOutline = copyMap.putIfAbsent( +- mergedOutline, +- () => new Outline(mergedOutline.element, mergedOutline.offset, +- mergedOutline.length, +- children: mergedOutline.children.toList())); +- copiedOutline.children.add(newChild); +- addToMap(newChild); +- } else { +- mergeChildren(mergedChild, newChild); +- } +- } +- } +- +- mergedOutlines.forEach(addToMap); +- for (int i = 1; i < count; i++) { +- for (Outline outline in partialResultList[i]) { +- Outline mergedOutline = outlineMap[computeKey(outline.element)]; +- if (mergedOutline == null) { +- // The [outline] does not correspond to any previously merged outline. +- mergedOutlines.add(outline); +- addToMap(outline); +- } else { +- // The [outline] corresponds to a previously merged outline, so we +- // just need to add its children to the merged outline's children. +- mergeChildren(mergedOutline, outline); +- } +- } +- } +- +- /** +- * Perform a depth first traversal of the outline structure rooted at the +- * given [outline] item, re-building each item if any of its children have +- * been updated by the merge process. +- */ +- Outline traverse(Outline outline) { +- Outline copiedOutline = copyMap[outline]; +- bool isCopied = copiedOutline != null; +- copiedOutline ??= outline; +- List currentChildren = copiedOutline.children; +- if (currentChildren == null || currentChildren.isEmpty) { +- return outline; +- } +- List updatedChildren = +- currentChildren.map((Outline child) => traverse(child)).toList(); +- if (currentChildren != updatedChildren) { +- if (!isCopied) { +- return new Outline( +- copiedOutline.element, copiedOutline.offset, copiedOutline.length, +- children: updatedChildren); +- } +- copiedOutline.children = updatedChildren; +- return copiedOutline; +- } +- return outline; +- } +- +- for (int i = 0; i < mergedOutlines.length; i++) { +- mergedOutlines[i] = traverse(mergedOutlines[i]); +- } +- return mergedOutlines; +- } +- +- /** +- * Return a list of source changes composed by merging the lists of source +- * changes in the [partialResultList]. +- * +- * The resulting list will contain all of the source changes from all of the +- * plugins. If two or more plugins contribute the same source change the +- * resulting list will contain duplications. +- */ +- List mergePrioritizedSourceChanges( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedChanges = +- []; +- for (List partialResults +- in partialResultList) { +- mergedChanges.addAll(partialResults); +- } +- mergedChanges.sort((first, second) => first.priority - second.priority); +- return mergedChanges; +- } +- +- /** +- * Return a refactoring feedback composed by merging the refactoring feedbacks +- * in the [partialResultList]. +- * +- * The content of the resulting feedback depends on the kind of feedbacks +- * being merged. +- * +- * Throw an exception if the refactoring feedbacks are of an unhandled type. +- * +- * The feedbacks in the [partialResultList] are expected to all be of the same +- * type. If that expectation is violated, and exception might be thrown. +- */ +- RefactoringFeedback mergeRefactoringFeedbacks( +- List feedbacks) { +- int count = feedbacks.length; +- if (count == 0) { +- return null; +- } else if (count == 1) { +- return feedbacks[0]; +- } +- RefactoringFeedback first = feedbacks[0]; +- if (first is ConvertGetterToMethodFeedback) { +- // The feedbacks are empty, so there's nothing to merge. +- return first; +- } else if (first is ConvertMethodToGetterFeedback) { +- // The feedbacks are empty, so there's nothing to merge. +- return first; +- } else if (first is ExtractLocalVariableFeedback) { +- List coveringExpressionOffsets = +- first.coveringExpressionOffsets == null +- ? [] +- : first.coveringExpressionOffsets.toList(); +- List coveringExpressionLengths = +- first.coveringExpressionLengths == null +- ? [] +- : first.coveringExpressionLengths.toList(); +- List names = first.names.toList(); +- List offsets = first.offsets.toList(); +- List lengths = first.lengths.toList(); +- for (int i = 1; i < count; i++) { +- ExtractLocalVariableFeedback feedback = feedbacks[i]; +- // TODO(brianwilkerson) This doesn't ensure that the covering data is in +- // the right order and consistent. +- if (feedback.coveringExpressionOffsets != null) { +- coveringExpressionOffsets.addAll(feedback.coveringExpressionOffsets); +- } +- if (feedback.coveringExpressionLengths != null) { +- coveringExpressionLengths.addAll(feedback.coveringExpressionLengths); +- } +- for (String name in feedback.names) { +- if (!names.contains(name)) { +- names.add(name); +- } +- } +- offsets.addAll(feedback.offsets); +- lengths.addAll(feedback.lengths); +- } +- return new ExtractLocalVariableFeedback(names.toList(), offsets, lengths, +- coveringExpressionOffsets: (coveringExpressionOffsets.isEmpty +- ? null +- : coveringExpressionOffsets), +- coveringExpressionLengths: (coveringExpressionLengths.isEmpty +- ? null +- : coveringExpressionLengths)); +- } else if (first is ExtractMethodFeedback) { +- int offset = first.offset; +- int length = first.length; +- String returnType = first.returnType; +- List names = first.names.toList(); +- bool canCreateGetter = first.canCreateGetter; +- List parameters = first.parameters; +- List offsets = first.offsets.toList(); +- List lengths = first.lengths.toList(); +- for (int i = 1; i < count; i++) { +- ExtractMethodFeedback feedback = feedbacks[i]; +- if (returnType.isEmpty) { +- returnType = feedback.returnType; +- } +- for (String name in feedback.names) { +- if (!names.contains(name)) { +- names.add(name); +- } +- } +- canCreateGetter = canCreateGetter && feedback.canCreateGetter; +- // TODO(brianwilkerson) This doesn't allow plugins to add parameters. +- // TODO(brianwilkerson) This doesn't check for duplicate offsets. +- offsets.addAll(feedback.offsets); +- lengths.addAll(feedback.lengths); +- } +- return new ExtractMethodFeedback(offset, length, returnType, +- names.toList(), canCreateGetter, parameters, offsets, lengths); +- } else if (first is InlineLocalVariableFeedback) { +- int occurrences = first.occurrences; +- for (int i = 1; i < count; i++) { +- occurrences += +- (feedbacks[i] as InlineLocalVariableFeedback).occurrences; +- } +- return new InlineLocalVariableFeedback(first.name, occurrences); +- } else if (first is InlineMethodFeedback) { +- // There is nothing in the feedback that can reasonably be extended or +- // modified by other plugins. +- return first; +- } else if (first is MoveFileFeedback) { +- // The feedbacks are empty, so there's nothing to merge. +- return first; +- } else if (first is RenameFeedback) { +- // There is nothing in the feedback that can reasonably be extended or +- // modified by other plugins. +- return first; +- } +- throw new StateError( +- 'Unsupported class of refactoring feedback: ${first.runtimeType}'); +- } +- +- /** +- * Return a list of refactoring kinds composed by merging the lists of +- * refactoring kinds in the [partialResultList]. +- * +- * The resulting list will contain all of the refactoring kinds from all of +- * the plugins, but will not contain duplicate elements. +- */ +- List mergeRefactoringKinds( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- Set mergedKinds = new HashSet(); +- for (List partialResults in partialResultList) { +- mergedKinds.addAll(partialResults); +- } +- return mergedKinds.toList(); +- } +- +- /** +- * Return the result for a getRefactorings request composed by merging the +- * results in the [partialResultList]. +- * +- * The returned result will contain the concatenation of the initial, options, +- * and final problems. If two or more plugins produce the same problem, then +- * the resulting list of problems will contain duplications. +- * +- * The returned result will contain a merged list of refactoring feedbacks (as +- * defined by [mergeRefactoringFeedbacks]) and a merged list of source changes +- * (as defined by [mergeChanges]). +- * +- * The returned result will contain the concatenation of the potential edits. +- * If two or more plugins produce the same potential edit, then the resulting +- * list of potential edits will contain duplications. +- */ +- EditGetRefactoringResult mergeRefactorings( +- List partialResultList) { +- /** +- * Return the result of merging the given list of source [changes] into a +- * single source change. +- * +- * The resulting change will have the first non-null message and the first +- * non-null selection. The linked edit groups will be a concatenation of all +- * of the individual linked edit groups because there's no way to determine +- * when two such groups should be merged. The resulting list of edits will +- * be merged at the level of the file being edited, but will be a +- * concatenation of the individual edits within each file, even if multiple +- * plugins contribute duplicate or conflicting edits. +- */ +- SourceChange mergeChanges(List changes) { +- int count = changes.length; +- if (count == 0) { +- return null; +- } else if (count == 1) { +- return changes[0]; +- } +- SourceChange first = changes[0]; +- String message = first.message; +- Map editMap = {}; +- for (SourceFileEdit edit in first.edits) { +- editMap[edit.file] = edit; +- } +- List linkedEditGroups = first.linkedEditGroups.toList(); +- Position selection = first.selection; +- for (int i = 1; i < count; i++) { +- SourceChange change = changes[i]; +- for (SourceFileEdit edit in change.edits) { +- SourceFileEdit mergedEdit = editMap[edit.file]; +- if (mergedEdit == null) { +- editMap[edit.file] = edit; +- } else { +- // This doesn't detect if multiple plugins contribute the same (or +- // conflicting) edits. +- List edits = mergedEdit.edits.toList(); +- edits.addAll(edit.edits); +- editMap[edit.file] = new SourceFileEdit( +- mergedEdit.file, mergedEdit.fileStamp, +- edits: edits); +- } +- } +- linkedEditGroups.addAll(change.linkedEditGroups); +- message ??= change.message; +- selection ??= change.selection; +- } +- return new SourceChange(message, +- edits: editMap.values.toList(), +- linkedEditGroups: linkedEditGroups, +- selection: selection); +- } +- +- int count = partialResultList.length; +- if (count == 0) { +- return null; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- EditGetRefactoringResult result = partialResultList[0]; +- List initialProblems = result.initialProblems.toList(); +- List optionsProblems = result.optionsProblems.toList(); +- List finalProblems = result.finalProblems.toList(); +- List feedbacks = []; +- if (result.feedback != null) { +- feedbacks.add(result.feedback); +- } +- List changes = []; +- if (result.change != null) { +- changes.add(result.change); +- } +- List potentialEdits = result.potentialEdits.toList(); +- for (int i = 1; i < count; i++) { +- EditGetRefactoringResult result = partialResultList[1]; +- initialProblems.addAll(result.initialProblems); +- optionsProblems.addAll(result.optionsProblems); +- finalProblems.addAll(result.finalProblems); +- if (result.feedback != null) { +- feedbacks.add(result.feedback); +- } +- if (result.change != null) { +- changes.add(result.change); +- } +- potentialEdits.addAll(result.potentialEdits); +- } +- return new EditGetRefactoringResult( +- initialProblems, optionsProblems, finalProblems, +- feedback: mergeRefactoringFeedbacks(feedbacks), +- change: mergeChanges(changes), +- potentialEdits: potentialEdits); +- } +- +- /** +- * Return a list of source changes composed by merging the lists of source +- * changes in the [partialResultList]. +- * +- * The resulting list will contain all of the source changes from all of the +- * plugins. If two or more plugins contribute the same source change the +- * resulting list will contain duplications. +- */ +- List mergeSourceChanges( +- List> partialResultList) { +- int count = partialResultList.length; +- if (count == 0) { +- return []; +- } else if (count == 1) { +- return partialResultList[0]; +- } +- List mergedChanges = []; +- for (List partialResults in partialResultList) { +- mergedChanges.addAll(partialResults); +- } +- return mergedChanges; +- } +- +- /** +- * Return `true` if a region extending from [leftStart] (inclusive) to +- * [leftEnd] (exclusive) overlaps a region extending from [rightStart] +- * (inclusive) to [rightEnd] (exclusive). If [allowNesting] is `true`, then +- * the regions are allowed to overlap as long as one region is completely +- * nested within the other region. +- */ +- @visibleForTesting +- bool overlaps(int leftStart, int leftEnd, int rightStart, int rightEnd, +- {bool allowNesting: false}) { +- if (leftEnd < rightStart || leftStart > rightEnd) { +- return false; +- } +- if (!allowNesting) { +- return true; +- } +- return !((leftStart <= rightStart && rightEnd <= leftEnd) || +- (rightStart <= leftStart && leftEnd <= rightEnd)); +- } +-} +diff --git a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart +deleted file mode 100644 +index 4fe30315517..00000000000 +--- a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart ++++ /dev/null +@@ -1,336 +0,0 @@ +-// Copyright (c) 2014, 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 'dart:convert' hide JsonDecoder; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' +- show JsonDecoder; +- +-export 'package:analyzer_plugin/src/protocol/protocol_internal.dart' +- show JsonDecoder; +- +-final Map REQUEST_ID_REFACTORING_KINDS = +- new HashMap(); +- +-/** +- * Adds the given [sourceEdits] to the list in [sourceFileEdit]. +- */ +-void addAllEditsForSource( +- SourceFileEdit sourceFileEdit, Iterable edits) { +- edits.forEach(sourceFileEdit.add); +-} +- +-/** +- * Adds the given [sourceEdit] to the list in [sourceFileEdit]. +- */ +-void addEditForSource(SourceFileEdit sourceFileEdit, SourceEdit sourceEdit) { +- List edits = sourceFileEdit.edits; +- int index = 0; +- while (index < edits.length && edits[index].offset > sourceEdit.offset) { +- index++; +- } +- edits.insert(index, sourceEdit); +-} +- +-/** +- * Adds [edit] to the [FileEdit] for the given [file]. +- */ +-void addEditToSourceChange( +- SourceChange change, String file, int fileStamp, SourceEdit edit) { +- SourceFileEdit fileEdit = change.getFileEdit(file); +- if (fileEdit == null) { +- fileEdit = new SourceFileEdit(file, fileStamp); +- change.addFileEdit(fileEdit); +- } +- fileEdit.add(edit); +-} +- +-/** +- * Get the result of applying the edit to the given [code]. Access via +- * SourceEdit.apply(). +- */ +-String applyEdit(String code, SourceEdit edit) { +- if (edit.length < 0) { +- throw new RangeError('length is negative'); +- } +- return code.replaceRange(edit.offset, edit.end, edit.replacement); +-} +- +-/** +- * Get the result of applying a set of [edits] to the given [code]. Edits +- * are applied in the order they appear in [edits]. Access via +- * SourceEdit.applySequence(). +- */ +-String applySequenceOfEdits(String code, Iterable edits) { +- edits.forEach((SourceEdit edit) { +- code = edit.apply(code); +- }); +- return code; +-} +- +-/** +- * Returns the [FileEdit] for the given [file], maybe `null`. +- */ +-SourceFileEdit getChangeFileEdit(SourceChange change, String file) { +- for (SourceFileEdit fileEdit in change.edits) { +- if (fileEdit.file == file) { +- return fileEdit; +- } +- } +- return null; +-} +- +-/** +- * Compare the lists [listA] and [listB], using [itemEqual] to compare +- * list elements. +- */ +-bool listEqual( +- List listA, List listB, bool itemEqual(T1 a, T2 b)) { +- if (listA == null) { +- return listB == null; +- } +- if (listB == null) { +- return false; +- } +- if (listA.length != listB.length) { +- return false; +- } +- for (int i = 0; i < listA.length; i++) { +- if (!itemEqual(listA[i], listB[i])) { +- return false; +- } +- } +- return true; +-} +- +-/** +- * Compare the maps [mapA] and [mapB], using [valueEqual] to compare map +- * values. +- */ +-bool mapEqual(Map mapA, Map mapB, bool valueEqual(V a, V b)) { +- if (mapA == null) { +- return mapB == null; +- } +- if (mapB == null) { +- return false; +- } +- if (mapA.length != mapB.length) { +- return false; +- } +- for (var key in mapA.keys) { +- if (!mapB.containsKey(key)) { +- return false; +- } +- if (!valueEqual(mapA[key], mapB[key])) { +- return false; +- } +- } +- return true; +-} +- +-/** +- * Translate the input [map], applying [keyCallback] to all its keys, and +- * [valueCallback] to all its values. +- */ +-Map mapMap(Map map, +- {KR keyCallback(KP key), VR valueCallback(VP value)}) { +- Map result = new HashMap(); +- map.forEach((key, value) { +- KR resultKey; +- VR resultValue; +- if (keyCallback != null) { +- resultKey = keyCallback(key); +- } else { +- resultKey = key as KR; +- } +- if (valueCallback != null) { +- resultValue = valueCallback(value); +- } else { +- resultValue = value as VR; +- } +- result[resultKey] = resultValue; +- }); +- return result; +-} +- +-RefactoringProblemSeverity maxRefactoringProblemSeverity( +- RefactoringProblemSeverity a, RefactoringProblemSeverity b) { +- if (b == null) { +- return a; +- } +- if (a == null) { +- return b; +- } else if (a == RefactoringProblemSeverity.INFO) { +- return b; +- } else if (a == RefactoringProblemSeverity.WARNING) { +- if (b == RefactoringProblemSeverity.ERROR || +- b == RefactoringProblemSeverity.FATAL) { +- return b; +- } +- } else if (a == RefactoringProblemSeverity.ERROR) { +- if (b == RefactoringProblemSeverity.FATAL) { +- return b; +- } +- } +- return a; +-} +- +-/** +- * Create a [RefactoringFeedback] corresponding the given [kind]. +- */ +-RefactoringFeedback refactoringFeedbackFromJson( +- JsonDecoder jsonDecoder, String jsonPath, Object json, Map feedbackJson) { +- RefactoringKind kind = jsonDecoder.refactoringKind; +- if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) { +- return new ExtractLocalVariableFeedback.fromJson( +- jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.EXTRACT_METHOD) { +- return new ExtractMethodFeedback.fromJson(jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) { +- return new InlineLocalVariableFeedback.fromJson( +- jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.INLINE_METHOD) { +- return new InlineMethodFeedback.fromJson(jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.RENAME) { +- return new RenameFeedback.fromJson(jsonDecoder, jsonPath, json); +- } +- return null; +-} +- +-/** +- * Create a [RefactoringOptions] corresponding the given [kind]. +- */ +-RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder, +- String jsonPath, Object json, RefactoringKind kind) { +- if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) { +- return new ExtractLocalVariableOptions.fromJson( +- jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.EXTRACT_METHOD) { +- return new ExtractMethodOptions.fromJson(jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.INLINE_METHOD) { +- return new InlineMethodOptions.fromJson(jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.MOVE_FILE) { +- return new MoveFileOptions.fromJson(jsonDecoder, jsonPath, json); +- } +- if (kind == RefactoringKind.RENAME) { +- return new RenameOptions.fromJson(jsonDecoder, jsonPath, json); +- } +- return null; +-} +- +-/** +- * Type of callbacks used to decode parts of JSON objects. [jsonPath] is a +- * string describing the part of the JSON object being decoded, and [value] is +- * the part to decode. +- */ +-typedef E JsonDecoderCallback(String jsonPath, Object value); +- +-/** +- * Instances of the class [HasToJson] implement [toJson] method that returns +- * a JSON presentation. +- */ +-abstract class HasToJson { +- /** +- * Returns a JSON presentation of the object. +- */ +- Map toJson(); +-} +- +-/** +- * JsonDecoder for decoding requests. Errors are reporting by throwing a +- * [RequestFailure]. +- */ +-class RequestDecoder extends JsonDecoder { +- /** +- * The request being deserialized. +- */ +- final Request _request; +- +- RequestDecoder(this._request); +- +- RefactoringKind get refactoringKind { +- // Refactoring feedback objects should never appear in requests. +- return null; +- } +- +- @override +- dynamic mismatch(String jsonPath, String expected, [Object actual]) { +- StringBuffer buffer = new StringBuffer(); +- buffer.write('Expected to be '); +- buffer.write(expected); +- if (actual != null) { +- buffer.write('; found "'); +- buffer.write(JSON.encode(actual)); +- buffer.write('"'); +- } +- return new RequestFailure( +- new Response.invalidParameter(_request, jsonPath, buffer.toString())); +- } +- +- @override +- dynamic missingKey(String jsonPath, String key) { +- return new RequestFailure(new Response.invalidParameter( +- _request, jsonPath, 'Expected to contain key ${JSON.encode(key)}')); +- } +-} +- +-abstract class RequestParams implements HasToJson { +- /** +- * Return a request whose parameters are taken from this object and that has +- * the given [id]. +- */ +- Request toRequest(String id); +-} +- +-/** +- * JsonDecoder for decoding responses from the server. This is intended to be +- * used only for testing. Errors are reported using bare [Exception] objects. +- */ +-class ResponseDecoder extends JsonDecoder { +- final RefactoringKind refactoringKind; +- +- ResponseDecoder(this.refactoringKind); +- +- @override +- dynamic mismatch(String jsonPath, String expected, [Object actual]) { +- StringBuffer buffer = new StringBuffer(); +- buffer.write('Expected '); +- buffer.write(expected); +- if (actual != null) { +- buffer.write(' found "'); +- buffer.write(JSON.encode(actual)); +- buffer.write('"'); +- } +- buffer.write(' at '); +- buffer.write(jsonPath); +- return new Exception(buffer.toString()); +- } +- +- @override +- dynamic missingKey(String jsonPath, String key) { +- return new Exception('Missing key $key at $jsonPath'); +- } +-} +- +-/** +- * The result data associated with a response. +- */ +-abstract class ResponseResult implements HasToJson { +- /** +- * Return a response whose result data is this object for the request with the +- * given [id]. +- */ +- Response toResponse(String id); +-} +diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart +deleted file mode 100644 +index a84b950cbe6..00000000000 +--- a/pkg/analysis_server/lib/src/protocol_server.dart ++++ /dev/null +@@ -1,283 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/plugin/protocol/protocol_dart.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/services/correction/fix.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart' +- as engine; +-import 'package:analyzer/dart/ast/ast.dart' as engine; +-import 'package:analyzer/dart/ast/visitor.dart' as engine; +-import 'package:analyzer/dart/element/element.dart' as engine; +-import 'package:analyzer/dart/element/type.dart' as engine; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/source/error_processor.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart' as engine; +-import 'package:analyzer/src/error/codes.dart' as engine; +-import 'package:analyzer/src/generated/engine.dart' as engine; +-import 'package:analyzer/src/generated/source.dart' as engine; +-import 'package:analyzer/src/generated/utilities_dart.dart' as engine; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-export 'package:analysis_server/plugin/protocol/protocol_dart.dart'; +-export 'package:analysis_server/protocol/protocol.dart'; +-export 'package:analysis_server/protocol/protocol_generated.dart'; +-export 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * Returns a list of AnalysisErrors corresponding to the given list of Engine +- * errors. +- */ +-List doAnalysisError_listFromEngine( +- engine.AnalysisOptions analysisOptions, +- engine.LineInfo lineInfo, +- List errors) { +- List serverErrors = []; +- for (engine.AnalysisError error in errors) { +- ErrorProcessor processor = +- ErrorProcessor.getProcessor(analysisOptions, error); +- if (processor != null) { +- engine.ErrorSeverity severity = processor.severity; +- // Errors with null severity are filtered out. +- if (severity != null) { +- // Specified severities override. +- serverErrors +- .add(newAnalysisError_fromEngine(lineInfo, error, severity)); +- } +- } else { +- serverErrors.add(newAnalysisError_fromEngine(lineInfo, error)); +- } +- } +- return serverErrors; +-} +- +-/** +- * Adds [edit] to the file containing the given [element]. +- */ +-void doSourceChange_addElementEdit( +- SourceChange change, engine.Element element, SourceEdit edit) { +- engine.Source source = element.source; +- doSourceChange_addSourceEdit(change, source, edit); +-} +- +-/** +- * Adds [edit] for the given [source] to the [change]. +- */ +-void doSourceChange_addSourceEdit( +- SourceChange change, engine.Source source, SourceEdit edit, +- {bool isNewFile: false}) { +- String file = source.fullName; +- change.addEdit(file, isNewFile ? -1 : 0, edit); +-} +- +-String getReturnTypeString(engine.Element element) { +- if (element is engine.ExecutableElement) { +- if (element.kind == engine.ElementKind.SETTER) { +- return null; +- } else { +- return element.returnType?.toString(); +- } +- } else if (element is engine.VariableElement) { +- engine.DartType type = element.type; +- return type != null ? type.displayName : 'dynamic'; +- } else if (element is engine.FunctionTypeAliasElement) { +- return element.returnType.toString(); +- } else { +- return null; +- } +-} +- +-/** +- * Construct based on error information from the analyzer engine. +- * +- * If an [errorSeverity] is specified, it will override the one in [error]. +- */ +-AnalysisError newAnalysisError_fromEngine( +- engine.LineInfo lineInfo, engine.AnalysisError error, +- [engine.ErrorSeverity errorSeverity]) { +- engine.ErrorCode errorCode = error.errorCode; +- // prepare location +- Location location; +- { +- String file = error.source.fullName; +- int offset = error.offset; +- int length = error.length; +- int startLine = -1; +- int startColumn = -1; +- if (lineInfo != null) { +- engine.LineInfo_Location lineLocation = lineInfo.getLocation(offset); +- if (lineLocation != null) { +- startLine = lineLocation.lineNumber; +- startColumn = lineLocation.columnNumber; +- } +- } +- location = new Location(file, offset, length, startLine, startColumn); +- } +- +- // Default to the error's severity if none is specified. +- errorSeverity ??= errorCode.errorSeverity; +- +- // done +- var severity = new AnalysisErrorSeverity(errorSeverity.name); +- var type = new AnalysisErrorType(errorCode.type.name); +- String message = error.message; +- String code = errorCode.name.toLowerCase(); +- String correction = error.correction; +- bool fix = hasFix(error.errorCode); +- return new AnalysisError(severity, type, location, message, code, +- correction: correction, hasFix: fix); +-} +- +-/** +- * Create a Location based on an [engine.Element]. +- */ +-Location newLocation_fromElement(engine.Element element) { +- if (element == null || element.source == null) { +- return null; +- } +- int offset = element.nameOffset; +- int length = element.nameLength; +- if (element is engine.CompilationUnitElement || +- (element is engine.LibraryElement && offset < 0)) { +- offset = 0; +- length = 0; +- } +- engine.CompilationUnitElement unitElement = _getUnitElement(element); +- engine.SourceRange range = new engine.SourceRange(offset, length); +- return _locationForArgs(unitElement, range); +-} +- +-/** +- * Create a Location based on an [engine.SearchMatch]. +- */ +-Location newLocation_fromMatch(engine.SearchMatch match) { +- engine.CompilationUnitElement unitElement = _getUnitElement(match.element); +- return _locationForArgs(unitElement, match.sourceRange); +-} +- +-/** +- * Create a Location based on an [engine.AstNode]. +- */ +-Location newLocation_fromNode(engine.AstNode node) { +- engine.CompilationUnit unit = +- node.getAncestor((node) => node is engine.CompilationUnit); +- engine.CompilationUnitElement unitElement = unit.element; +- engine.SourceRange range = new engine.SourceRange(node.offset, node.length); +- return _locationForArgs(unitElement, range); +-} +- +-/** +- * Create a Location based on an [engine.CompilationUnit]. +- */ +-Location newLocation_fromUnit( +- engine.CompilationUnit unit, engine.SourceRange range) { +- return _locationForArgs(unit.element, range); +-} +- +-/** +- * Construct based on an element from the analyzer engine. +- */ +-OverriddenMember newOverriddenMember_fromEngine(engine.Element member) { +- Element element = convertElement(member); +- String className = member.enclosingElement.displayName; +- return new OverriddenMember(element, className); +-} +- +-/** +- * Construct based on a value from the search engine. +- */ +-SearchResult newSearchResult_fromMatch(engine.SearchMatch match) { +- SearchResultKind kind = newSearchResultKind_fromEngine(match.kind); +- Location location = newLocation_fromMatch(match); +- List path = _computePath(match.element); +- return new SearchResult(location, kind, !match.isResolved, path); +-} +- +-/** +- * Construct based on a value from the search engine. +- */ +-SearchResultKind newSearchResultKind_fromEngine(engine.MatchKind kind) { +- if (kind == engine.MatchKind.DECLARATION) { +- return SearchResultKind.DECLARATION; +- } +- if (kind == engine.MatchKind.READ) { +- return SearchResultKind.READ; +- } +- if (kind == engine.MatchKind.READ_WRITE) { +- return SearchResultKind.READ_WRITE; +- } +- if (kind == engine.MatchKind.WRITE) { +- return SearchResultKind.WRITE; +- } +- if (kind == engine.MatchKind.INVOCATION) { +- return SearchResultKind.INVOCATION; +- } +- if (kind == engine.MatchKind.REFERENCE) { +- return SearchResultKind.REFERENCE; +- } +- return SearchResultKind.UNKNOWN; +-} +- +-/** +- * Construct based on a SourceRange. +- */ +-SourceEdit newSourceEdit_range(engine.SourceRange range, String replacement, +- {String id}) { +- return new SourceEdit(range.offset, range.length, replacement, id: id); +-} +- +-List _computePath(engine.Element element) { +- List path = []; +- while (element != null) { +- path.add(convertElement(element)); +- // go up +- if (element is engine.PrefixElement) { +- // imports are library children, but they are physically in the unit +- engine.LibraryElement library = element.enclosingElement; +- element = library.definingCompilationUnit; +- } else { +- element = element.enclosingElement; +- } +- } +- return path; +-} +- +-engine.CompilationUnitElement _getUnitElement(engine.Element element) { +- if (element is engine.CompilationUnitElement) { +- return element; +- } +- if (element?.enclosingElement is engine.LibraryElement) { +- element = element.enclosingElement; +- } +- if (element is engine.LibraryElement) { +- return element.definingCompilationUnit; +- } +- for (; element != null; element = element.enclosingElement) { +- if (element is engine.CompilationUnitElement) { +- return element; +- } +- } +- return null; +-} +- +-/** +- * Creates a new [Location]. +- */ +-Location _locationForArgs( +- engine.CompilationUnitElement unitElement, engine.SourceRange range) { +- int startLine = 0; +- int startColumn = 0; +- try { +- engine.LineInfo lineInfo = unitElement.lineInfo; +- if (lineInfo != null) { +- engine.LineInfo_Location offsetLocation = +- lineInfo.getLocation(range.offset); +- startLine = offsetLocation.lineNumber; +- startColumn = offsetLocation.columnNumber; +- } +- } on AnalysisException {} +- return new Location(unitElement.source.fullName, range.offset, range.length, +- startLine, startColumn); +-} +diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart +deleted file mode 100644 +index 9934390413e..00000000000 +--- a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart ++++ /dev/null +@@ -1,86 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * An empty list returned by [CompletionContributor]s +- * when they have no suggestions to contribute. +- */ +-const EMPTY_LIST = const []; +- +-/** +- * An object used to instantiate a [CompletionContributor] instance +- * for each 'completion.getSuggestions' request. +- * Contributors should *not* be cached between requests. +- */ +-typedef CompletionContributor CompletionContributorFactory(); +- +-/** +- * [AbortCompletion] is thrown when the current completion request +- * should be aborted because either +- * the source changed since the request was made, or +- * a new completion request was received. +- */ +-class AbortCompletion {} +- +-/** +- * An object used to produce completions at a specific location within a file. +- * +- * Clients may implement this class when implementing plugins. +- */ +-abstract class CompletionContributor { +- /** +- * Return a [Future] that completes with a list of suggestions +- * for the given completion [request]. This will +- * throw [AbortCompletion] if the completion request has been aborted. +- */ +- Future> computeSuggestions( +- CompletionRequest request); +-} +- +-/** +- * The information about a requested list of completions. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class CompletionRequest { +- /** +- * Return the offset within the source at which the completion is being +- * requested. +- */ +- int get offset; +- +- /** +- * Return the resource provider associated with this request. +- */ +- ResourceProvider get resourceProvider; +- +- /** +- * The analysis result for the file in which the completion is being +- * requested. +- */ +- AnalysisResult get result; +- +- /** +- * Return the source in which the completion is being requested. +- */ +- Source get source; +- +- /** +- * Return the content of the [source] in which the completion is being +- * requested, or `null` if the content could not be accessed. +- */ +- String get sourceContents; +- +- /** +- * Throw [AbortCompletion] if the completion request has been aborted. +- */ +- void checkAborted(); +-} +diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart +deleted file mode 100644 +index 093c2da1c66..00000000000 +--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart ++++ /dev/null +@@ -1,97 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/provisional/completion/completion_core.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-export 'package:analysis_server/src/provisional/completion/completion_core.dart' +- show EMPTY_LIST; +-export 'package:analyzer_plugin/utilities/completion/relevance.dart'; +- +-/** +- * An object used to instantiate a [DartCompletionContributor] instance +- * for each 'completion.getSuggestions' request. +- * Contributors should *not* be cached between requests. +- */ +-typedef DartCompletionContributor DartCompletionContributorFactory(); +- +-/** +- * An object used to produce completions +- * at a specific location within a Dart file. +- * +- * Clients may implement this class when implementing plugins. +- */ +-abstract class DartCompletionContributor { +- /** +- * Return a [Future] that completes with a list of suggestions +- * for the given completion [request]. +- */ +- Future> computeSuggestions( +- DartCompletionRequest request); +-} +- +-/** +- * The information about a requested list of completions within a Dart file. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class DartCompletionRequest extends CompletionRequest { +- /** +- * Return the expression to the right of the "dot" or "dot dot", +- * or `null` if this is not a "dot" completion (e.g. `foo.b`). +- */ +- Expression get dotTarget; +- +- /** +- * Return `true` if free standing identifiers should be suggested +- */ +- bool get includeIdentifiers; +- +- /** +- * Return the library element which contains the unit in which the completion +- * is occurring. This may return `null` if the library cannot be determined +- * (e.g. unlinked part file). +- */ +- LibraryElement get libraryElement; +- +- /** +- * The source for the library containing the completion request. +- * This may be different from the source in which the completion is requested +- * if the completion is being requested in a part file. +- * This may be `null` if the library for a part file cannot be determined. +- */ +- Source get librarySource; +- +- /** +- * Answer the [DartType] for Object in dart:core +- */ +- DartType get objectType; +- +- /** +- * The [OpType] which describes which types of suggestions would fit the +- * request. +- */ +- OpType get opType; +- +- /** +- * Return the [SourceFactory] of the request. +- */ +- SourceFactory get sourceFactory; +- +- /** +- * Return the completion target. This determines what part of the parse tree +- * will receive the newly inserted text. +- * At a minimum, all declarations in the completion scope in [target.unit] +- * will be resolved if they can be resolved. +- */ +- CompletionTarget get target; +-} +diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart +deleted file mode 100644 +index 4b53584b495..00000000000 +--- a/pkg/analysis_server/lib/src/search/element_references.dart ++++ /dev/null +@@ -1,93 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- show SearchResult, newSearchResult_fromMatch; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-/** +- * A computer for `search.findElementReferences` request results. +- */ +-class ElementReferencesComputer { +- final SearchEngine searchEngine; +- +- ElementReferencesComputer(this.searchEngine); +- +- /** +- * Computes [SearchResult]s for [element] references. +- */ +- Future> compute( +- Element element, bool withPotential) async { +- List results = []; +- +- // Add element references. +- results.addAll(await _findElementsReferences(element)); +- +- // Add potential references. +- if (withPotential && _isMemberElement(element)) { +- String name = element.displayName; +- List matches = +- await searchEngine.searchMemberReferences(name); +- matches = SearchMatch.withNotNullElement(matches); +- results.addAll(matches.where((match) => !match.isResolved).map(toResult)); +- } +- +- return results; +- } +- +- /** +- * Returns a [Future] completing with a [List] of references to [element] or +- * to the corresponding hierarchy [Element]s. +- */ +- Future> _findElementsReferences(Element element) async { +- List allResults = []; +- Iterable refElements = await _getRefElements(element); +- for (Element refElement in refElements) { +- List elementResults = +- await _findSingleElementReferences(refElement); +- allResults.addAll(elementResults); +- } +- return allResults; +- } +- +- /** +- * Returns a [Future] completing with a [List] of references to [element]. +- */ +- Future> _findSingleElementReferences( +- Element element) async { +- List matches = await searchEngine.searchReferences(element); +- matches = SearchMatch.withNotNullElement(matches); +- return matches.map(toResult).toList(); +- } +- +- /** +- * Returns a [Future] completing with [Element]s to search references to. +- * +- * If a [ClassMemberElement] is given, each corresponding [Element] in the +- * hierarchy is returned. +- * +- * Otherwise, only references to [element] should be searched. +- */ +- Future> _getRefElements(Element element) { +- if (element is ClassMemberElement) { +- return getHierarchyMembers(searchEngine, element); +- } +- return new Future.value([element]); +- } +- +- static SearchResult toResult(SearchMatch match) { +- return newSearchResult_fromMatch(match); +- } +- +- static bool _isMemberElement(Element element) { +- if (element is ConstructorElement) { +- return false; +- } +- return element.enclosingElement is ClassElement; +- } +-} +diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart +deleted file mode 100644 +index cb7f02fb53e..00000000000 +--- a/pkg/analysis_server/lib/src/search/search_domain.dart ++++ /dev/null +@@ -1,211 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analysis_server/src/search/element_references.dart'; +-import 'package:analysis_server/src/search/type_hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-/** +- * Instances of the class [SearchDomainHandler] implement a [RequestHandler] +- * that handles requests in the search domain. +- */ +-class SearchDomainHandler implements protocol.RequestHandler { +- /** +- * The analysis server that is using this handler to process requests. +- */ +- final AnalysisServer server; +- +- /** +- * The [SearchEngine] for this server. +- */ +- final SearchEngine searchEngine; +- +- /** +- * The next search response id. +- */ +- int _nextSearchId = 0; +- +- /** +- * Initialize a newly created handler to handle requests for the given [server]. +- */ +- SearchDomainHandler(AnalysisServer server) +- : server = server, +- searchEngine = server.searchEngine; +- +- Future findElementReferences(protocol.Request request) async { +- var params = +- new protocol.SearchFindElementReferencesParams.fromRequest(request); +- String file = params.file; +- // prepare element +- Element element = await server.getElementAtOffset(file, params.offset); +- if (element is ImportElement) { +- element = (element as ImportElement).prefix; +- } +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- if (element is PropertyAccessorElement) { +- element = (element as PropertyAccessorElement).variable; +- } +- // respond +- String searchId = (_nextSearchId++).toString(); +- var result = new protocol.SearchFindElementReferencesResult(); +- if (element != null) { +- result.id = searchId; +- result.element = protocol.convertElement(element); +- } +- _sendSearchResult(request, result); +- // search elements +- if (element != null) { +- var computer = new ElementReferencesComputer(searchEngine); +- List results = +- await computer.compute(element, params.includePotential); +- _sendSearchNotification(searchId, true, results); +- } +- } +- +- Future findMemberDeclarations(protocol.Request request) async { +- var params = +- new protocol.SearchFindMemberDeclarationsParams.fromRequest(request); +- await server.onAnalysisComplete; +- // respond +- String searchId = (_nextSearchId++).toString(); +- _sendSearchResult( +- request, new protocol.SearchFindMemberDeclarationsResult(searchId)); +- // search +- List matches = +- await searchEngine.searchMemberDeclarations(params.name); +- matches = SearchMatch.withNotNullElement(matches); +- _sendSearchNotification(searchId, true, matches.map(toResult)); +- } +- +- Future findMemberReferences(protocol.Request request) async { +- var params = +- new protocol.SearchFindMemberReferencesParams.fromRequest(request); +- await server.onAnalysisComplete; +- // respond +- String searchId = (_nextSearchId++).toString(); +- _sendSearchResult( +- request, new protocol.SearchFindMemberReferencesResult(searchId)); +- // search +- List matches = +- await searchEngine.searchMemberReferences(params.name); +- matches = SearchMatch.withNotNullElement(matches); +- _sendSearchNotification(searchId, true, matches.map(toResult)); +- } +- +- Future findTopLevelDeclarations(protocol.Request request) async { +- var params = +- new protocol.SearchFindTopLevelDeclarationsParams.fromRequest(request); +- try { +- // validate the regex +- new RegExp(params.pattern); +- } on FormatException catch (exception) { +- server.sendResponse(new protocol.Response.invalidParameter( +- request, 'pattern', exception.message)); +- return; +- } +- +- await server.onAnalysisComplete; +- // respond +- String searchId = (_nextSearchId++).toString(); +- _sendSearchResult( +- request, new protocol.SearchFindTopLevelDeclarationsResult(searchId)); +- // search +- List matches = +- await searchEngine.searchTopLevelDeclarations(params.pattern); +- matches = SearchMatch.withNotNullElement(matches); +- _sendSearchNotification(searchId, true, matches.map(toResult)); +- } +- +- /** +- * Implement the `search.getTypeHierarchy` request. +- */ +- Future getTypeHierarchy(protocol.Request request) async { +- var params = new protocol.SearchGetTypeHierarchyParams.fromRequest(request); +- String file = params.file; +- // prepare element +- Element element = await server.getElementAtOffset(file, params.offset); +- if (element == null) { +- _sendTypeHierarchyNull(request); +- return; +- } +- // maybe supertype hierarchy only +- if (params.superOnly == true) { +- TypeHierarchyComputer computer = +- new TypeHierarchyComputer(searchEngine, element); +- List items = computer.computeSuper(); +- protocol.Response response = +- new protocol.SearchGetTypeHierarchyResult(hierarchyItems: items) +- .toResponse(request.id); +- server.sendResponse(response); +- return; +- } +- // prepare type hierarchy +- TypeHierarchyComputer computer = +- new TypeHierarchyComputer(searchEngine, element); +- List items = await computer.compute(); +- protocol.Response response = +- new protocol.SearchGetTypeHierarchyResult(hierarchyItems: items) +- .toResponse(request.id); +- server.sendResponse(response); +- } +- +- @override +- protocol.Response handleRequest(protocol.Request request) { +- try { +- String requestName = request.method; +- if (requestName == SEARCH_REQUEST_FIND_ELEMENT_REFERENCES) { +- findElementReferences(request); +- return protocol.Response.DELAYED_RESPONSE; +- } else if (requestName == SEARCH_REQUEST_FIND_MEMBER_DECLARATIONS) { +- findMemberDeclarations(request); +- return protocol.Response.DELAYED_RESPONSE; +- } else if (requestName == SEARCH_REQUEST_FIND_MEMBER_REFERENCES) { +- findMemberReferences(request); +- return protocol.Response.DELAYED_RESPONSE; +- } else if (requestName == SEARCH_REQUEST_FIND_TOP_LEVEL_DECLARATIONS) { +- findTopLevelDeclarations(request); +- return protocol.Response.DELAYED_RESPONSE; +- } else if (requestName == SEARCH_REQUEST_GET_TYPE_HIERARCHY) { +- getTypeHierarchy(request); +- return protocol.Response.DELAYED_RESPONSE; +- } +- } on protocol.RequestFailure catch (exception) { +- return exception.response; +- } +- return null; +- } +- +- void _sendSearchNotification( +- String searchId, bool isLast, Iterable results) { +- server.sendNotification( +- new protocol.SearchResultsParams(searchId, results.toList(), isLast) +- .toNotification()); +- } +- +- /** +- * Send a search response with the given [result] to the given [request]. +- */ +- void _sendSearchResult(protocol.Request request, result) { +- protocol.Response response = result.toResponse(request.id); +- server.sendResponse(response); +- } +- +- void _sendTypeHierarchyNull(protocol.Request request) { +- protocol.Response response = +- new protocol.SearchGetTypeHierarchyResult().toResponse(request.id); +- server.sendResponse(response); +- } +- +- static protocol.SearchResult toResult(SearchMatch match) { +- return protocol.newSearchResult_fromMatch(match); +- } +-} +diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart +deleted file mode 100644 +index 841e291ec82..00000000000 +--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart ++++ /dev/null +@@ -1,202 +0,0 @@ +-// Copyright (c) 2014, 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:analysis_server/src/protocol_server.dart' +- show TypeHierarchyItem, convertElement; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +- +-/** +- * A computer for a type hierarchy of an [Element]. +- */ +-class TypeHierarchyComputer { +- final SearchEngine _searchEngine; +- +- Element _pivotElement; +- LibraryElement _pivotLibrary; +- ElementKind _pivotKind; +- String _pivotName; +- bool _pivotFieldFinal; +- ClassElement _pivotClass; +- +- final List _items = []; +- final List _itemClassElements = []; +- final Map _elementItemMap = +- new HashMap(); +- +- TypeHierarchyComputer(this._searchEngine, this._pivotElement) { +- _pivotLibrary = _pivotElement.library; +- _pivotKind = _pivotElement.kind; +- _pivotName = _pivotElement.name; +- // try to find enclosing ClassElement +- Element element = _pivotElement; +- if (_pivotElement is FieldElement) { +- _pivotFieldFinal = (_pivotElement as FieldElement).isFinal; +- element = _pivotElement.enclosingElement; +- } +- if (_pivotElement is ExecutableElement) { +- element = _pivotElement.enclosingElement; +- } +- if (element is ClassElement) { +- _pivotClass = element; +- } +- } +- +- /** +- * Returns the computed type hierarchy, maybe `null`. +- */ +- Future> compute() async { +- if (_pivotClass != null) { +- InterfaceType type = _pivotClass.type; +- _createSuperItem(type); +- await _createSubclasses(_items[0], 0, type); +- return _items; +- } +- return null; +- } +- +- /** +- * Returns the computed super type only type hierarchy, maybe `null`. +- */ +- List computeSuper() { +- if (_pivotClass != null) { +- InterfaceType type = _pivotClass.type; +- _createSuperItem(type); +- return _items; +- } +- return null; +- } +- +- Future _createSubclasses( +- TypeHierarchyItem item, int itemId, InterfaceType type) async { +- Set subElements = +- await getDirectSubClasses(_searchEngine, type.element); +- List subItemIds = []; +- for (ClassElement subElement in subElements) { +- // check for recursion +- TypeHierarchyItem subItem = _elementItemMap[subElement]; +- if (subItem != null) { +- int id = _items.indexOf(subItem); +- item.subclasses.add(id); +- continue; +- } +- // create a subclass item +- ExecutableElement subMemberElement = _findMemberElement(subElement); +- subItem = new TypeHierarchyItem(convertElement(subElement), +- memberElement: subMemberElement != null +- ? convertElement(subMemberElement) +- : null, +- superclass: itemId); +- int subItemId = _items.length; +- // remember +- _elementItemMap[subElement] = subItem; +- _items.add(subItem); +- _itemClassElements.add(subElement); +- // add to hierarchy +- item.subclasses.add(subItemId); +- subItemIds.add(subItemId); +- } +- // compute subclasses of subclasses +- for (int subItemId in subItemIds) { +- TypeHierarchyItem subItem = _items[subItemId]; +- ClassElement subItemElement = _itemClassElements[subItemId]; +- InterfaceType subType = subItemElement.type; +- await _createSubclasses(subItem, subItemId, subType); +- } +- } +- +- int _createSuperItem(InterfaceType type) { +- // check for recursion +- TypeHierarchyItem item = _elementItemMap[type.element]; +- if (item != null) { +- return _items.indexOf(item); +- } +- // create an empty item now +- int itemId; +- { +- String displayName = null; +- if (type.typeArguments.isNotEmpty) { +- displayName = type.toString(); +- } +- ClassElement classElement = type.element; +- ExecutableElement memberElement = _findMemberElement(classElement); +- item = new TypeHierarchyItem(convertElement(classElement), +- displayName: displayName, +- memberElement: +- memberElement != null ? convertElement(memberElement) : null); +- _elementItemMap[classElement] = item; +- itemId = _items.length; +- _items.add(item); +- _itemClassElements.add(classElement); +- } +- // superclass +- { +- InterfaceType superType = type.superclass; +- if (superType != null) { +- item.superclass = _createSuperItem(superType); +- } +- } +- // mixins +- type.mixins.forEach((InterfaceType type) { +- int id = _createSuperItem(type); +- item.mixins.add(id); +- }); +- // interfaces +- type.interfaces.forEach((InterfaceType type) { +- int id = _createSuperItem(type); +- item.interfaces.add(id); +- }); +- // done +- return itemId; +- } +- +- ExecutableElement _findMemberElement(ClassElement clazz) { +- ExecutableElement result; +- // try to find in the class itself +- if (_pivotKind == ElementKind.METHOD) { +- result = clazz.getMethod(_pivotName); +- } else if (_pivotKind == ElementKind.GETTER) { +- result = clazz.getGetter(_pivotName); +- } else if (_pivotKind == ElementKind.SETTER) { +- result = clazz.getSetter(_pivotName); +- } else if (_pivotKind == ElementKind.FIELD) { +- result = clazz.getGetter(_pivotName); +- if (result == null && !_pivotFieldFinal) { +- result = clazz.getSetter(_pivotName); +- } +- } +- if (result != null && result.isAccessibleIn(_pivotLibrary)) { +- return result; +- } +- // try to find in the class mixin +- for (InterfaceType mixin in clazz.mixins.reversed) { +- ClassElement mixinElement = mixin.element; +- if (_pivotKind == ElementKind.METHOD) { +- result = mixinElement.lookUpMethod(_pivotName, _pivotLibrary); +- } else if (_pivotKind == ElementKind.GETTER) { +- result = mixinElement.lookUpGetter(_pivotName, _pivotLibrary); +- } else if (_pivotKind == ElementKind.SETTER) { +- result = mixinElement.lookUpSetter(_pivotName, _pivotLibrary); +- } else if (_pivotKind == ElementKind.FIELD) { +- result = mixinElement.lookUpGetter(_pivotName, _pivotLibrary); +- if (result == null && !_pivotFieldFinal) { +- result = mixinElement.lookUpSetter(_pivotName, _pivotLibrary); +- } +- } +- if (result == _pivotElement) { +- return null; +- } +- if (result != null) { +- return result; +- } +- } +- // not found +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/server/diagnostic_server.dart b/pkg/analysis_server/lib/src/server/diagnostic_server.dart +deleted file mode 100644 +index b147a43ed55..00000000000 +--- a/pkg/analysis_server/lib/src/server/diagnostic_server.dart ++++ /dev/null +@@ -1,16 +0,0 @@ +-// 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'; +- +-/** +- * A handle to start, and return the current port of, a diagnostic server. +- */ +-abstract class DiagnosticServer { +- /** +- * Return the port of the diagnostic web server. If the server is not running +- * this call will start the server. +- */ +- Future getServerPort(); +-} +diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart +deleted file mode 100644 +index 039d508bd01..00000000000 +--- a/pkg/analysis_server/lib/src/server/driver.dart ++++ /dev/null +@@ -1,640 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +-import 'dart:math'; +- +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/server/diagnostic_server.dart'; +-import 'package:analysis_server/src/server/http_server.dart'; +-import 'package:analysis_server/src/server/stdio_server.dart'; +-import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart' +- show UriContributor; +-import 'package:analysis_server/src/socket_server.dart'; +-import 'package:analysis_server/starter.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer/instrumentation/file_instrumentation.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/plugin/resolver_provider.dart'; +-import 'package:analyzer/src/context/builder.dart'; +-import 'package:analyzer/src/dart/sdk/sdk.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:args/args.dart'; +-import 'package:linter/src/rules.dart' as linter; +-import 'package:plugin/manager.dart'; +-import 'package:telemetry/crash_reporting.dart'; +-import 'package:telemetry/telemetry.dart' as telemetry; +- +-/// Commandline argument parser. (Copied from analyzer/lib/options.dart) +-/// TODO(pquitslund): replaces with a simple [ArgParser] instance +-/// when the args package supports ignoring unrecognized +-/// options/flags (https://github.com/dart-lang/args/issues/9). +-class CommandLineParser { +- final List _knownFlags; +- final bool _alwaysIgnoreUnrecognized; +- final ArgParser _parser; +- +- /// Creates a new command line parser +- CommandLineParser({bool alwaysIgnoreUnrecognized: false}) +- : _knownFlags = [], +- _alwaysIgnoreUnrecognized = alwaysIgnoreUnrecognized, +- _parser = new ArgParser(allowTrailingOptions: true); +- +- ArgParser get parser => _parser; +- +- /// Defines a flag. +- /// See [ArgParser.addFlag()]. +- void addFlag(String name, +- {String abbr, +- String help, +- bool defaultsTo: false, +- bool negatable: true, +- void callback(bool value), +- bool hide: false}) { +- _knownFlags.add(name); +- _parser.addFlag(name, +- abbr: abbr, +- help: help, +- defaultsTo: defaultsTo, +- negatable: negatable, +- callback: callback, +- hide: hide); +- } +- +- /// Defines a value-taking option. +- /// See [ArgParser.addOption()]. +- void addOption(String name, +- {String abbr, +- String help, +- List allowed, +- Map allowedHelp, +- String defaultsTo, +- void callback(value), +- bool allowMultiple: false}) { +- _knownFlags.add(name); +- _parser.addOption(name, +- abbr: abbr, +- help: help, +- allowed: allowed, +- allowedHelp: allowedHelp, +- defaultsTo: defaultsTo, +- callback: callback, +- allowMultiple: allowMultiple); +- } +- +- /// Generates a string displaying usage information for the defined options. +- /// See [ArgParser.usage]. +- String getUsage() => _parser.usage; +- +- /// Parses [args], a list of command-line arguments, matches them against the +- /// flags and options defined by this parser, and returns the result. The +- /// values of any defined variables are captured in the given map. +- /// See [ArgParser]. +- ArgResults parse(List args, Map definedVariables) => +- _parser.parse( +- _filterUnknowns(parseDefinedVariables(args, definedVariables))); +- +- List parseDefinedVariables( +- List args, Map definedVariables) { +- int count = args.length; +- List remainingArgs = []; +- for (int i = 0; i < count; i++) { +- String arg = args[i]; +- if (arg == '--') { +- while (i < count) { +- remainingArgs.add(args[i++]); +- } +- } else if (arg.startsWith("-D")) { +- definedVariables[arg.substring(2)] = args[++i]; +- } else { +- remainingArgs.add(arg); +- } +- } +- return remainingArgs; +- } +- +- List _filterUnknowns(List args) { +- // Only filter args if the ignore flag is specified, or if +- // _alwaysIgnoreUnrecognized was set to true +- if (_alwaysIgnoreUnrecognized || +- args.contains('--ignore-unrecognized-flags')) { +- // Filter all unrecognized flags and options. +- List filtered = []; +- for (int i = 0; i < args.length; ++i) { +- String arg = args[i]; +- if (arg.startsWith('--') && arg.length > 2) { +- String option = arg.substring(2); +- // remove any leading 'no-' +- if (option.startsWith('no-')) { +- option = option.substring(3); +- } +- // strip the last '=value' +- int equalsOffset = option.lastIndexOf('='); +- if (equalsOffset != -1) { +- option = option.substring(0, equalsOffset); +- } +- // check the option +- if (!_knownFlags.contains(option)) { +- //"eat" params by advancing to the next flag/option +- i = _getNextFlagIndex(args, i); +- } else { +- filtered.add(arg); +- } +- } else { +- filtered.add(arg); +- } +- } +- +- return filtered; +- } else { +- return args; +- } +- } +- +- _getNextFlagIndex(args, i) { +- for (; i < args.length; ++i) { +- if (args[i].startsWith('--')) { +- return i; +- } +- } +- return i; +- } +-} +- +-/** +- * The [Driver] class represents a single running instance of the analysis +- * server application. It is responsible for parsing command line options +- * and starting the HTTP and/or stdio servers. +- */ +-class Driver implements ServerStarter { +- /** +- * The name of the application that is used to start a server. +- */ +- static const BINARY_NAME = "server"; +- +- /** +- * The name of the option used to set the identifier for the client. +- */ +- static const String CLIENT_ID = "client-id"; +- +- /** +- * The name of the option used to set the version for the client. +- */ +- static const String CLIENT_VERSION = "client-version"; +- +- /** +- * The name of the option used to enable DartPad specific functionality. +- */ +- static const String DARTPAD_OPTION = "dartpad"; +- +- /** +- * The name of the option used to enable instrumentation. +- */ +- static const String ENABLE_INSTRUMENTATION_OPTION = "enable-instrumentation"; +- +- /** +- * The name of the option used to set the file read mode. +- */ +- static const String FILE_READ_MODE = "file-read-mode"; +- +- /** +- * The name of the flag used when analyzing the flutter repository. +- * See comments in source for `flutter analyze --watch`. +- */ +- static const FLUTTER_REPO = "flutter-repo"; +- +- /** +- * The name of the option used to print usage information. +- */ +- static const String HELP_OPTION = "help"; +- +- /** +- * The name of the flag used to configure reporting analytics. +- */ +- static const String ANALYTICS_FLAG = "analytics"; +- +- /** +- * Suppress analytics for this session. +- */ +- static const String SUPPRESS_ANALYTICS_FLAG = "suppress-analytics"; +- +- /** +- * The name of the option used to cause instrumentation to also be written to +- * a local file. +- */ +- static const String INSTRUMENTATION_LOG_FILE = "instrumentation-log-file"; +- +- /** +- * The name of the option used to specify if [print] should print to the +- * console instead of being intercepted. +- */ +- static const String INTERNAL_PRINT_TO_CONSOLE = "internal-print-to-console"; +- +- /** +- * The name of the option used to describe the new analysis driver logger. +- */ +- static const String NEW_ANALYSIS_DRIVER_LOG = 'new-analysis-driver-log'; +- +- /** +- * The name of the flag used to enable version 2 of semantic highlight +- * notification. +- */ +- static const String USE_ANALYSIS_HIGHLIGHT2 = "useAnalysisHighlight2"; +- +- /** +- * The option for specifying the http diagnostic port. +- * If specified, users can review server status and performance information +- * by opening a web browser on http://localhost: +- */ +- static const String PORT_OPTION = "port"; +- +- /** +- * The path to the SDK. +- */ +- static const String SDK_OPTION = "sdk"; +- +- /** +- * The path to the data cache. +- */ +- static const String CACHE_FOLDER = "cache"; +- +- /** +- * Whether to enable the Dart 2.0 Front End. +- */ +- static const String PREVIEW_DART2 = "preview-dart-2"; +- +- /** +- * The instrumentation server that is to be used by the analysis server. +- */ +- InstrumentationServer instrumentationServer; +- +- /** +- * The file resolver provider used to override the way file URI's are +- * resolved in some contexts. +- */ +- ResolverProvider fileResolverProvider; +- +- /** +- * The package resolver provider used to override the way package URI's are +- * resolved in some contexts. +- */ +- ResolverProvider packageResolverProvider; +- +- SocketServer socketServer; +- +- HttpAnalysisServer httpServer; +- +- StdioAnalysisServer stdioServer; +- +- Driver(); +- +- /** +- * Use the given command-line [arguments] to start this server. +- * +- * At least temporarily returns AnalysisServer so that consumers of the +- * starter API can then use the server, this is done as a stopgap for the +- * angular plugin until the official plugin API is finished. +- */ +- AnalysisServer start(List arguments) { +- CommandLineParser parser = _createArgParser(); +- ArgResults results = parser.parse(arguments, {}); +- +- AnalysisServerOptions analysisServerOptions = new AnalysisServerOptions(); +- analysisServerOptions.useAnalysisHighlight2 = +- results[USE_ANALYSIS_HIGHLIGHT2]; +- analysisServerOptions.fileReadMode = results[FILE_READ_MODE]; +- analysisServerOptions.newAnalysisDriverLog = +- results[NEW_ANALYSIS_DRIVER_LOG]; +- analysisServerOptions.clientId = results[CLIENT_ID]; +- analysisServerOptions.clientVersion = results[CLIENT_VERSION]; +- analysisServerOptions.cacheFolder = results[CACHE_FOLDER]; +- analysisServerOptions.previewDart2 = results[PREVIEW_DART2]; +- +- ContextBuilderOptions.flutterRepo = results[FLUTTER_REPO]; +- +- telemetry.Analytics analytics = telemetry.createAnalyticsInstance( +- 'UA-26406144-29', 'analysis-server', +- disableForSession: results[SUPPRESS_ANALYTICS_FLAG]); +- analysisServerOptions.analytics = analytics; +- +- if (analysisServerOptions.clientId != null) { +- // Record the client name as the application installer ID. +- analytics.setSessionValue('aiid', analysisServerOptions.clientId); +- } +- if (analysisServerOptions.clientVersion != null) { +- analytics.setSessionValue('cd1', analysisServerOptions.clientVersion); +- } +- +- // TODO(devoncarew): Replace with the real crash product ID. +- analysisServerOptions.crashReportSender = +- new CrashReportSender('Dart_analysis_server', analytics); +- +- if (telemetry.SHOW_ANALYTICS_UI) { +- if (results.wasParsed(ANALYTICS_FLAG)) { +- analytics.enabled = results[ANALYTICS_FLAG]; +- print(telemetry.createAnalyticsStatusMessage(analytics.enabled)); +- return null; +- } +- } +- +- if (results[DARTPAD_OPTION]) { +- UriContributor.suggestFilePaths = false; +- } +- +- if (results[HELP_OPTION]) { +- _printUsage(parser.parser, analytics, fromHelp: true); +- return null; +- } +- +- int port; +- bool serve_http = false; +- if (results[PORT_OPTION] != null) { +- try { +- port = int.parse(results[PORT_OPTION]); +- serve_http = true; +- } on FormatException { +- print('Invalid port number: ${results[PORT_OPTION]}'); +- print(''); +- _printUsage(parser.parser, analytics); +- exitCode = 1; +- return null; +- } +- } +- +- // +- // Process all of the plugins so that extensions are registered. +- // +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- linter.registerLintRules(); +- +- String defaultSdkPath; +- if (results[SDK_OPTION] != null) { +- defaultSdkPath = results[SDK_OPTION]; +- } else { +- // No path to the SDK was provided. +- // Use FolderBasedDartSdk.defaultSdkDirectory, which will make a guess. +- defaultSdkPath = FolderBasedDartSdk +- .defaultSdkDirectory(PhysicalResourceProvider.INSTANCE) +- .path; +- } +- // TODO(brianwilkerson) It would be nice to avoid creating an SDK that +- // cannot be re-used, but the SDK is needed to create a package map provider +- // in the case where we need to run `pub` in order to get the package map. +- DartSdk defaultSdk = _createDefaultSdk(defaultSdkPath, true); +- // +- // Initialize the instrumentation service. +- // +- String logFilePath = results[INSTRUMENTATION_LOG_FILE]; +- if (logFilePath != null) { +- _rollLogFiles(logFilePath, 5); +- FileInstrumentationServer fileBasedServer = +- new FileInstrumentationServer(logFilePath); +- instrumentationServer = instrumentationServer != null +- ? new MulticastInstrumentationServer( +- [instrumentationServer, fileBasedServer]) +- : fileBasedServer; +- } +- InstrumentationService instrumentationService = +- new InstrumentationService(instrumentationServer); +- instrumentationService.logVersion( +- _readUuid(instrumentationService), +- analysisServerOptions.clientId, +- analysisServerOptions.clientVersion, +- AnalysisServer.VERSION, +- defaultSdk.sdkVersion); +- AnalysisEngine.instance.instrumentationService = instrumentationService; +- +- _DiagnosticServerImpl diagnosticServer = new _DiagnosticServerImpl(); +- +- // Ping analytics with our initial call. +- analytics.sendScreenView('home'); +- +- // +- // Create the sockets and start listening for requests. +- // +- socketServer = new SocketServer( +- analysisServerOptions, +- new DartSdkManager(defaultSdkPath, true), +- defaultSdk, +- instrumentationService, +- diagnosticServer, +- fileResolverProvider, +- packageResolverProvider); +- httpServer = new HttpAnalysisServer(socketServer); +- stdioServer = new StdioAnalysisServer(socketServer); +- +- diagnosticServer.httpServer = httpServer; +- if (serve_http) { +- diagnosticServer.startOnPort(port); +- } +- +- _captureExceptions(instrumentationService, () { +- stdioServer.serveStdio().then((_) async { +- if (serve_http) { +- httpServer.close(); +- } +- await instrumentationService.shutdown(); +- exit(0); +- }); +- }, +- print: +- results[INTERNAL_PRINT_TO_CONSOLE] ? null : httpServer.recordPrint); +- +- return socketServer.analysisServer; +- } +- +- /** +- * Execute the given [callback] within a zone that will capture any unhandled +- * exceptions and both report them to the client and send them to the given +- * instrumentation [service]. If a [print] function is provided, then also +- * capture any data printed by the callback and redirect it to the function. +- */ +- dynamic _captureExceptions(InstrumentationService service, dynamic callback(), +- {void print(String line)}) { +- void errorFunction(Zone self, ZoneDelegate parent, Zone zone, +- dynamic exception, StackTrace stackTrace) { +- service.logPriorityException(exception, stackTrace); +- AnalysisServer analysisServer = socketServer.analysisServer; +- analysisServer.sendServerErrorNotification( +- 'Captured exception', exception, stackTrace); +- throw exception; +- } +- +- var printFunction = print == null +- ? null +- : (Zone self, ZoneDelegate parent, Zone zone, String line) { +- // Note: we don't pass the line on to stdout, because that is +- // reserved for communication to the client. +- print(line); +- }; +- ZoneSpecification zoneSpecification = new ZoneSpecification( +- handleUncaughtError: errorFunction, print: printFunction); +- return runZoned(callback, zoneSpecification: zoneSpecification); +- } +- +- /** +- * Create and return the parser used to parse the command-line arguments. +- */ +- CommandLineParser _createArgParser() { +- CommandLineParser parser = +- new CommandLineParser(alwaysIgnoreUnrecognized: true); +- parser.addOption(CLIENT_ID, +- help: "an identifier used to identify the client"); +- parser.addOption(CLIENT_VERSION, help: "the version of the client"); +- parser.addFlag(DARTPAD_OPTION, +- help: 'enable DartPad specific functionality', +- defaultsTo: false, +- hide: true); +- parser.addFlag(ENABLE_INSTRUMENTATION_OPTION, +- help: "enable sending instrumentation information to a server", +- defaultsTo: false, +- negatable: false); +- parser.addFlag(FLUTTER_REPO, +- help: 'used by "flutter analyze" to enable specific lints' +- ' when analyzing the flutter repository', +- hide: false); +- parser.addFlag(HELP_OPTION, +- help: "print this help message without starting a server", +- abbr: 'h', +- defaultsTo: false, +- negatable: false); +- parser.addOption(INSTRUMENTATION_LOG_FILE, +- help: "write instrumentation data to the given file"); +- parser.addFlag(INTERNAL_PRINT_TO_CONSOLE, +- help: "enable sending `print` output to the console", +- defaultsTo: false, +- negatable: false); +- parser.addOption(NEW_ANALYSIS_DRIVER_LOG, +- help: "set a destination for the new analysis driver's log"); +- if (telemetry.SHOW_ANALYTICS_UI) { +- parser.addFlag(ANALYTICS_FLAG, +- help: 'enable or disable sending analytics information to Google'); +- } +- parser.addFlag(SUPPRESS_ANALYTICS_FLAG, +- negatable: false, help: 'suppress analytics for this session'); +- parser.addOption(PORT_OPTION, +- help: "the http diagnostic port on which the server provides" +- " status and performance information"); +- parser.addOption(SDK_OPTION, help: "[path] the path to the sdk"); +- parser.addFlag(USE_ANALYSIS_HIGHLIGHT2, +- help: "enable version 2 of semantic highlight", +- defaultsTo: false, +- negatable: false); +- parser.addOption(FILE_READ_MODE, +- help: "an option for reading files (some clients normalize eol " +- "characters, which make the file offset and range information " +- "incorrect)", +- allowed: ["as-is", "normalize-eol-always"], +- allowedHelp: { +- "as-is": "file contents are read as-is", +- "normalize-eol-always": +- r"eol characters normalized to the single character new line ('\n')" +- }, +- defaultsTo: "as-is"); +- parser.addOption(CACHE_FOLDER, +- help: "[path] path to the location where to cache data"); +- parser.addFlag(PREVIEW_DART2, +- help: "Enable the Dart 2.0 Front End implementation."); +- +- return parser; +- } +- +- DartSdk _createDefaultSdk(String defaultSdkPath, bool useSummaries) { +- PhysicalResourceProvider resourceProvider = +- PhysicalResourceProvider.INSTANCE; +- FolderBasedDartSdk sdk = new FolderBasedDartSdk( +- resourceProvider, resourceProvider.getFolder(defaultSdkPath)); +- sdk.useSummary = useSummaries; +- return sdk; +- } +- +- /** +- * Print information about how to use the server. +- */ +- void _printUsage(ArgParser parser, telemetry.Analytics analytics, +- {bool fromHelp: false}) { +- print('Usage: $BINARY_NAME [flags]'); +- print(''); +- print('Supported flags are:'); +- print(parser.usage); +- +- if (telemetry.SHOW_ANALYTICS_UI) { +- // Print analytics status and information. +- if (fromHelp) { +- print(''); +- print(telemetry.analyticsNotice); +- } +- print(''); +- print(telemetry.createAnalyticsStatusMessage(analytics.enabled, +- command: ANALYTICS_FLAG)); +- } +- } +- +- /** +- * Read the UUID from disk, generating and storing a new one if necessary. +- */ +- String _readUuid(InstrumentationService service) { +- File uuidFile = new File(PhysicalResourceProvider.INSTANCE +- .getStateLocation('.instrumentation') +- .getChild('uuid.txt') +- .path); +- try { +- if (uuidFile.existsSync()) { +- String uuid = uuidFile.readAsStringSync(); +- if (uuid != null && uuid.length > 5) { +- return uuid; +- } +- } +- } catch (exception, stackTrace) { +- service.logPriorityException(exception, stackTrace); +- } +- int millisecondsSinceEpoch = new DateTime.now().millisecondsSinceEpoch; +- int random = new Random().nextInt(0x3fffffff); +- String uuid = '$millisecondsSinceEpoch$random'; +- try { +- uuidFile.parent.createSync(recursive: true); +- uuidFile.writeAsStringSync(uuid); +- } catch (exception, stackTrace) { +- service.logPriorityException(exception, stackTrace); +- // Slightly alter the uuid to indicate it was not persisted +- uuid = 'temp-$uuid'; +- } +- return uuid; +- } +- +- /** +- * Perform log files rolling. +- * +- * Rename existing files with names `[path].(x)` to `[path].(x+1)`. +- * Keep at most [numOld] files. +- * Rename the file with the given [path] to `[path].1`. +- */ +- static void _rollLogFiles(String path, int numOld) { +- for (int i = numOld - 1; i >= 0; i--) { +- try { +- String oldPath = i == 0 ? path : '$path.$i'; +- new File(oldPath).renameSync('$path.${i+1}'); +- } catch (e) {} +- } +- } +-} +- +-/** +- * Implements the [DiagnosticServer] class by wrapping an [HttpAnalysisServer]. +- */ +-class _DiagnosticServerImpl extends DiagnosticServer { +- HttpAnalysisServer httpServer; +- +- _DiagnosticServerImpl(); +- +- @override +- Future getServerPort() => httpServer.serveHttp(); +- +- Future startOnPort(int port) { +- return httpServer.serveHttp(port); +- } +-} +diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart +deleted file mode 100644 +index 131d00a2b7c..00000000000 +--- a/pkg/analysis_server/lib/src/server/http_server.dart ++++ /dev/null +@@ -1,169 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +- +-import 'package:analysis_server/src/socket_server.dart'; +-import 'package:analysis_server/src/status/diagnostics.dart'; +- +-/** +- * Instances of the class [AbstractGetHandler] handle GET requests. +- */ +-abstract class AbstractGetHandler { +- /** +- * Handle a GET request received by the HTTP server. +- */ +- void handleGetRequest(HttpRequest request); +-} +- +-/** +- * An [AbstractGetHandler] that always returns the given error message. +- */ +-class ErrorGetHandler extends AbstractGetHandler { +- final String message; +- +- ErrorGetHandler(this.message); +- +- @override +- void handleGetRequest(HttpRequest request) { +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.NOT_FOUND; +- response.headers.contentType = ContentType.TEXT; +- response.write(message); +- response.close(); +- } +-} +- +-/** +- * Instances of the class [HttpServer] implement a simple HTTP server. The +- * server: +- * +- * - listens for an UPGRADE request in order to start an analysis server +- * - serves diagnostic information as html pages +- */ +-class HttpAnalysisServer { +- /** +- * Number of lines of print output to capture. +- */ +- static const int MAX_PRINT_BUFFER_LENGTH = 1000; +- +- /** +- * An object that can handle either a WebSocket connection or a connection +- * to the client over stdio. +- */ +- SocketServer socketServer; +- +- /** +- * An object that can handle GET requests. +- */ +- AbstractGetHandler getHandler; +- +- /** +- * Future that is completed with the HTTP server once it is running. +- */ +- Future _serverFuture; +- +- /** +- * Last PRINT_BUFFER_LENGTH lines printed. +- */ +- List _printBuffer = []; +- +- /** +- * Initialize a newly created HTTP server. +- */ +- HttpAnalysisServer(this.socketServer); +- +- /** +- * Return the port this server is bound to. +- */ +- Future get boundPort async => (await _serverFuture)?.port; +- +- void close() { +- _serverFuture?.then((HttpServer server) { +- server.close(); +- }); +- } +- +- /** +- * Record that the given line was printed out by the analysis server. +- */ +- void recordPrint(String line) { +- _printBuffer.add(line); +- if (_printBuffer.length > MAX_PRINT_BUFFER_LENGTH) { +- _printBuffer.removeRange( +- 0, _printBuffer.length - MAX_PRINT_BUFFER_LENGTH); +- } +- } +- +- /** +- * Begin serving HTTP requests over the given port. +- */ +- Future serveHttp([int initialPort]) async { +- if (_serverFuture != null) { +- return boundPort; +- } +- +- try { +- _serverFuture = +- HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, initialPort ?? 0); +- +- HttpServer server = await _serverFuture; +- _handleServer(server); +- return server.port; +- } catch (ignore) { +- // If we can't bind to the specified port, don't remember the broken +- // server. +- _serverFuture = null; +- +- return null; +- } +- } +- +- /** +- * Handle a GET request received by the HTTP server. +- */ +- Future _handleGetRequest(HttpRequest request) async { +- if (getHandler == null) { +- getHandler = new DiagnosticsSite(socketServer, _printBuffer); +- } +- await getHandler.handleGetRequest(request); +- } +- +- /** +- * Attach a listener to a newly created HTTP server. +- */ +- void _handleServer(HttpServer httpServer) { +- httpServer.listen((HttpRequest request) async { +- List updateValues = request.headers[HttpHeaders.UPGRADE]; +- if (request.method == 'GET') { +- await _handleGetRequest(request); +- } else if (updateValues != null && +- updateValues.indexOf('websocket') >= 0) { +- // We no longer support serving analysis server communications over +- // WebSocket connections. +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.NOT_FOUND; +- response.headers.contentType = ContentType.TEXT; +- response.write( +- 'WebSocket connections not supported (${request.uri.path}).'); +- response.close(); +- } else { +- _returnUnknownRequest(request); +- } +- }); +- } +- +- /** +- * Return an error in response to an unrecognized request received by the HTTP +- * server. +- */ +- void _returnUnknownRequest(HttpRequest request) { +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.NOT_FOUND; +- response.headers.contentType = ContentType.TEXT; +- response.write('Not found'); +- response.close(); +- } +-} +diff --git a/pkg/analysis_server/lib/src/server/stdio_server.dart b/pkg/analysis_server/lib/src/server/stdio_server.dart +deleted file mode 100644 +index 18954447cbe..00000000000 +--- a/pkg/analysis_server/lib/src/server/stdio_server.dart ++++ /dev/null +@@ -1,40 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +- +-import 'package:analysis_server/src/channel/byte_stream_channel.dart'; +-import 'package:analysis_server/src/socket_server.dart'; +- +-/** +- * Instances of the class [StdioServer] implement a simple server operating +- * over standard input and output. The primary responsibility of this server +- * is to split incoming messages on newlines and pass them along to the +- * analysis server. +- */ +-class StdioAnalysisServer { +- /** +- * An object that can handle either a WebSocket connection or a connection +- * to the client over stdio. +- */ +- SocketServer socketServer; +- +- /** +- * Initialize a newly created stdio server. +- */ +- StdioAnalysisServer(this.socketServer); +- +- /** +- * Begin serving requests over stdio. +- * +- * Return a future that will be completed when stdin closes. +- */ +- Future serveStdio() { +- ByteStreamServerChannel serverChannel = new ByteStreamServerChannel( +- stdin, stdout, socketServer.instrumentationService); +- socketServer.createAnalysisServer(serverChannel); +- return serverChannel.closed; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart +deleted file mode 100644 +index 9d15c203812..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart ++++ /dev/null +@@ -1,75 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/completion_core.dart'; +-import 'package:analysis_server/src/services/completion/completion_performance.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * The information about a requested list of completions. +- */ +-class CompletionRequestImpl implements CompletionRequest { +- @override +- final AnalysisResult result; +- +- @override +- final Source source; +- +- @override +- final int offset; +- +- /** +- * The offset of the start of the text to be replaced. +- * This will be different than the [offset] used to request the completion +- * suggestions if there was a portion of an identifier before the original +- * [offset]. In particular, the [replacementOffset] will be the offset of the +- * beginning of said identifier. +- */ +- int replacementOffset; +- +- /** +- * The length of the text to be replaced if the remainder of the identifier +- * containing the cursor is to be replaced when the suggestion is applied +- * (that is, the number of characters in the existing identifier). +- * This will be different than the [replacementOffset] - [offset] +- * if the [offset] is in the middle of an existing identifier. +- */ +- int replacementLength; +- +- @override +- final ResourceProvider resourceProvider; +- +- bool _aborted = false; +- +- final CompletionPerformance performance; +- +- /** +- * Initialize a newly created completion request based on the given arguments. +- */ +- CompletionRequestImpl(this.result, this.resourceProvider, Source source, +- int offset, this.performance) +- : this.source = source, +- this.offset = offset, +- replacementOffset = offset, +- replacementLength = 0; +- +- @override +- String get sourceContents => result?.content; +- +- /** +- * Abort the current completion request. +- */ +- void abort() { +- _aborted = true; +- } +- +- @override +- void checkAborted() { +- if (_aborted) { +- throw new AbortCompletion(); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart +deleted file mode 100644 +index fab1435d9ca..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart ++++ /dev/null +@@ -1,117 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * Overall performance of a code completion operation. +- */ +-class CompletionPerformance { +- final DateTime start = new DateTime.now(); +- final Map _startTimes = new Map(); +- final Stopwatch _stopwatch = new Stopwatch(); +- final List operations = []; +- +- Source source; +- String snippet = ''; +- int notificationCount = -1; +- int suggestionCountFirst = -1; +- int suggestionCountLast = -1; +- Duration _firstNotification; +- +- CompletionPerformance() { +- _stopwatch.start(); +- } +- +- int get elapsedInMilliseconds => +- operations.length > 0 ? operations.last.elapsed.inMilliseconds : 0; +- +- int get firstNotificationInMilliseconds => +- _firstNotification != null ? _firstNotification.inMilliseconds : 0; +- +- String get startTimeAndMs => '${start.millisecondsSinceEpoch} - $start'; +- +- String get suggestionCount { +- if (notificationCount < 1) return ''; +- if (notificationCount == 1) return '$suggestionCountFirst'; +- return '$suggestionCountFirst, $suggestionCountLast'; +- } +- +- void complete([String tag = null]) { +- _stopwatch.stop(); +- _logDuration(tag ?? 'total time', _stopwatch.elapsed); +- } +- +- void logElapseTime(String tag) { +- Duration end = _stopwatch.elapsed; +- Duration start = _startTimes[tag]; +- if (start == null) { +- _logDuration(tag, null); +- return null; +- } +- _logDuration(tag, end - start); +- } +- +- void logFirstNotificationComplete(String tag) { +- _firstNotification = _stopwatch.elapsed; +- _logDuration(tag, _firstNotification); +- } +- +- void logStartTime(String tag) { +- _startTimes[tag] = _stopwatch.elapsed; +- } +- +- void setContentsAndOffset(String contents, int offset) { +- snippet = _computeSnippet(contents, offset); +- } +- +- void _logDuration(String tag, Duration elapsed) { +- operations.add(new OperationPerformance(tag, elapsed)); +- } +- +- static String _computeSnippet(String contents, int offset) { +- if (contents == null || +- offset == null || +- offset < 0 || +- contents.length < offset) { +- return '???'; +- } +- int start = offset; +- while (start > 0) { +- String ch = contents[start - 1]; +- if (ch == '\r' || ch == '\n') { +- break; +- } +- --start; +- } +- int end = offset; +- while (end < contents.length) { +- String ch = contents[end]; +- if (ch == '\r' || ch == '\n') { +- break; +- } +- ++end; +- } +- String prefix = contents.substring(start, offset); +- String suffix = contents.substring(offset, end); +- return '$prefix^$suffix'; +- } +-} +- +-/** +- * The performance of an operation when computing code completion. +- */ +-class OperationPerformance { +- /** +- * The name of the operation +- */ +- final String name; +- +- /** +- * The elapse time or `null` if undefined. +- */ +- final Duration elapsed; +- +- OperationPerformance(this.name, this.elapsed); +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart +deleted file mode 100644 +index 010164a1cea..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart ++++ /dev/null +@@ -1,340 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- hide Element, ElementKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/utilities.dart'; +-import 'package:analysis_server/src/utilities/documentation.dart'; +-import 'package:analysis_server/src/utilities/flutter.dart' as flutter; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/utilities_dart.dart'; +- +-/** +- * Determine the number of arguments. +- */ +-int _argCount(DartCompletionRequest request) { +- AstNode node = request.target.containingNode; +- if (node is ArgumentList) { +- if (request.target.entity == node.rightParenthesis) { +- // Parser ignores trailing commas +- if (node.rightParenthesis.previous?.lexeme == ',') { +- return node.arguments.length + 1; +- } +- } +- return node.arguments.length; +- } +- return 0; +-} +- +-/** +- * If the containing [node] is an argument list +- * or named expression in an argument list +- * then return the simple identifier for the method, constructor, or annotation +- * to which the argument list is associated +- */ +-SimpleIdentifier _getTargetId(AstNode node) { +- if (node is NamedExpression) { +- return _getTargetId(node.parent); +- } +- if (node is ArgumentList) { +- AstNode parent = node.parent; +- if (parent is MethodInvocation) { +- return parent.methodName; +- } +- if (parent is InstanceCreationExpression) { +- ConstructorName constructorName = parent.constructorName; +- if (constructorName != null) { +- if (constructorName.name != null) { +- return constructorName.name; +- } +- Identifier typeName = constructorName.type.name; +- if (typeName is SimpleIdentifier) { +- return typeName; +- } +- if (typeName is PrefixedIdentifier) { +- return typeName.identifier; +- } +- } +- } +- if (parent is Annotation) { +- return parent.constructorName ?? parent.name; +- } +- } +- return null; +-} +- +-/** +- * Determine if the completion target is at the end of the list of arguments. +- */ +-bool _isAppendingToArgList(DartCompletionRequest request) { +- AstNode node = request.target.containingNode; +- if (node is ArgumentList) { +- var entity = request.target.entity; +- if (entity == node.rightParenthesis) { +- return true; +- } +- if (node.arguments.length > 0 && node.arguments.last == entity) { +- return entity is SimpleIdentifier; +- } +- } +- return false; +-} +- +-/** +- * Determine if the completion target is the label for a named argument. +- */ +-bool _isEditingNamedArgLabel(DartCompletionRequest request) { +- AstNode node = request.target.containingNode; +- if (node is ArgumentList) { +- var entity = request.target.entity; +- if (entity is NamedExpression) { +- int offset = request.offset; +- if (entity.offset < offset && offset < entity.end) { +- return true; +- } +- } +- } +- return false; +-} +- +-/** +- * Return `true` if the [request] is inside of a [NamedExpression] name. +- */ +-bool _isInNamedExpression(DartCompletionRequest request) { +- Object entity = request.target.entity; +- if (entity is NamedExpression) { +- Label name = entity.name; +- return name.offset < request.offset && request.offset < name.end; +- } +- return false; +-} +- +-/** +- * Determine if the completion target is in the middle or beginning of the list +- * of named parameters and is not preceded by a comma. This method assumes that +- * _isAppendingToArgList has been called and is false. +- */ +-bool _isInsertingToArgListWithNoSynthetic(DartCompletionRequest request) { +- AstNode node = request.target.containingNode; +- if (node is ArgumentList) { +- var entity = request.target.entity; +- return entity is NamedExpression; +- } +- return false; +-} +- +-/** +- * Determine if the completion target is in the middle or beginning of the list +- * of named parameters and is preceded by a comma. This method assumes that +- * _isAppendingToArgList and _isInsertingToArgListWithNoSynthetic have been +- * called and both return false. +- */ +-bool _isInsertingToArgListWithSynthetic(DartCompletionRequest request) { +- AstNode node = request.target.containingNode; +- if (node is ArgumentList) { +- var entity = request.target.entity; +- if (entity is SimpleIdentifier) { +- int argIndex = request.target.argIndex; +- // if the next argument is a NamedExpression, then we are in the named +- // parameter list, guard first against end of list +- if (node.arguments.length == argIndex + 1 || +- node.arguments.getRange(argIndex + 1, argIndex + 2).first +- is NamedExpression) { +- return true; +- } +- } +- } +- return false; +-} +- +-/** +- * Return a collection of currently specified named arguments +- */ +-Iterable _namedArgs(DartCompletionRequest request) { +- AstNode node = request.target.containingNode; +- List namedArgs = new List(); +- if (node is ArgumentList) { +- for (Expression arg in node.arguments) { +- if (arg is NamedExpression) { +- namedArgs.add(arg.name.label.name); +- } +- } +- } +- return namedArgs; +-} +- +-/** +- * A contributor for calculating `completion.getSuggestions` request results +- * when the cursor position is inside the arguments to a method call. +- */ +-class ArgListContributor extends DartCompletionContributor { +- DartCompletionRequest request; +- List suggestions; +- +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- this.request = request; +- this.suggestions = []; +- +- // Determine if the target is in an argument list +- // for a method or a constructor or an annotation +- SimpleIdentifier targetId = _getTargetId(request.target.containingNode); +- if (targetId == null) { +- return EMPTY_LIST; +- } +- Element elem = targetId.bestElement; +- if (elem == null) { +- return EMPTY_LIST; +- } +- +- // Generate argument list suggestion based upon the type of element +- if (elem is ClassElement) { +- _addSuggestions(elem.unnamedConstructor?.parameters); +- return suggestions; +- } +- if (elem is ConstructorElement) { +- _addSuggestions(elem.parameters); +- return suggestions; +- } +- if (elem is FunctionElement) { +- _addSuggestions(elem.parameters); +- return suggestions; +- } +- if (elem is MethodElement) { +- _addSuggestions(elem.parameters); +- return suggestions; +- } +- return EMPTY_LIST; +- } +- +- void _addDefaultParamSuggestions(Iterable parameters, +- [bool appendComma = false]) { +- bool appendColon = !_isInNamedExpression(request); +- Iterable namedArgs = _namedArgs(request); +- for (ParameterElement parameter in parameters) { +- if (parameter.parameterKind == ParameterKind.NAMED) { +- _addNamedParameterSuggestion( +- namedArgs, parameter, appendColon, appendComma); +- } +- } +- } +- +- void _addNamedParameterSuggestion(List namedArgs, +- ParameterElement parameter, bool appendColon, bool appendComma) { +- String name = parameter.name; +- String type = parameter.type?.displayName; +- if (name != null && name.length > 0 && !namedArgs.contains(name)) { +- String completion = name; +- if (appendColon) { +- completion += ': '; +- } +- int selectionOffset = completion.length; +- +- // Optionally add Flutter child widget details. +- Element element = parameter.enclosingElement; +- if (element is ConstructorElement) { +- if (flutter.isWidget(element.enclosingElement) && +- parameter.name == 'children') { +- String value = getDefaultStringParameterValue(parameter); +- if (value != null) { +- completion += value; +- // children: [] +- selectionOffset = completion.length - 1; // before closing ']' +- } +- } +- } +- +- if (appendComma) { +- completion += ','; +- } +- +- final int relevance = parameter.isRequired +- ? DART_RELEVANCE_NAMED_PARAMETER_REQUIRED +- : DART_RELEVANCE_NAMED_PARAMETER; +- +- CompletionSuggestion suggestion = new CompletionSuggestion( +- CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance, +- completion, +- selectionOffset, +- 0, +- false, +- false, +- parameterName: name, +- parameterType: type); +- if (parameter is FieldFormalParameterElement) { +- _setDocumentation(suggestion, parameter.field?.documentationComment); +- suggestion.element = convertElement(parameter); +- } +- +- suggestions.add(suggestion); +- } +- } +- +- void _addSuggestions(Iterable parameters) { +- if (parameters == null || parameters.length == 0) { +- return; +- } +- Iterable requiredParam = parameters.where( +- (ParameterElement p) => p.parameterKind == ParameterKind.REQUIRED); +- int requiredCount = requiredParam.length; +- // TODO (jwren) _isAppendingToArgList can be split into two cases (with and +- // without preceded), then _isAppendingToArgList, +- // _isInsertingToArgListWithNoSynthetic and +- // _isInsertingToArgListWithSynthetic could be formatted into a single +- // method which returns some enum with 5+ cases. +- if (_isEditingNamedArgLabel(request) || _isAppendingToArgList(request)) { +- if (requiredCount == 0 || requiredCount < _argCount(request)) { +- bool addTrailingComma = +- !_isFollowedByAComma(request) && _isInFlutterCreation(request); +- _addDefaultParamSuggestions(parameters, addTrailingComma); +- } +- } else if (_isInsertingToArgListWithNoSynthetic(request)) { +- _addDefaultParamSuggestions(parameters, true); +- } else if (_isInsertingToArgListWithSynthetic(request)) { +- _addDefaultParamSuggestions(parameters, !_isFollowedByAComma(request)); +- } +- } +- +- bool _isFollowedByAComma(DartCompletionRequest request) { +- // new A(^); NO +- // new A(one: 1, ^); NO +- // new A(^ , one: 1); YES +- // new A(^), ... NO +- +- var containingNode = request.target.containingNode; +- var entity = request.target.entity; +- Token token = +- entity is AstNode ? entity.endToken : entity is Token ? entity : null; +- return (token != containingNode?.endToken) && +- token?.next?.type == TokenType.COMMA; +- } +- +- bool _isInFlutterCreation(DartCompletionRequest request) { +- AstNode containingNode = request?.target?.containingNode; +- InstanceCreationExpression newExpr = containingNode != null +- ? flutter.identifyNewExpression(containingNode.parent) +- : null; +- return newExpr != null && flutter.isWidgetCreation(newExpr); +- } +- +- /** +- * If the given [comment] is not `null`, fill the [suggestion] documentation +- * fields. +- */ +- static void _setDocumentation( +- CompletionSuggestion suggestion, String comment) { +- if (comment != null) { +- String doc = removeDartDocDelimiters(comment); +- suggestion.docComplete = doc; +- suggestion.docSummary = getDartDocSummary(doc); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart +deleted file mode 100644 +index 4d30f30eb5f..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart ++++ /dev/null +@@ -1,41 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- hide Element, ElementKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-/** +- * A contributor for calculating `completion.getSuggestions` request results +- * for the import combinators show and hide. +- */ +-class CombinatorContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- AstNode node = request.target.containingNode; +- if (node is! Combinator) { +- return EMPTY_LIST; +- } +- +- // Build list of suggestions +- var directive = node.getAncestor((parent) => parent is NamespaceDirective); +- if (directive is NamespaceDirective) { +- LibraryElement library = directive.uriElement; +- if (library != null) { +- LibraryElementSuggestionBuilder builder = +- new LibraryElementSuggestionBuilder(request.libraryElement, +- CompletionSuggestionKind.IDENTIFIER, false, false); +- library.visitChildren(builder); +- return builder.suggestions; +- } +- } +- return EMPTY_LIST; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart +deleted file mode 100644 +index a515bedff80..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart ++++ /dev/null +@@ -1,127 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library services.completion.dart.sorter.common; +- +-import 'dart:async'; +- +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/provisional/completion/completion_core.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'; +- +-part 'common_usage_sorter.g.dart'; +- +-/** +- * A computer for adjusting the relevance of completions computed by others +- * based upon common Dart usage patterns. This is a long-lived object +- * that should not maintain state between calls to it's [sort] method. +- */ +-class CommonUsageSorter implements DartContributionSorter { +- /** +- * A map of . to an ordered list of method names, +- * field names, getter names, and named constructors. +- * The names are ordered from most relevant to least relevant. +- * Names not listed are considered equally less relevant than those listed. +- */ +- Map> selectorRelevance; +- +- CommonUsageSorter([this.selectorRelevance = defaultSelectorRelevance]); +- +- @override +- Future sort(DartCompletionRequest request, +- Iterable suggestions) { +- _update(request, suggestions); +- return new Future.value(); +- } +- +- CompletionTarget _getCompletionTarget(CompletionRequest request) => +- new CompletionTarget.forOffset(request.result.unit, request.offset); +- +- /** +- * Adjusts the relevance based on the given completion context. +- * The compilation unit and completion node +- * in the given completion context may not be resolved. +- */ +- void _update( +- CompletionRequest request, Iterable suggestions) { +- var target = _getCompletionTarget(request); +- if (target != null) { +- var visitor = new _BestTypeVisitor(target.entity); +- DartType type = target.containingNode.accept(visitor); +- if (type != null) { +- Element typeElem = type.element; +- if (typeElem != null) { +- LibraryElement libElem = typeElem.library; +- if (libElem != null) { +- _updateInvocationRelevance(type, libElem, suggestions); +- } +- } +- } +- } +- } +- +- /** +- * Adjusts the relevance of all method suggestions based upon the given +- * target type and library. +- */ +- void _updateInvocationRelevance(DartType type, LibraryElement libElem, +- Iterable suggestions) { +- String typeName = type.name; +- List selectors = selectorRelevance['${libElem.name}.$typeName']; +- if (selectors != null) { +- for (CompletionSuggestion suggestion in suggestions) { +- protocol.Element element = suggestion.element; +- if (element != null && +- (element.kind == protocol.ElementKind.CONSTRUCTOR || +- element.kind == protocol.ElementKind.FIELD || +- element.kind == protocol.ElementKind.GETTER || +- element.kind == protocol.ElementKind.METHOD || +- element.kind == protocol.ElementKind.SETTER) && +- suggestion.kind == CompletionSuggestionKind.INVOCATION && +- suggestion.declaringType == typeName) { +- int index = selectors.indexOf(suggestion.completion); +- if (index != -1) { +- suggestion.relevance = DART_RELEVANCE_COMMON_USAGE - index; +- } +- } +- } +- } +- } +-} +- +-/** +- * An [AstVisitor] used to determine the best defining type of a node. +- */ +-class _BestTypeVisitor extends GeneralizingAstVisitor { +- /** +- * The entity which the completed text will replace (or which will be +- * displaced once the completed text is inserted). This may be an AstNode or +- * a Token, or it may be null if the cursor is after all tokens in the file. +- * See field of the same name in [CompletionTarget]. +- */ +- final Object entity; +- +- _BestTypeVisitor(this.entity); +- +- DartType visitConstructorName(ConstructorName node) => +- node.period != null && node.name == entity ? node.type?.type : null; +- +- DartType visitNode(AstNode node) { +- return null; +- } +- +- DartType visitPrefixedIdentifier(PrefixedIdentifier node) => +- node.identifier == entity ? node.prefix?.bestType : null; +- +- DartType visitPropertyAccess(PropertyAccess node) => +- node.propertyName == entity ? node.realTarget?.bestType : null; +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart +deleted file mode 100644 +index f065701d986..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.g.dart ++++ /dev/null +@@ -1,427 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-part of services.completion.dart.sorter.common; +- +-// Auto-generated, please do not edit. +- +-/** +- * A map of . to an ordered list of method names, +- * field names, getter names, and named constructors. +- * The names are ordered from most relevant to least relevant. +- * Names not listed are considered equally less relevant than those listed. +- */ +-const Map> defaultSelectorRelevance = const { +-'dart.core.Comparable': const ['compareTo','compare',], +-'dart.math.Random': const ['nextInt','nextDouble','nextBool',], +-'dart.core.List': const ['add','map','length','removeLast','addAll','join','forEach','contains','removeAt','where','last','clear','setRange','sort','insert','remove','sublist','indexOf','isEmpty','any','insertAll','first','removeRange','replaceRange','take','getRange','skip','toList','retainWhere','fillRange','removeWhere','expand','fold','reversed','firstWhere','every','setAll','asMap','isNotEmpty','lastIndexOf','singleWhere','lastWhere','shuffle','takeWhile','iterator','toString','toSet','single','reduce','elementAt','skipWhile','insertRange','filter','push','mappedBy','addLast','some','slice','retainMatching','firstMatching','removeAll','retainAll','removeMatching','min','lastMatching','singleMatching','max','get','toArray','runtimeType','reverse','addd','asByteArray',], +-'dart.core.Iterable': const ['toList','map','join','toSet','where','forEach','expand','fold','every','any','contains','firstWhere','length','elementAt','skipWhile','reduce','iterator','take','skip','toString','singleWhere','lastWhere','takeWhile','isEmpty','first','single','last','isNotEmpty','addAll','indexOf','add','sort','toArray','mappedBy','filter',], +-'dart.core.Set': const ['add','contains','remove','addAll','clear','difference','map','containsAll','union','removeWhere','removeAll','intersection','retainAll','retainWhere','forEach','toSet','every','lookup','any','toString','toList','where','length','join','skip','firstWhere','isEmpty','first','iterator','singleWhere','expand','elementAt','fold','reduce','single','lastWhere','isNotEmpty','take','takeWhile','skipWhile','last','findBy','toArray','filter',], +-'dart.collection.Queue': const ['add','removeFirst','clear','removeLast','remove','addAll','addLast','addFirst','removeWhere','retainWhere','length','toList','where','contains','forEach','map','isNotEmpty','first','isEmpty','fold','skip','any','elementAt',], +-'dart.core.Map': const ['containsKey','forEach','remove','putIfAbsent','clear','addAll','length','keys','values','containsValue','toString','isNotEmpty','isEmpty','get','getKeys','put','getValues','clone','keySet','hashCode','runtimeType',], +-'dart.core.Iterator': const ['moveNext','current','next','hasNext',], +-'dart.pkg.collection.equality.Equality': const ['hash','equals','isValidKey',], +-'dart.pkg.collection.equality.SetEquality': const ['equals','hash',], +-'dart.pkg.collection.equality.MapEquality': const ['equals','hash',], +-'dart.pkg.collection.equality.ListEquality': const ['equals','hash',], +-'dart.pkg.collection.equality.IterableEquality': const ['hash','equals',], +-'dart.pkg.collection.equality.UnorderedIterableEquality': const ['hash','equals',], +-'dart.async.StreamSubscription': const ['cancel','pause','onDone','resume','onError','asFuture','onData','isPaused',], +-'dart.async.StreamController': const ['add','close','addError','addStream','stream','hasListener','signalError','sink','done',], +-'dart.async.Stream': const ['listen','transform','pipe','first','toList','forEach','firstWhere','where','join','fold','asyncMap','map','isEmpty','asBroadcastStream','handleError','capture','asyncExpand','take','single','expand','onFile','skip','any','timeout','add','last','runtimeType','isBroadcast','drain','elementAt','skipWhile','distinct','singleWhere','lastWhere','contains','every','takeWhile','emit','onDir','onError','onDone','onData','length',], +-'dart.async.Future': const ['then','catchError','wait','whenComplete','forEach','asStream','timeout','map','packages','where','firstWhere','chain','transform','doWhile','onError','onResponse','onRequest','handleException',], +-'dart.core.String': const ['substring','codeUnitAt','startsWith','replaceAll','split','contains','indexOf','toLowerCase','trim','length','endsWith','lastIndexOf','compareTo','isEmpty','toUpperCase','replaceFirst','toString','replaceAllMapped','allMatches','padLeft','codeUnits','hashCode','splitMapJoin','isNotEmpty','runes','charCodeAt','charCodes','trimRight','padRight','concat','equalsIgnoreCase','splitChars','trimLeft','matchAsPrefix','equals','map','toLoweCase','match','slice','getBytes','toCharArray','runtimeType','charAt','valueOf',], +-'dart.core.StringBuffer': const ['write','toString','writeln','writeCharCode','clear','writeAll','add','addAll','addCharCode','isEmpty',], +-'dart.core.RegExp': const ['firstMatch','hasMatch','allMatches','matchAsPrefix','pattern','stringMatch','toString','exec',], +-'dart.core.double': const ['parse','toInt','compareTo','floor','toString','abs','round','toStringAsPrecision','toDouble','floorToDouble','ceil','truncate','toStringAsFixed','roundToDouble','clamp','isNaN','isFinite','toStringAsExponential','ceilToDouble','truncateToDouble','isNan','isNegative','isInfinite','hashCode',], +-'dart.core.Type': const ['toString','hashCode','runtimeType',], +-'dart.mirrors.InstanceMirror': const ['reflectee','getField','type','invoke','setField','delegate','function','then','apply','hasReflectee',], +-'dart.collection.IterableBase': const ['iterableToFullString',], +-'dart.pkg.collection.utils.Pair': const ['last',], +-'dart.collection.Maps': const ['mapToString','length','putIfAbsent','clear','containsKey','getValues','forEach','containsValue','isNotEmpty','isEmpty',], +-'dart.collection.SplayTreeSet': const ['add','addAll','where',], +-'dart.core.StackTrace': const ['toString','frames',], +-'dart.convert.JsonCodec': const ['encode','decode','fuse',], +-'dart.mirrors.MirrorSystem': const ['getName','libraries','findLibrary','isolate','dynamicType','getSymbol','voidType',], +-'dart.mirrors.ClassMirror': const ['newInstance','isSubtypeOf','reflectedType','qualifiedName','metadata','getField','owner','declarations','superclass','simpleName','isSubclassOf','invoke','instanceMembers','mixin','isAbstract','originalDeclaration','typeVariables','setField','isOriginalDeclaration','superinterfaces','isAssignableTo','owners',], +-'dart.io.Process': const ['start','runSync','run','kill','exitCode',], +-'dart.core.int': const ['parse','toDouble','toString','toInt','compareTo','toRadixString','abs','remainder','toUnsigned','toSigned','clamp','round','floor','substr','ceil','isEven','id','append','truncate','hashCode','toStringAsFixed','ceilToDouble','roundToDouble','floorToDouble','truncateToDouble','isNegative','length','isNaN','isInfinite','runtimeType','bitLength',], +-'dart.core.Sink': const ['add','close',], +-'dart.async.EventSink': const ['close','add','addError',], +-'dart.async.Completer': const ['complete','completeError','future','isCompleted','completeException','then',], +-'dart.io.FileStat': const ['mode','stat','type','statSync','changed','modified','size',], +-'dart.io.Link': const ['existsSync','createSync','resolveSymbolicLinksSync','exists','delete','targetSync','deleteSync','target','create','updateSync',], +-'dart.io.FileSystemEntityType': const ['toString','NOT_FOUND','DIRECTORY','FILE',], +-'dart.io.Directory': const ['existsSync','list','listSync','watch','path','exists','createSync','create','deleteSync','delete','createTemp','createTempSync','renameSync','parent','absolute','stat','current','createRecursivelySync','resolveSymbolicLinksSync','rename','statSync',], +-'dart.io.File': const ['existsSync','readAsStringSync','openRead','writeAsStringSync','readAsString','openWrite','lastModifiedSync','exists','resolveSymbolicLinksSync','writeAsString','path','resolveSymbolicLinks','statSync','deleteSync','createSync','delete','openSync','parent','readAsBytesSync','copy','open','absolute','fullPathSync','length','writeAsBytesSync','lastModified','writeAsBytes','readAsLinesSync','fullPath','readAsBytes','copySync','create','lengthSync','readAsLines','isFileSync','isFile','rename','openOutputStream','openInputStream','stat','renameSync','watch','directorySync','isAbsolute','directory',], +-'dart.io.Stdout': const ['writeln','close','write','flush','addStream','writeString','add','writeCharCode','addString',], +-'dart.io.IOSink': const ['write','close','writeln','flush','add','addStream','writeAll','writeCharCode','encoding','addError','done',], +-'dart.mirrors.LibraryMirror': const ['uri','getField','declarations','invoke','topLevelMembers','setField','classes','first',], +-'dart.core.Match': const ['group','end','start','groups','toString',], +-'dart.isolate.SendPort': const ['send','call','hashCode',], +-'dart.core.DateTime': const ['parse','toIso8601String','millisecondsSinceEpoch','difference','toUtc','add','day','year','month','isAfter','toString','compareTo','subtract','isBefore','millisecond','toLocal','timeZoneName','timeZoneOffset','isUtc','weekday','isAtSameMomentAs','second','hour','minute','hashCode','now','runtimeType',], +-'dart.core.Duration': const ['inMilliseconds','toString','inSeconds','inMicroseconds','inHours','inMinutes','inDays','isNegative','compareTo',], +-'dart.core.Uri': const ['parse','toString','toFilePath','path','resolve','decodeComponent','encodeFull','decodeQueryComponent','scheme','encodeComponent','resolveUri','encodeQueryComponent','query','decodeFull','pathSegments','queryParameters','origin','authority','splitQueryString','replace','host','isAbsolute','port','fragment','hasAuthority','userInfo','parseIPv4Address','parseIPv6Address','hasQuery','endsWith','startsWith',], +-'dart.typed_data.Uint32List': const ['sublist','setAll','fillRange','setRange','removeRange','removeLast','clear','addAll','add',], +-'dart.typed_data.TypedData': const ['buffer',], +-'dart.io.BytesBuilder': const ['takeBytes','addByte','add','clear','toBytes',], +-'dart.isolate.ReceivePort': const ['close','transform','listen','receive','toSendPort','takeWhile','sendPort','asBroadcastStream',], +-'dart.convert.Encoding': const ['decode','encode','getByName','decodeStream','name',], +-'dart.convert.Utf8Codec': const ['encode','decode','decoder','decodeStream',], +-'dart.core.Stopwatch': const ['start','stop','reset','elapsedMicroseconds','elapsedMilliseconds','elapsed','elapsedInMs',], +-'dart.async.ZoneDelegate': const ['handleUncaughtError','registerUnaryCallback','registerCallback','registerBinaryCallback','runBinary','errorCallback','scheduleMicrotask','run','createTimer',], +-'dart.async.Zone': const ['handleUncaughtError','run','fork','inSameErrorZone','runGuarded','bindUnaryCallback','bindBinaryCallback','runUnary','bindCallback','scheduleMicrotask','createTimer',], +-'dart.dom.html.BodyElement': const ['innerHtml','children','nodes','append','style','onContextMenu','onMouseDown','onMouseWheel','scrollTop','onMouseUp','onClick','scrollLeft','clientHeight','clientWidth','onBlur','onFocus','onDoubleClick','scrollHeight','onMouseMove','elements','createFragment','classes','ownerDocument','query','onKeyDown','querySelector','offsetWidth','scrollWidth','offsetHeight','setInnerHtml','childNodes','requestFullscreen','offsetTop',], +-'dart.dom.html.Location': const ['hash','search','reload','pathname','toString','href','host','assign','replace','protocol','hostname','port','origin',], +-'dart.convert.HtmlEscape': const ['convert',], +-'dart.dom.html.Window': const ['postMessage','btoa','lookupPort','document','requestAnimationFrame','alert','navigator','devicePixelRatio','pageYOffset','pageXOffset','onAnimationEnd','innerWidth','onResize','getSelection','cancelAnimationFrame','animationEndEvent','innerHeight','registerPort','dispatchEvent','onAnimationStart','onMouseUp','onMouseMove','open','screen','indexedDB','setTimeout','scrollX','scrollY','onScroll','openDatabase','confirm','getContainer','location','onKeyUp','atob','scrollTo','localStorage','scrollBy','setInterval','setImmediate','requestLayoutFrame','requestFileSystem','onHashChange','close','console','onError','onMessage','animationFrame',], +-'dart.core.Function': const ['apply','toString','call','bind',], +-'dart.async.Timer': const ['cancel','run',], +-'dart.dom.html.HeadElement': const ['append','querySelector','query','children','style','elements','querySelectorAll','nodes','id','insertBefore','text',], +-'dart.dom.html.ElementStream': const ['listen','where','first','matches','forEach','map',], +-'dart.dom.html.Element': const ['query','onClick','innerHtml','style','querySelector','nodes','children','remove','append','querySelectorAll','classes','attributes','setInnerHtml','getComputedStyle','onChange','parent','matches','getBoundingClientRect','focus','dispatchEvent','addEventListener','insertAllBefore','clone','getAttribute','blur','createShadowRoot','contains','text','setAttribute','insertAdjacentElement','appendText','scrollIntoView','shadowRoot','getNamespacedAttributes','removeEventListener','insertBefore','appendHtml','click','offsetWidth','insertAdjacentHtml','insertAdjacentText','getClientRects','getElementsByClassName','replaceWith','scrollByLines','scrollByPages','hasChildNodes','requestFullscreen','requestPointerLock','queryAll','setAttributeNS','getAttributeNS','dataset','offsetHeight','on','createFragment','offsetTo','getDestinationInsertionPoints','matchesWithAncestors','attributeChanged','onMouseDown','nextElementSibling','getRegionFlowRanges','onContextMenu','animate','onTouchStart','scrollTop','offsetTop','onTouchMove','onTouchEnd','onMouseWheel','clientWidth','scrollLeft','clientHeight','isTagSupported','parentNode','onMouseUp','bind','onKeyDown','ownerDocument','unbind','unbindAll','init','createInstance','render','update','onKeyUp','onMouseMove','xtag','offsetLeft','tabIndex','client','requestFullScreen','getInputContext','borderEdge','clearModel','id','disabled','value','getContext','lastChild','firstChild','nextNode','innerHTML','onMouseEnter','onMouseLeave','contentEdge','elements','matchesSelector','webkitRequestPointerLock','tagName','childNodes','webkitRequestFullscreen','webkitRequestFullScreen','marginEdge','paddingEdge','outerHtml','onMouseOver','onMouseOut','onDragEnd','boolean','scrollHeight','hidden','onDragStart','onDoubleClick','nodeType','hashCode','onDrag','onInput','selectionStart','selectionEnd','onDrop','onDragLeave','hideOrShowNavigation','onDragOver','model','scrollEvent','onDragEnter','previousElementSibling','className','namespaceUri','onSubmit','selection','setItemSelected','runtimeType','apply','createBinding','values','onBlur','onTouchCancel','show','insertAdjacentHTML','nodeName','selected','contentEditable','localName','number','draggable','src','addText','addHTML','select','clear','str','clearSelection',], +-'dart.dom.html.HtmlElement': const ['querySelector','query','append','classes','style','getComputedStyle','remove','getBoundingClientRect','querySelectorAll','clone','attributes','focus','tabIndex','onClick','parent','onMouseLeave','replaceWith','onContextMenu','onMouseEnter','onKeyDown','blur','setInnerText','scrollTop','appendHtml','dataset','lastChild','onSelectStart','onDrop','onDragOver','onDragLeave','onDragEnter','onDragEnd','onDragStart','onDrag','onDoubleClick','children','onScroll','getAttribute','nodes','outerHtml','click','createShadowRoot',], +-'dart.dom.html.ElementList': const ['forEach','length','contains','last','style','addAll','first','where','onMouseLeave','onMouseEnter','toList','some','onClick','map','classes','indexOf',], +-'dart.dom.html.HtmlDocument': const ['query','querySelectorAll','querySelector','queryAll','createElement','body','title','createElementUpgrader','documentElement','timeline','onKeyDown','getElementById','registerElement','onClick','addEventListener','onMouseUp','onMouseMove','activeElement','createElementNS','createDocumentFragment','createRange','adoptNode','getElementsByTagName','onKeyUp','elementFromPoint','contains','getElementsByName','head','exitFullscreen','onMouseWheel','register',], +-'dart.collection.LinkedHashMap': const ['containsKey','forEach','remove','putIfAbsent','keys','length','clear','values','isNotEmpty',], +-'dart.dom.html.Navigator': const ['userAgent','language','appVersion','appName','geolocation','vendor','appCodeName','dartEnabled','getUserMedia','onLine','platform','storageQuota',], +-'dart.dom.html.CssStyleDeclaration': const ['display','width','height','top','setProperty','left','position','zIndex','cssText','right','maxHeight','visibility','bottom','background','removeProperty','cursor','overflow','getPropertyValue','opacity','backgroundColor','float','transform','padding','border','borderRadius','paddingBottom','transition','paddingTop','overflowY','color','outline','backgroundImage','transformStyle','pointerEvents','marginLeft','textAlign','backgroundPosition','boxSizing','paddingLeft','backgroundSize','margin','fontFamily','userSelect','fontSize','lineHeight','willChange','fontWeight','getProperty','marginRight','whiteSpace','overflowX','textDecoration','perspective','perspectiveOrigin','appearance','borderLeftWidth','paddingRight','borderColor','borderBottomWidth','borderTopWidth','webkitOverflowScrolling','borderRightWidth','marginBottom','transitionProperty','transitionTimingFunction','transitionDuration','animation','animationDelay','animationFillMode','animationDirection','animationIterationCount','animationTimingFunction','animationDuration','animationName','verticalAlign','marginTop','boxShadow','getPropertyPriority','textStrokeColor','borderBottom','font','supportsProperty','textShadow','maxWidth','minWidth','minHeight','outlineColor','filter','borderWidth','animationPlayState','fontStyle','borderRight','borderLeft','borderTop',], +-'dart.io.ProcessResult': const ['stdout','exitCode',], +-'dart.io.FileSystemEvent': const ['path','isDirectory','type','MODIFY','CREATE','DELETE',], +-'dart.collection.HashSet': const ['add','contains','remove','clear','addAll','retainAll','length','isEmpty','toList','removeAll','any','forEach','map',], +-'dart.collection.HashMap': const ['remove','containsKey','forEach','clear','keys','putIfAbsent','addAll','values',], +-'dart.io.FileSystemEntity': const ['isDirectorySync','path','typeSync','existsSync','isDirectory','identicalSync','isFileSync','type','isFile','statSync','deleteSync','isLinkSync','parentOf','renameSync','isLink','readAsStringSync','identical','rename','toString','delete','exists','parent','stat',], +-'dart.io.OSError': const ['errorCode','toString',], +-'dart.async.StreamTransformer': const ['bind',], +-'dart.core.Runes': const ['toList','any','elementAt','iterator','single','first','forEach','last',], +-'dart.core.Object': const ['toString','toJson','hashCode','discardListChages','reverse','map','lightDom','getName','where','add','containsKey','format','setTable','getClass','getNamespace','getId','getCell','getSize','setNamespace','equals','setColumn','getColumnName','getForeignTableName','setDatabase','setAttribute','setId','getChild','body','setPrevious','getIndex','getParent','getChildAt','getChildCount','getValue','getRoot','POST','GET','getPackage','setSchema','clone','getType','then','isInheritance','isVisible','getDartName','getPlatform','setPosition','setPackage','requiresTransactionInPostgres','setAppData','getSchema','getBuildProperty','getPrevious','getTerminal','n','replaceWith','setChild','setPlatform','run','removeItem','getAllItems','bytes','compareTo','getAttribute','setPreviousIndex','isEmpty','getEdgeAt','isVertex','writeExternal','isEdge','getEdgeCount','isConnectable','setValue','isCollapsed','getStyles','setRoot','getStyle','getGeometry','noSuchMethod','contains','elementAt','e',], +-'dart.core.StringSink': const ['write','writeln','writeCharCode','toString','writeAll',], +-'dart.io.Stdin': const ['pipe','readLineSync','transform','listen',], +-'dart.io.HttpServer': const ['bind','listen','close','connectionsInfo','bindSecure','address','port','idleTimeout','serverHeader','autoCompress','asBroadcastStream','transform','addRequestHandler','listenOn','on',], +-'dart.io.HttpResponse': const ['close','write','statusCode','headers','add','done','redirect','addStream','detachSocket','reasonPhrase','writeln','addError','writeCharCode','writeAll','flush','toString','when','cookies','contentLength','addString','getLogs','listen','persistentConnection','deadline',], +-'dart.io.HttpRequest': const ['listen','uri','session','drain','transform','response','toString','cookies','method','fold','connectionInfo','pipe','asBroadcastStream','toList','timeout','takeWhile','take','skipWhile','singleWhere','map','lastWhere','join','handleError','skip','firstWhere','expand','every','elementAt','distinct','asyncMap','asyncExpand','any','toSet','contains','where','reduce','forEach','headers','path',], +-'dart.collection.SplayTreeMap': const ['forEach','containsKey','remove','keys','values','firstKeyAfter','lastKeyBefore','clear','length',], +-'dart.io.HttpClient': const ['post','getUrl','openUrl','close','postUrl','get','open','addCredentials','patchUrl','shutdown','put','delete','addProxyCredentials','findProxyFromEnvironment',], +-'dart.io.HttpClientRequest': const ['close','add','write','addStream','cookies',], +-'dart.io.Platform': const ['isWindows','script','environment','operatingSystem','pathSeparator',], +-'dart.collection.LinkedHashSet': const ['add','map','contains','toList','addAll','remove',], +-'dart.io.RandomAccessFile': const ['lengthSync','readIntoSync','close','closeSync','writeStringSync','writeString','writeFromSync','length','readInto','read','readSync','writeFrom','readListSync','flushSync','positionSync','setPosition','writeListSync','setPositionSync','unlock','lock','unlockSync','readList','lockSync','readByteSync','position','writeList','writeByteSync',], +-'dart.core.num': const ['round','toDouble','toInt','floor','abs','toString','parse','ceil','toStringAsFixed','isNaN','compareTo','roundToDouble','remainder','hashCode','clamp','isInfinite','isNegative','truncate','toStringAsPrecision','toStringAsExponential','isFinite','truncateToDouble','toRadixString',], +-'dart.dom.html.HttpRequest': const ['send','open','getString','abort','setRequestHeader','request','getAllResponseHeaders','overrideMimeType','requestCrossOrigin','getResponseHeader','postFormData','onLoadEnd','onError','onLoad','DONE','withCredentials','onReadyStateChange','onLoadStart',], +-'dart.dom.html.Event': const ['preventDefault','toString','stopImmediatePropagation','stopPropagation','target','currentTarget',], +-'dart.dom.html.FileReader': const ['readAsArrayBuffer','readAsDataUrl','readAsText','onError','onLoadEnd','result',], +-'dart.core.Pattern': const ['allMatches','matchAsPrefix','toString','firstMatch','pattern','codeUnitAt',], +-'dart.io.ContentType': const ['parse','toString','charset','mimeType','value','parameters','subType','primaryType',], +-'dart.io.HttpHeaders': const ['set','contentType','ifModifiedSince','value','add','host','forEach','date','removeAll','clear','remove','noFolding','contentLength','port','expires','chunkedTransferEncoding','persistentConnection','toString','CONTENT_TYPE','data',], +-'dart.typed_data.Uint8List': const ['setRange','sublist','fillRange','setAll','length','buffer','toString','toList','lastIndexOf','indexOf','join','removeRange','removeLast','clear','addAll','add',], +-'dart.async.StreamSink': const ['close','addStream','add','addError',], +-'dart.typed_data.ByteData': const ['getUint32','setUint32','getUint8','setUint64','getInt32','getUint16','getUint64','setUint16','getInt16','setInt64','setInt32','setInt16','setFloat64','getInt64','setInt8','getFloat64','getFloat32','setFloat32','getInt8','setUint8',], +-'dart.io.HttpClientResponse': const ['listen','toList','transform','drain','fold','pipe','detachSocket',], +-'dart.core.BidirectionalIterator': const ['moveNext','movePrevious',], +-'dart.mirrors.ClosureMirror': const ['invoke','apply','function',], +-'dart.typed_data.Int32x4': const ['x','signMask','select',], +-'dart.js.JsObject': const ['callMethod','hasProperty','toString','deleteProperty','instanceof',], +-'dart.dom.html.Node': const ['remove','ELEMENT_NODE','insertBefore','replaceWith','insertAllBefore','querySelector','localName','text','append','setMenubarOrientation','getElementsByTagName','getElementsByClassName','nodes','parentNode','getElementById','firstChild','parent','contains','tagName','value','toString','name','querySelectorAll','clone','attributes','nextNode','nodeType','click','bind','outerHtml','dispatchEvent','on','childNodes',], +-'dart.core.RuneIterator': const ['moveNext','reset',], +-'dart.mirrors.DeclarationMirror': const ['isPrivate','simpleName','metadata','isSubclassOf','qualifiedName','parameters','invoke',], +-'dart.dom.html.History': const ['pushState','back','replaceState','length',], +-'dart.dom.html.CssClassSet': const ['add','remove','toggle','clear','contains','addAll','removeAll','toString','firstWhere','first','toggleAll','length','containsAll',], +-'dart.dom.html.Document': const ['querySelector','querySelectorAll','documentElement','createElement','title','body','removeEventListener','addEventListener','getElementsByTagName','createElementNS','query','window','queryAll',], +-'dart.mirrors.IsolateMirror': const ['rootLibrary',], +-'dart.mirrors.ObjectMirror': const ['invoke','getField','setField',], +-'dart.dom.html.DivElement': const ['append','classes','style','setInnerHtml','remove','querySelector','id','getComputedStyle','appendText','text','querySelectorAll','onDragEnd','onDrag','onDragStart','draggable','innerHtml','insertAdjacentElement','appendHtml','className','children','focus','query','nodes','createShadowRoot','clone','attributes','queryAll','click','onMouseDown','onClick','hidden','addEventListener','onMouseMove','scrollIntoView','onKeyDown','title','getBoundingClientRect','onMouseUp','dispatchEvent','insertAdjacentText','contentEditable','scrollTop','scrollByLines','bind','insertBefore','xtag','insertAdjacentHtml','matches','setAttribute','on','onKeyUp','getElementsByClassName',], +-'dart.dom.html.NodeValidatorBuilder': const ['allowNavigation','allowElement','allowHtml5','allowSvg','allowInlineStyles','allowTextElements','allowTemplating','allowCustomElement','allowTagExtension','allowImages',], +-'dart.dom.html.Console': const ['timeEnd','time','timeStamp','warn','log','error','groupEnd','info','debug','groupCollapsed','group','dir',], +-'dart.dom.html.ElementUpgrader': const ['upgrade',], +-'dart.async.StreamIterator': const ['moveNext','cancel',], +-'dart.io.SystemEncoding': const ['decode',], +-'dart.collection.UnmodifiableListView': const ['where','contains','any','length','join','firstWhere',], +-'dart.core.Error': const ['safeToString','toString',], +-'dart.convert.Utf8Encoder': const ['bind','convert','startChunkedConversion',], +-'dart.dom.html.DomImplementation': const ['createHtmlDocument',], +-'dart.dom.html.DocumentFragment': const ['querySelectorAll','append','clone','nodes','children','setInnerHtml','querySelector','queryAll','query','remove','ownerDocument',], +-'dart.dom.html.ShadowRoot': const ['querySelector','querySelectorAll','host','children','append','contains','query','activeElement','supported','nodes','firstChild','getElementsByTagName','text','innerHtml','olderShadowRoot',], +-'dart.mirrors.TypeMirror': const ['qualifiedName','isSubtypeOf','reflectedType','newInstance','isAssignableTo','simpleName','typeArguments','originalDeclaration','toString','referent','hasReflectedType','isPrivate','typeVariables','owner','invoke','isOriginalDeclaration',], +-'dart.io.ServerSocket': const ['bind','close','listen',], +-'dart.dom.html.PerformanceNavigation': const ['type','redirectCount',], +-'dart.dom.html.Performance': const ['now','timing','navigation',], +-'dart.dom.html.PerformanceTiming': const ['navigationStart',], +-'dart.typed_data.ByteBuffer': const ['asUint8List','asUint32List','asInt32List','asByteData','asFloat64x2List','asInt32x4List','asFloat32x4List','asFloat64List','asFloat32List','asUint64List','asInt64List','asUint16List','asInt16List','asUint8ClampedList','asInt8List',], +-'dart.io.WebSocket': const ['add','listen','close','connect','where','map','send',], +-'dart.convert.JsonEncoder': const ['convert','startChunkedConversion',], +-'dart.convert.JsonDecoder': const ['convert','startChunkedConversion',], +-'dart.core.bool': const ['toString','should','hashCode','isAssignableFrom','parse','containsKey',], +-'dart.core.FormatException': const ['toString',], +-'dart.dom.html.WindowBase': const ['postMessage','navigator','close','alert',], +-'dart.dom.html.ButtonElement': const ['text','onClick','classes','attributes','style','append','type','setInnerHtml','children','onMouseOut','onMouseOver','click','disabled','dataset','appendText',], +-'dart.core.Exception': const ['toString','printStackTrace',], +-'dart.dom.html.DataTransfer': const ['setData','setDragImage','types','effectAllowed','dropEffect','getData','files',], +-'dart.math.Point': const ['x','y','distanceTo','magnitude',], +-'dart.dom.html.LIElement': const ['classes','append','style','text','querySelector','innerHtml','dispatchEvent','children','dataset','className','nodes','remove','value',], +-'dart.dom.html.CanvasRenderingContext2D': const ['lineTo','beginPath','fillRect','moveTo','stroke','drawImage','closePath','restore','translate','save','scale','fill','getImageData','clearRect','setTransform','strokeRect','rotate','putImageData','fillStyle','arc','transform','fillText','strokeStyle','createImageData','createPatternFromImage','clip','lineWidth','drawImageToRect','strokeText','font','rect','drawImageScaledFromSource','setFillColorRgb','createLinearGradient','bezierCurveTo','drawImageScaled','measureText','setLineDash','shadowBlur','shadowOffsetX','shadowOffsetY','shadowColor','quadraticCurveTo','imageSmoothingEnabled','textAlign','createRadialGradient','textBaseline','globalAlpha','lineCap',], +-'dart.io.HeaderValue': const ['parse',], +-'dart.dom.html.ScriptElement': const ['src','type','async','remove','text',], +-'dart.dom.html.MouseEvent': const ['preventDefault','stopPropagation','target','dataTransfer','page','client','ctrlKey','stopImmediatePropagation','metaKey','shiftKey',], +-'dart.io.RawSocket': const ['write','listen','close','connect','read','available','shutdown','setOption',], +-'dart.io.RawSecureSocket': const ['secure','connect','shutdown','listen','secureServer','write','read',], +-'dart.dom.web_sql.SqlDatabase': const ['transaction','supported',], +-'dart.dom.web_sql.SqlTransaction': const ['executeSql',], +-'dart.dom.web_sql.SqlResultSetRowList': const ['length','elementAt','isNotEmpty','item','forEach',], +-'dart.convert.AsciiCodec': const ['encode','decode',], +-'dart.dom.html.EventStreamProvider': const ['forTarget','forElement',], +-'dart.dom.html.MutationObserver': const ['observe','disconnect','takeRecords',], +-'dart.dom.html.UListElement': const ['queryAll','append','style','id','children','remove','query','insertBefore','classes',], +-'dart.dom.html.VideoElement': const ['canPlayType','load','pause','play','autoplay','remove','src',], +-'dart.dom.html.MediaError': const ['code',], +-'dart.dom.html.TimeRanges': const ['start','end',], +-'dart.dom.html.SourceElement': const ['remove',], +-'dart.dom.html.ObjectElement': const ['remove','getAttribute',], +-'dart.dom.html.OptionElement': const ['value','text','selected','label','appendText',], +-'dart.dom.html.SpanElement': const ['classes','text','style','append','appendText','onMouseOut','onMouseOver','onClick','attributes','remove','draggable','id','outerHtml','innerHtml','setAttribute','querySelector','scrollIntoView',], +-'dart.dom.html.Geolocation': const ['getCurrentPosition','watchPosition',], +-'dart.dom.html.Coordinates': const ['accuracy','longitude','latitude','speed','heading','altitudeAccuracy','altitude',], +-'dart.dom.html.ImageElement': const ['remove','width','height','onLoad','src','style','crossOrigin','classes','className','id','onDragStart',], +-'dart.mirrors.MethodMirror': const ['parameters','isGetter','isConstructor','returnType','owner','simpleName','location','source','isStatic',], +-'dart.dom.html.Storage': const ['containsKey','clear','remove','length','keys','containsValue',], +-'dart.convert.ChunkedConversionSink': const ['add','close','specialI',], +-'dart.collection.ListQueue': const ['add','removeFirst','addAll','addLast','removeLast','forEach','toList','removeWhere','addFirst',], +-'dart.dom.html.CanvasElement': const ['getContext','style','width','height','context2D','toDataUrl','getContext3d','onMouseUp','onMouseDown','getBoundingClientRect','onMouseMove','onClick','onMouseOut','className','onMouseOver','setAttribute','remove','context2d','focus',], +-'dart.dom.html.KeyboardEvent': const ['preventDefault','which','stopPropagation','ctrlKey','keyCode','stopImmediatePropagation','metaKey','altKey','shiftKey','getModifierState',], +-'dart.dom.html.WebSocket': const ['send','close','onMessage','onClose','onError','onOpen','readyState','url','sendTypedData','binaryType',], +-'dart.io.WebSocketTransformer': const ['upgrade','isUpgradeRequest',], +-'dart.core.Symbol': const ['toString','length',], +-'dart.js.JsFunction': const ['apply',], +-'dart.io.InternetAddress': const ['address','host','lookup','toString','isLoopback',], +-'dart.convert.Latin1Codec': const ['decode',], +-'dart.dom.html.ElementEvents': const ['click','load','change','keyPress','drop','dragOver','dragEnter','input','keyDown','dragLeave','dragEnd','dragStart','mouseOut','mouseMove','keyUp','loadedMetadata',], +-'dart.dom.html.TableCellElement': const ['setInnerHtml','style','append','text','insertAdjacentElement','colSpan','setAttribute','innerHtml','cellIndex',], +-'dart.dom.html.TableRowElement': const ['append','attributes','classes','onClick','children','onMouseOut','onMouseOver','remove','insertCell','cells','createFragment','addCell','query','outerHtml',], +-'dart.convert.Converter': const ['convert','startChunkedConversion',], +-'dart.dom.html.FormData': const ['append','appendBlob',], +-'dart.io.ProcessException': const ['toString',], +-'dart.dom.html.Text': const ['remove','text','toString',], +-'dart.dom.html.AnchorElement': const ['href','text','onClick','id','classes','append','dispatchEvent','replaceWith','download','click','setAttribute','appendText',], +-'dart.dom.svg.LineElement': const ['setAttribute',], +-'dart.dom.svg.RectElement': const ['setAttribute','attributes',], +-'dart.dom.svg.EllipseElement': const ['setAttribute',], +-'dart.dom.svg.PolylineElement': const ['attributes',], +-'dart.dom.svg.CircleElement': const ['setAttribute',], +-'dart.dom.svg.PathElement': const ['setAttribute','createSvgPathSegLinetoAbs','createSvgPathSegMovetoAbs',], +-'dart.dom.html.HeadingElement': const ['text','classes','appendText','append','id',], +-'dart.dom.html.TableElement': const ['insertRow','createFragment','append','children','createTBody','deleteRow','addRow','query','querySelector',], +-'dart.io.HttpConnectionInfo': const ['remoteAddress','remotePort','localPort','remoteHost',], +-'dart.dom.html.FormElement': const ['append','submit','children','remove',], +-'dart.io.Cookie': const ['value','toString','path',], +-'dart.dom.html.InputElement': const ['focus','select','value','remove','type','checkValidity','dataset','onKeyDown','setSelectionRange','dispatchEvent','selectionStart','selectionEnd','setAttribute','bind','checked','attributes','blur','setRangeText','click','onChange','placeholder','id','onKeyUp','onBlur','onKeyPress','autocomplete','onPaste','defaultChecked','onFocus','disabled',], +-'dart.io.Socket': const ['close','connect','transform','destroy','add','listen','write','addStream','pipe','address','read','writeList','setOption','flush','map','readList','available',], +-'dart.mirrors.ParameterMirror': const ['type','isOptional','defaultValue',], +-'dart.convert.Codec': const ['fuse','encode','decode',], +-'dart.dom.indexed_db.Database': const ['transaction','createObjectStore','close',], +-'dart.dom.indexed_db.Transaction': const ['objectStore','onAbort','onError','onComplete',], +-'dart.dom.indexed_db.ObjectStore': const ['put','delete','createIndex','getObject','index','openCursor','clear',], +-'dart.dom.svg.SvgSvgElement': const ['append','setAttribute','createFragment','createSvgPoint','getScreenCtm','onMouseUp','onMouseMove',], +-'dart.dom.svg.Point': const ['matrixTransform',], +-'dart.dom.svg.Matrix': const ['inverse',], +-'dart.dom.html.WheelEvent': const ['preventDefault','stopPropagation',], +-'dart.dom.svg.AnimatedRect': const ['baseVal',], +-'dart.dom.html.SelectElement': const ['append','focus','remove','classes','tabIndex','options','selectedIndex','querySelectorAll','multiple','value',], +-'dart.dom.html.LabelElement': const ['query','text','append','htmlFor','style','appendText','classes',], +-'dart.io.HttpSession': const ['id','destroy','clear','containsKey','isNew','remove','onTimeout',], +-'dart.dom.indexed_db.IdbFactory': const ['open','deleteDatabase','supported','supportsDatabaseNames','getDatabaseNames',], +-'dart.dom.indexed_db.Request': const ['result',], +-'dart.dom.indexed_db.Index': const ['openCursor',], +-'dart.dom.indexed_db.KeyRange': const ['upperBound_','bound_','lowerBound_','only_',], +-'dart.dom.indexed_db.CursorWithValue': const ['delete',], +-'dart.core.NoSuchMethodError': const ['toString',], +-'dart.isolate.Isolate': const ['spawn','spawnUri','resume','addOnExitListener','removeErrorListener','addErrorListener','kill','ping','pause','setErrorsFatal',], +-'dart.dom.html.TemplateElement': const ['decorate','content',], +-'dart.dom.html.TreeWalker': const ['nextNode',], +-'dart.dom.html.StyleElement': const ['remove','appendText','text','sheet','attributes','type','appendHtml','dataset','append','innerHtml',], +-'dart.dom.html.EventTarget': const ['error','result','matchesWithAncestors','nodeName','matches','classes','dispatchEvent','removeEventListener','addEventListener','status','parent','value','hashCode',], +-'dart.collection_helpers.equality.Equality': const ['hash','equals','isValidKey',], +-'dart.collection_helpers.equality.SetEquality': const ['hash','equals',], +-'dart.collection_helpers.equality.MapEquality': const ['hash','equals',], +-'dart.collection_helpers.equality.ListEquality': const ['hash','equals',], +-'dart.collection_helpers.equality.IterableEquality': const ['hash','equals',], +-'dart.collection_helpers.equality.UnorderedIterableEquality': const ['hash','equals',], +-'dart.io.SecureSocket': const ['initialize','close','connect','listen','write','add','fold','writeln','secure','transform',], +-'dart.io.HttpDate': const ['parse','format',], +-'dart.math.Rectangle': const ['top','left','containsPoint','height','width','topLeft','intersection','topRight','intersects','containsRectangle','boundingBox','snap',], +-'dart.dom.html.ContentElement': const ['getDistributedNodes',], +-'dart.io.SocketException': const ['toString',], +-'dart.dom.html.TextAreaElement': const ['style','focus','select','rows','attributes','setSelectionRange','value','appendText','remove',], +-'dart.dom.html.LinkElement': const ['href','replaceWith','rel',], +-'dart.dom.html.ParagraphElement': const ['text','appendHtml','classes','addHtml','hidden',], +-'dart.typed_data.Int32List': const ['setRange','indexOf','sublist','removeRange','removeLast','clear','addAll','add','setAll',], +-'dart.dom.web_gl.RenderingContext': const ['ARRAY_BUFFER','texParameteri','bindBuffer','bindFramebuffer','TEXTURE_2D','enable','deleteShader','getUniformLocation','bindTexture','clear','createTexture','detachShader','attachShader','getAttribLocation','createBuffer','enableVertexAttribArray','vertexAttribPointer','FLOAT','STATIC_DRAW','createShader','shaderSource','compileShader','viewport','useProgram','clearColor','bufferDataTyped','getShaderParameter','uniformMatrix4fv','getShaderInfoLog','bindRenderbuffer','deleteTexture','deleteProgram','RGBA','linkProgram','createProgram','disableVertexAttribArray','disable','getProgramParameter','blendFunc','drawArrays','getProgramInfoLog','TRIANGLES','lineWidth','COMPILE_STATUS','texImage2DTyped','NEAREST','createFramebuffer','getExtension','framebufferTexture2D','framebufferRenderbuffer','renderbufferStorage','createRenderbuffer','ELEMENT_ARRAY_BUFFER','uniformMatrix3fv','uniform2f','UNSIGNED_BYTE','deleteFramebuffer','deleteRenderbuffer','TEXTURE_MIN_FILTER','TEXTURE_MAG_FILTER','CLAMP_TO_EDGE','DEPTH_TEST','DEPTH_BUFFER_BIT','texImage2DImage','COLOR_BUFFER_BIT','LINK_STATUS','FRAGMENT_SHADER','VERTEX_SHADER','bufferData','TEXTURE_WRAP_S','TEXTURE_WRAP_T','texImage2DCanvas','LINEAR','UNSIGNED_SHORT','texImage2D','drawElements','pixelStorei','colorMask','depthFunc','TRIANGLE_STRIP','activeTexture','TEXTURE0','depthMask','FRAMEBUFFER','UNPACK_FLIP_Y_WEBGL','generateMipmap','uniform1i',], +-'dart.typed_data.Float32List': const ['sublist','indexOf','buffer','setRange','length',], +-'dart.dom.html.DirectoryEntry': const ['getFile','createDirectory','createFile','createReader','getDirectory','removeRecursively','toUrl','fullPath','toString',], +-'dart.dom.html.Entry': const ['moveTo','isFile','copyTo','isDirectory','fullPath','name','remove','getMetadata','createWriter','file','getParent','toUrl',], +-'dart.dom.html.DirectoryReader': const ['readEntries',], +-'dart.dom.html.KeyCode': const ['DOWN','RIGHT','LEFT','TAB','UP','ESC','ENTER','isCharacterKey','SPACE','NUM_SOUTH','NUM_NORTH','NUM_EAST','NUM_WEST','NUM_NORTH_EAST','NUM_SOUTH_EAST','R',], +-'dart.pkg.collection.iterable_zip.IterableZip': const ['map','toList',], +-'dart.convert.LineSplitter': const ['convert',], +-'dart.dom.html.HttpRequestUpload': const ['onProgress','onError','onTimeout',], +-'dart.dom.html.File': const ['name','slice','readAsBytesSync','existsSync',], +-'dart.dom.html.Events': const ['error','message','load','hashChange','popState','resize','loadEnd',], +-'dart.dom.html.Url': const ['createObjectUrl','revokeObjectUrl','createObjectUrlFromBlob','createObjectUrlFromStream',], +-'dart.dom.html.RtcIceCandidate': const ['candidate','sdpMLineIndex',], +-'dart.dom.html.RtcPeerConnection': const ['setLocalDescription','createDataChannel','createOffer','createAnswer',], +-'dart.io.RawDatagramSocket': const ['bind','close','receive','send','listen',], +-'dart.pkg.collection.equality.DeepCollectionEquality': const ['equals','hash',], +-'dart.pkg.collection.priority_queue.PriorityQueue': const ['addAll','contains','removeFirst','add','removeAll',], +-'dart.convert.StringConversionSink': const ['add','asUtf8Sink','close','asStringSink','addSlice',], +-'dart.dom.html.ImageData': const ['data',], +-'dart.dom.html.PreElement': const ['appendText','text','append','classes',], +-'dart.dom.html.MediaStream': const ['stop',], +-'dart.dom.html.DomParser': const ['parseFromString',], +-'dart.dom.html.CustomEvent': const ['stopImmediatePropagation','preventDefault','stopPropagation',], +-'dart.typed_data.Uint16List': const ['buffer','sublist','setRange','removeRange','removeLast','clear','addAll','add','length',], +-'dart.dom.html.CanvasGradient': const ['addColorStop',], +-'dart.dom.html.Notification': const ['requestPermission',], +-'dart.dom.svg.Length': const ['value','valueAsString',], +-'dart.dom.svg.AnimatedLength': const ['baseVal',], +-'dart.dom.svg.PointList': const ['getItem',], +-'dart.mirrors.SourceLocation': const ['line',], +-'dart.DartGrammarDefinition': const ['build',], +-'dart.dom.html.TextMetrics': const ['width',], +-'dart.dom.html.CssRect': const ['width','height','top','left','topLeft',], +-'dart.dom.html.KeyboardEventStream': const ['onKeyDown',], +-'dart.dom.html.CssRule': const ['selectorText',], +-'dart.dom.html.CssStyleRule': const ['style','selectorText',], +-'dart.dom.html.Selection': const ['removeAllRanges','collapse','getRangeAt',], +-'dart.dom.html.CheckboxInputElement': const ['checked','attributes','classes','value',], +-'dart.dom.html.TextInputElement': const ['classes','value','focus','select','className','onKeyDown','style',], +-'dart.dom.html.DateInputElement': const ['classes',], +-'dart.dom.html.RangeInputElement': const ['style','attributes','onChange','value','step','max','min',], +-'dart.dom.html.AnimationTimeline': const ['play',], +-'dart.dom.html.AnimationPlayer': const ['play',], +-'dart.dom.html.GlobalEventHandlers': const ['clickEvent',], +-'dart.dom.html.TouchEvent': const ['preventDefault','supported','stopPropagation',], +-'dart.dom.html.AudioElement': const ['canPlayType','load','append','play','pause','remove',], +-'dart.io.ProcessSignal': const ['watch',], +-'dart.convert.Utf8Decoder': const ['convert','startChunkedConversion',], +-'dart.dom.html.AnimationEvent': const ['preventDefault','stopImmediatePropagation',], +-'dart.dom.html.FocusEvent': const ['stopImmediatePropagation',], +-'dart.dom.html.Touch': const ['page','client',], +-'dart.async.DeferredLibrary': const ['load',], +-'dart.dom.html.TableSectionElement': const ['append','innerHtml','rows','createFragment','addRow',], +-'dart.mirrors.Mirror': const ['methods','invoke','type','delegate','members',], +-'dart.core.StateError': const ['toString',], +-'dart.io.FileMode': const ['APPEND','READ','WRITE',], +-'dart.dom.html.CssStyleDeclarationBase': const ['display','backgroundColor','opacity','borderLeftWidth',], +-'dart.dom.html.IFrameElement': const ['style','src',], +-'dart.io.FileSystemException': const ['toString',], +-'dart.dom.html.Screen': const ['width','height','pixelDepth',], +-'dart.core.ArgumentError': const ['toString',], +-'dart.dom.html.Blob': const ['slice',], +-'dart.dom.svg.PatternElement': const ['setAttribute','append',], +-'dart.dom.svg.DefsElement': const ['append',], +-'dart.dom.svg.PathSegList': const ['appendItem','clear','length','getItem',], +-'dart.dom.html.FileList': const ['length','item',], +-'dart.dom.html.FileError': const ['NOT_FOUND_ERR','code',], +-'dart.mirrors.VariableMirror': const ['type','isFinal','isStatic',], +-'dart.io.HttpStatus': const ['NOT_FOUND',], +-'dart.typed_data.Float64List': const ['sublist','indexOf','setRange',], +-'dart.typed_data.Float32x4': const ['shuffle','shuffleMix','scale','signMask','clamp','withX','withY','w','z','y','x',], +-'dart.pkg.typed_data.typed_buffers.Int32x4Buffer': const ['add',], +-'dart.dom.html.NumberInputElement': const ['step','max','min','valueAsNumber',], +-'dart.dom.html.ValidityState': const ['valid',], +-'dart.dom.html.CssStyleSheet': const ['ownerNode','insertRule','addRule',], +-'dart.io.ZLibCodec': const ['decode',], +-'dart.collection.HasNextIterator': const ['next',], +-'dart.isolate.RawReceivePort': const ['close',], +-'dart.mirrors.TypeVariableMirror': const ['simpleName','isSubtypeOf','isAssignableTo','owner',], +-'dart.typed_data.implementation.NativeByteBuffer': const ['asFloat64List','asFloat32List','asInt32List',], +-'dart.typed_data.implementation.NativeFloat32x4List': const ['length',], +-'dart.typed_data.implementation.NativeFloat32List': const ['sublist',], +-'dart.typed_data.implementation.NativeInt32x4List': const ['length',], +-'dart.typed_data.implementation.NativeFloat64x2List': const ['length',], +-'dart.typed_data.implementation.NativeFloat64List': const ['sublist',], +-'dart.typed_data.implementation.NativeTypedArray': const ['length',], +-'dart.typed_data.implementation.NativeTypedArrayOfDouble': const ['setRange',], +-'dart.typed_data.implementation.NativeTypedArrayOfInt': const ['setRange',], +-'dart.typed_data.implementation.NativeInt32x4': const ['w','z','y','x',], +-'dart.dom.svg.SvgElement': const ['isTagSupported','clone','setAttribute','children','setInnerHtml','attributes',], +-'dart.dom.svg.GElement': const ['append','querySelector','id',], +-'dart.dom.html.ProgressEvent': const ['toString',], +-'dart.core.RangeError': const ['toString','checkValidRange','checkNotNegative','checkValueInInterval','checkValidIndex',], +-'dart.dom.html.TouchList': const ['length','first','isEmpty','isNotEmpty',], +-'dart.dom.html.FieldSetElement': const ['append','querySelector',], +-'dart.dom.html.ShadowElement': const ['getDistributedNodes',], +-'dart.dom.html.KeyEvent': const ['keyCode','type','preventDefault',], +-'dart.dom.html.NodeList': const ['length','add',], +-'dart.dom.html.DomStringList': const ['length',], +-'dart.dom.html.HtmlCollection': const ['length','forEach','contains',], +-'dart.dom.html.Range': const ['createContextualFragment','selectNodeContents','insertNode','setEndAfter',], +-'dart.dom.html.NodeTreeSanitizer': const ['sanitizeTree',], +-'dart.dom.html.MimeTypeArray': const ['length',], +-'dart.dom.html.PluginArray': const ['length',], +-'dart.dom.html.SourceBufferList': const ['length',], +-'dart.dom.html.SpeechGrammarList': const ['length',], +-'dart.dom.html.TextTrackCueList': const ['length',], +-'dart.dom.html.TextTrackList': const ['length',], +-'dart.dom.html.Dimension': const ['value','toString',], +-'dart.dom.html.UriPolicy': const ['allowsUri',], +-'dart.dom.html.NodeValidator': const ['allowsAttribute','allowsElement',], +-'dart.dom.html.Worker': const ['terminate',], +-'dart.typed_data.Int16List': const ['sublist','buffer','contains','setRange','removeRange','removeLast','clear','addAll','add',], +-'dart.dom.indexed_db.Cursor': const ['next',], +-'dart.dom.svg.LengthList': const ['length','getItem',], +-'dart.dom.svg.NumberList': const ['length','getItem',], +-'dart.dom.svg.StringList': const ['length','getItem',], +-'dart.dom.svg.TransformList': const ['length','getItem',], +-'dart.js.JsArray': const ['length','addAll','insert','removeRange','removeAt','add','setRange','removeLast',], +-'dart.dom.html.ApplicationCache': const ['swapCache',], +-'dart.dom.web_audio.AudioContext': const ['createBufferSource','createOscillator','destination','createPanner','createGain',], +-'dart.dom.html.FileUploadInputElement': const ['click',], +-'dart.dom.html.DomRectReadOnly': const ['top','left','height','width',], +-'dart.typed_data.Int8List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add','buffer',], +-'dart.dom.web_audio.AudioBufferSourceNode': const ['connectNode','start','stop',], +-'dart.dom.html.FileEntry': const ['file','getParent','toUrl','getMetadata',], +-'dart.dom.html.CustomStream': const ['listen',], +-'dart.dom.html.TrackElement': const ['defaultValue',], +-'dart.dom.web_audio.OscillatorNode': const ['connectNode',], +-'dart.dom.html.StorageQuota': const ['queryInfo',], +-'dart.collection.DoubleLinkedQueue': const ['add',], +-'dart.core.TypeError': const ['toString',], +-'dart.core.AssertionError': const ['toString',], +-'dart.profiler.Metrics': const ['register',], +-'dart.collection.LinkedList': const ['remove','addFirst','clear','add',], +-'dart.typed_data.Uint8ClampedList': const ['sublist',], +-'dart.typed_data.Float64x2': const ['y','x','withX',], +-'dart.convert.ByteConversionSink': const ['close','add','addSlice',], +-'dart.convert.ClosableStringSink': const ['close','write',], +-'dart.mirrors.TypedefMirror': const ['isSubtypeOf','isAssignableTo','referent',], +-'dart.mirrors.FunctionTypeMirror': const ['isSubtypeOf','isAssignableTo','returnType','parameters','isOriginalDeclaration',], +-'dart.mirrors.LibraryDependencyMirror': const ['metadata',], +-'dart.test.stream_from_iterable.IterableTest': const ['run',], +-'dart.io.SecureServerSocket': const ['bind','close','listen',], +-'dart.io.RawServerSocket': const ['bind','listen','close',], +-'dart.typed_data.Uint64List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add',], +-'dart.typed_data.Int64List': const ['sublist','setRange','removeRange','removeLast','clear','addAll','add',], +-'dart.io.StdioType': const ['name',], +-'dart.io.HttpConnectionsInfo': const ['total','idle','active',], +-'dart.io.RawSecureServerSocket': const ['bind','close','listen',], +-'dart.io.ServerSocketReference': const ['create',], +-'dart.io.NetworkInterface': const ['list',], +-'dart.io.ZLibDecoder': const ['convert',], +-'dart.io.ZLibEncoder': const ['convert',], +-'dart.pkg.async.results.ValueResult': const ['value',], +-'dart.pkg.async.stream_zip.StreamZip': const ['toList',], +-'dart.pkg.async.results.Result': const ['flatten','release',], +-'dart.pkg.async.results.ErrorResult': const ['stackTrace','error',], +-'dart.dom.html.OptGroupElement': const ['append',], +-'dart.dom.html.UnknownElement': const ['query',], +-'dart.dom.web_audio.AudioParam': const ['value','setValueAtTime',], +-'dart.dom.html.RadioButtonInputElement': const ['checked',], +-'dart.dom.web_audio.BiquadFilterNode': const ['connectNode',], +-'dart.async.StreamConsumer': const ['addStream','close',], +-'dart.dom.html.FileSystem': const ['root',], +-'dart.dom.html.FileWriter': const ['write','abort',], +-'dart.dom.html.OutputElement': const ['scrollIntoView',], +-'dart.dom.html.Css': const ['supports',], +-'dart.io.IOException': const ['toString',], +-'dart.dom.html.ButtonInputElement': const ['value','onClick',], +-}; +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart +deleted file mode 100644 +index 7cba4580f7e..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart ++++ /dev/null +@@ -1,278 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/provisional/completion/completion_core.dart' +- show CompletionContributor, CompletionRequest; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/completion_core.dart'; +-import 'package:analysis_server/src/services/completion/completion_performance.dart'; +-import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart'; +-import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart'; +-import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/label_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart'; +-import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/task/model.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-/** +- * [DartCompletionManager] determines if a completion request is Dart specific +- * and forwards those requests to all [DartCompletionContributor]s. +- */ +-class DartCompletionManager implements CompletionContributor { +- /** +- * The [contributionSorter] is a long-lived object that isn't allowed +- * to maintain state between calls to [DartContributionSorter#sort(...)]. +- */ +- static DartContributionSorter contributionSorter = new CommonUsageSorter(); +- +- @override +- Future> computeSuggestions( +- CompletionRequest request) async { +- request.checkAborted(); +- if (!AnalysisEngine.isDartFileName(request.source.shortName)) { +- return EMPTY_LIST; +- } +- +- CompletionPerformance performance = +- (request as CompletionRequestImpl).performance; +- DartCompletionRequestImpl dartRequest = +- await DartCompletionRequestImpl.from(request); +- +- // Don't suggest in comments. +- if (dartRequest.target.isCommentText) { +- return EMPTY_LIST; +- } +- +- SourceRange range = +- dartRequest.target.computeReplacementRange(dartRequest.offset); +- (request as CompletionRequestImpl) +- ..replacementOffset = range.offset +- ..replacementLength = range.length; +- +- // Request Dart specific completions from each contributor +- Map suggestionMap = +- {}; +- List contributors = [ +- new ArgListContributor(), +- new CombinatorContributor(), +- new FieldFormalContributor(), +- new ImportedReferenceContributor(), +- new InheritedReferenceContributor(), +- new KeywordContributor(), +- new LabelContributor(), +- new LibraryMemberContributor(), +- new LibraryPrefixContributor(), +- new LocalConstructorContributor(), +- new LocalLibraryContributor(), +- new LocalReferenceContributor(), +- new NamedConstructorContributor(), +- // Revisit this contributor and these tests +- // once DartChangeBuilder API has solidified. +- // new OverrideContributor(), +- new StaticMemberContributor(), +- new TypeMemberContributor(), +- new UriContributor(), +- new VariableNameContributor() +- ]; +- for (DartCompletionContributor contributor in contributors) { +- String contributorTag = +- 'DartCompletionManager - ${contributor.runtimeType}'; +- performance.logStartTime(contributorTag); +- List contributorSuggestions = +- await contributor.computeSuggestions(dartRequest); +- performance.logElapseTime(contributorTag); +- request.checkAborted(); +- +- for (CompletionSuggestion newSuggestion in contributorSuggestions) { +- var oldSuggestion = suggestionMap.putIfAbsent( +- newSuggestion.completion, () => newSuggestion); +- if (newSuggestion != oldSuggestion && +- newSuggestion.relevance > oldSuggestion.relevance) { +- suggestionMap[newSuggestion.completion] = newSuggestion; +- } +- } +- } +- +- // Adjust suggestion relevance before returning +- List suggestions = suggestionMap.values.toList(); +- const SORT_TAG = 'DartCompletionManager - sort'; +- performance.logStartTime(SORT_TAG); +- await contributionSorter.sort(dartRequest, suggestions); +- performance.logElapseTime(SORT_TAG); +- request.checkAborted(); +- return suggestions; +- } +-} +- +-/** +- * The information about a requested list of completions within a Dart file. +- */ +-class DartCompletionRequestImpl implements DartCompletionRequest { +- @override +- final AnalysisResult result; +- +- @override +- final ResourceProvider resourceProvider; +- +- @override +- final InterfaceType objectType; +- +- @override +- final Source source; +- +- @override +- final int offset; +- +- @override +- Expression dotTarget; +- +- @override +- Source librarySource; +- +- @override +- CompletionTarget target; +- +- OpType _opType; +- +- final CompletionRequest _originalRequest; +- +- final CompletionPerformance performance; +- +- DartCompletionRequestImpl._( +- this.result, +- this.resourceProvider, +- this.objectType, +- this.librarySource, +- this.source, +- this.offset, +- CompilationUnit unit, +- this._originalRequest, +- this.performance) { +- _updateTargets(unit); +- } +- +- @override +- bool get includeIdentifiers { +- return opType.includeIdentifiers; +- } +- +- @override +- LibraryElement get libraryElement { +- //TODO(danrubel) build the library element rather than all the declarations +- CompilationUnit unit = target.unit; +- if (unit != null) { +- CompilationUnitElement elem = unit.element; +- if (elem != null) { +- return elem.library; +- } +- } +- return null; +- } +- +- OpType get opType { +- if (_opType == null) { +- _opType = new OpType.forCompletion(target, offset); +- } +- return _opType; +- } +- +- @override +- String get sourceContents => result.content; +- +- @override +- SourceFactory get sourceFactory => result.sourceFactory; +- +- /** +- * Throw [AbortCompletion] if the completion request has been aborted. +- */ +- void checkAborted() { +- _originalRequest.checkAborted(); +- } +- +- /** +- * Update the completion [target] and [dotTarget] based on the given [unit]. +- */ +- void _updateTargets(CompilationUnit unit) { +- _opType = null; +- dotTarget = null; +- target = new CompletionTarget.forOffset(unit, offset); +- AstNode node = target.containingNode; +- if (node is MethodInvocation) { +- if (identical(node.methodName, target.entity)) { +- dotTarget = node.realTarget; +- } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { +- dotTarget = node.realTarget; +- } +- } +- if (node is PropertyAccess) { +- if (identical(node.propertyName, target.entity)) { +- dotTarget = node.realTarget; +- } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { +- dotTarget = node.realTarget; +- } +- } +- if (node is PrefixedIdentifier) { +- if (identical(node.identifier, target.entity)) { +- dotTarget = node.prefix; +- } +- } +- } +- +- /** +- * Return a [Future] that completes with a newly created completion request +- * based on the given [request]. This method will throw [AbortCompletion] +- * if the completion request has been aborted. +- */ +- static Future from(CompletionRequest request, +- {ResultDescriptor resultDescriptor}) async { +- request.checkAborted(); +- CompletionPerformance performance = +- (request as CompletionRequestImpl).performance; +- const BUILD_REQUEST_TAG = 'build DartCompletionRequest'; +- performance.logStartTime(BUILD_REQUEST_TAG); +- +- CompilationUnit unit = request.result.unit; +- Source libSource = unit.element.library.source; +- InterfaceType objectType = request.result.typeProvider.objectType; +- +- DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._( +- request.result, +- request.resourceProvider, +- objectType, +- libSource, +- request.source, +- request.offset, +- unit, +- request, +- performance); +- +- performance.logElapseTime(BUILD_REQUEST_TAG); +- return dartRequest; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart +deleted file mode 100644 +index 6dfbf6fb881..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart ++++ /dev/null +@@ -1,24 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * The abstract class [DartContributionSorter] defines the behavior of objects +- * that are used to adjust the relevance of an existing list of suggestions. +- * This is a long-lived object that should not maintain state between +- * calls to it's [sort] method. +- */ +-abstract class DartContributionSorter { +- /** +- * After [CompletionSuggestion]s have been computed, +- * this method is called to adjust the relevance of those suggestions. +- * Return a [Future] that completes when the suggestions have been updated. +- */ +- Future sort(DartCompletionRequest request, +- Iterable suggestions); +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart +deleted file mode 100644 +index 94f43188f5f..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart ++++ /dev/null +@@ -1,78 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- hide Element, ElementKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +- +-/** +- * A contributor for calculating invocation / access suggestions +- * `completion.getSuggestions` request results. +- */ +-class FieldFormalContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- AstNode node = request.target.containingNode; +- if (node is! FieldFormalParameter) { +- return EMPTY_LIST; +- } +- +- // If this is a constructor declaration +- // then compute fields already referenced +- ConstructorDeclaration constructorDecl = +- node.getAncestor((p) => p is ConstructorDeclaration); +- if (constructorDecl == null) { +- return EMPTY_LIST; +- } +- +- // Compute the list of fields already referenced in the constructor +- List referencedFields = new List(); +- for (FormalParameter param in constructorDecl.parameters.parameters) { +- if (param is DefaultFormalParameter && +- param.parameter is FieldFormalParameter) { +- param = (param as DefaultFormalParameter).parameter; +- } +- if (param is FieldFormalParameter) { +- SimpleIdentifier fieldId = param.identifier; +- if (fieldId != null && fieldId != request.target.entity) { +- String fieldName = fieldId.name; +- if (fieldName != null && fieldName.length > 0) { +- referencedFields.add(fieldName); +- } +- } +- } +- } +- +- // Add suggestions for fields that are not already referenced +- ClassDeclaration classDecl = +- constructorDecl.getAncestor((p) => p is ClassDeclaration); +- List suggestions = []; +- for (ClassMember member in classDecl.members) { +- if (member is FieldDeclaration && !member.isStatic) { +- for (VariableDeclaration varDecl in member.fields.variables) { +- SimpleIdentifier fieldId = varDecl.name; +- if (fieldId != null) { +- String fieldName = fieldId.name; +- if (fieldName != null && fieldName.length > 0) { +- if (!referencedFields.contains(fieldName)) { +- CompletionSuggestion suggestion = createSuggestion( +- fieldId.bestElement, +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- if (suggestion != null) { +- suggestions.add(suggestion); +- } +- } +- } +- } +- } +- } +- } +- return suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart +deleted file mode 100644 +index e182fdfb7b2..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart ++++ /dev/null +@@ -1,86 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/resolver.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-import '../../../protocol_server.dart' show CompletionSuggestion; +- +-List hiddenNamesIn(ImportElement importElem) { +- for (NamespaceCombinator combinator in importElem.combinators) { +- if (combinator is HideElementCombinator) { +- return combinator.hiddenNames; +- } +- } +- return null; +-} +- +-List showNamesIn(ImportElement importElem) { +- for (NamespaceCombinator combinator in importElem.combinators) { +- if (combinator is ShowElementCombinator) { +- return combinator.shownNames; +- } +- } +- return null; +-} +- +-/** +- * A contributor for calculating suggestions for imported top level members. +- */ +-class ImportedReferenceContributor extends DartCompletionContributor { +- DartCompletionRequest request; +- OpType optype; +- +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- if (!request.includeIdentifiers) { +- return EMPTY_LIST; +- } +- +- List imports = request.libraryElement.imports; +- if (imports == null) { +- return EMPTY_LIST; +- } +- +- this.request = request; +- this.optype = (request as DartCompletionRequestImpl).opType; +- List suggestions = []; +- +- // Traverse imports including dart:core +- for (ImportElement importElem in imports) { +- LibraryElement libElem = importElem?.importedLibrary; +- if (libElem != null) { +- suggestions.addAll(_buildSuggestions(libElem.exportNamespace, +- prefix: importElem.prefix?.name, +- showNames: showNamesIn(importElem), +- hiddenNames: hiddenNamesIn(importElem))); +- } +- } +- +- return suggestions; +- } +- +- List _buildSuggestions(Namespace namespace, +- {String prefix, List showNames, List hiddenNames}) { +- LibraryElementSuggestionBuilder visitor = +- new LibraryElementSuggestionBuilder(request, optype, prefix); +- for (Element elem in namespace.definedNames.values) { +- if (showNames != null && !showNames.contains(elem.name)) { +- continue; +- } +- if (hiddenNames != null && hiddenNames.contains(elem.name)) { +- continue; +- } +- elem.accept(visitor); +- } +- return visitor.suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart +deleted file mode 100644 +index 315b49c64f3..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart ++++ /dev/null +@@ -1,134 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-import '../../../protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +- +-/** +- * Return the class containing the target +- * or `null` if the target is in a static method or field +- * or not in a class. +- */ +-ClassDeclaration _enclosingClass(CompletionTarget target) { +- AstNode node = target.containingNode; +- while (node != null) { +- if (node is ClassDeclaration) { +- return node; +- } +- if (node is MethodDeclaration) { +- if (node.isStatic) { +- return null; +- } +- } +- if (node is FieldDeclaration) { +- if (node.isStatic) { +- return null; +- } +- } +- node = node.parent; +- } +- return null; +-} +- +-/** +- * A contributor for calculating suggestions for inherited references. +- */ +-class InheritedReferenceContributor extends DartCompletionContributor +- with ElementSuggestionBuilder { +- @override +- LibraryElement containingLibrary; +- +- @override +- CompletionSuggestionKind kind; +- +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- if (!request.includeIdentifiers) { +- return EMPTY_LIST; +- } +- +- ClassDeclaration classDecl = _enclosingClass(request.target); +- if (classDecl == null || classDecl.element == null) { +- return EMPTY_LIST; +- } +- containingLibrary = request.libraryElement; +- return _computeSuggestionsForClass2( +- resolutionMap.elementDeclaredByClassDeclaration(classDecl), request); +- } +- +- List computeSuggestionsForClass( +- ClassElement classElement, DartCompletionRequest request, +- {bool skipChildClass: true}) { +- if (!request.includeIdentifiers) { +- return EMPTY_LIST; +- } +- containingLibrary = request.libraryElement; +- +- return _computeSuggestionsForClass2(classElement, request, +- skipChildClass: skipChildClass); +- } +- +- _addSuggestionsForType(InterfaceType type, OpType optype, +- {bool isFunctionalArgument: false}) { +- if (!isFunctionalArgument) { +- for (PropertyAccessorElement elem in type.accessors) { +- if (elem.isGetter) { +- if (optype.includeReturnValueSuggestions) { +- addSuggestion(elem); +- } +- } else { +- if (optype.includeVoidReturnSuggestions) { +- addSuggestion(elem); +- } +- } +- } +- } +- for (MethodElement elem in type.methods) { +- if (elem.returnType == null) { +- addSuggestion(elem); +- } else if (!elem.returnType.isVoid) { +- if (optype.includeReturnValueSuggestions) { +- addSuggestion(elem); +- } +- } else { +- if (optype.includeVoidReturnSuggestions) { +- addSuggestion(elem); +- } +- } +- } +- } +- +- List _computeSuggestionsForClass2( +- ClassElement classElement, DartCompletionRequest request, +- {bool skipChildClass: true}) { +- bool isFunctionalArgument = request.target.isFunctionalArgument(); +- kind = isFunctionalArgument +- ? CompletionSuggestionKind.IDENTIFIER +- : CompletionSuggestionKind.INVOCATION; +- OpType optype = request.opType; +- +- if (!skipChildClass) { +- _addSuggestionsForType(classElement.type, optype, +- isFunctionalArgument: isFunctionalArgument); +- } +- +- for (InterfaceType type in classElement.allSupertypes) { +- _addSuggestionsForType(type, optype, +- isFunctionalArgument: isFunctionalArgument); +- } +- return suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart +deleted file mode 100644 +index 8803b5a2e97..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart ++++ /dev/null +@@ -1,706 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/src/dart/ast/token.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-const ASYNC_STAR = 'async*'; +-const DEFERRED_AS = 'deferred as'; +-const EXPORT_STATEMENT = "export '';"; +-const IMPORT_STATEMENT = "import '';"; +-const PART_STATEMENT = "part '';"; +-const SYNC_STAR = 'sync*'; +-const YIELD_STAR = 'yield*'; +- +-/** +- * A contributor for calculating `completion.getSuggestions` request results +- * for the local library in which the completion is requested. +- */ +-class KeywordContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- List suggestions = []; +- request.target.containingNode +- .accept(new _KeywordVisitor(request, suggestions)); +- return suggestions; +- } +-} +- +-/** +- * A visitor for generating keyword suggestions. +- */ +-class _KeywordVisitor extends GeneralizingAstVisitor { +- final DartCompletionRequest request; +- final Object entity; +- final List suggestions; +- +- _KeywordVisitor(DartCompletionRequest request, this.suggestions) +- : this.request = request, +- this.entity = request.target.entity; +- +- @override +- visitArgumentList(ArgumentList node) { +- if (request is DartCompletionRequestImpl) { +- //TODO(danrubel) consider adding opType to the API then remove this cast +- OpType opType = (request as DartCompletionRequestImpl).opType; +- if (opType.includeOnlyNamedArgumentSuggestions) { +- return; +- } +- } +- if (entity == node.rightParenthesis) { +- _addExpressionKeywords(node); +- Token previous = (entity as Token).previous; +- if (previous.isSynthetic) { +- previous = previous.previous; +- } +- if (previous.lexeme == ')') { +- _addSuggestion(Keyword.ASYNC); +- _addSuggestion2(ASYNC_STAR); +- _addSuggestion2(SYNC_STAR); +- } +- } +- if (entity is SimpleIdentifier && node.arguments.contains(entity)) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitAsExpression(AsExpression node) { +- if (identical(entity, node.asOperator) && +- node.expression is ParenthesizedExpression) { +- _addSuggestion(Keyword.ASYNC, DART_RELEVANCE_HIGH); +- _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- } +- } +- +- @override +- visitBlock(Block node) { +- Statement prevStmt = OpType.getPreviousStatement(node, entity); +- if (prevStmt is TryStatement) { +- if (prevStmt.finallyBlock == null) { +- _addSuggestion(Keyword.ON); +- _addSuggestion(Keyword.CATCH); +- _addSuggestion(Keyword.FINALLY); +- if (prevStmt.catchClauses.isEmpty) { +- // If try statement with no catch, on, or finally +- // then only suggest these keywords +- return; +- } +- } +- } +- +- if (entity is ExpressionStatement) { +- Expression expression = (entity as ExpressionStatement).expression; +- if (expression is SimpleIdentifier) { +- Token token = expression.token; +- Token previous = token.previous; +- if (previous.isSynthetic) { +- previous = previous.previous; +- } +- Token next = token.next; +- if (next.isSynthetic) { +- next = next.next; +- } +- if (previous.type == TokenType.CLOSE_PAREN && +- next.type == TokenType.OPEN_CURLY_BRACKET) { +- _addSuggestion(Keyword.ASYNC); +- _addSuggestion2(ASYNC_STAR); +- _addSuggestion2(SYNC_STAR); +- } +- } +- } +- _addStatementKeywords(node); +- if (_inCatchClause(node)) { +- _addSuggestion(Keyword.RETHROW, DART_RELEVANCE_KEYWORD - 1); +- } +- } +- +- @override +- visitClassDeclaration(ClassDeclaration node) { +- // Don't suggest class name +- if (entity == node.name) { +- return; +- } +- if (entity == node.rightBracket) { +- _addClassBodyKeywords(); +- } else if (entity is ClassMember) { +- _addClassBodyKeywords(); +- int index = node.members.indexOf(entity); +- ClassMember previous = index > 0 ? node.members[index - 1] : null; +- if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) { +- _addSuggestion(Keyword.ASYNC); +- _addSuggestion2(ASYNC_STAR); +- _addSuggestion2(SYNC_STAR); +- } +- } else { +- _addClassDeclarationKeywords(node); +- } +- } +- +- @override +- visitCompilationUnit(CompilationUnit node) { +- var previousMember = null; +- for (var member in node.childEntities) { +- if (entity == member) { +- break; +- } +- previousMember = member; +- } +- if (previousMember is ClassDeclaration) { +- if (previousMember.leftBracket == null || +- previousMember.leftBracket.isSynthetic) { +- // If the prior member is an unfinished class declaration +- // then the user is probably finishing that +- _addClassDeclarationKeywords(previousMember); +- return; +- } +- } +- if (previousMember is ImportDirective) { +- if (previousMember.semicolon == null || +- previousMember.semicolon.isSynthetic) { +- // If the prior member is an unfinished import directive +- // then the user is probably finishing that +- _addImportDirectiveKeywords(previousMember); +- return; +- } +- } +- if (previousMember == null || previousMember is Directive) { +- if (previousMember == null && +- !node.directives.any((d) => d is LibraryDirective)) { +- _addSuggestions([Keyword.LIBRARY], DART_RELEVANCE_HIGH); +- } +- _addSuggestion2(IMPORT_STATEMENT, +- offset: 8, relevance: DART_RELEVANCE_HIGH); +- _addSuggestion2(EXPORT_STATEMENT, +- offset: 8, relevance: DART_RELEVANCE_HIGH); +- _addSuggestion2(PART_STATEMENT, +- offset: 6, relevance: DART_RELEVANCE_HIGH); +- } +- if (entity == null || entity is Declaration) { +- if (previousMember is FunctionDeclaration && +- previousMember.functionExpression is FunctionExpression && +- previousMember.functionExpression.body is EmptyFunctionBody) { +- _addSuggestion(Keyword.ASYNC, DART_RELEVANCE_HIGH); +- _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- } +- _addCompilationUnitKeywords(); +- } +- } +- +- @override +- visitConstructorDeclaration(ConstructorDeclaration node) { +- if (node.initializers.isNotEmpty && node.initializers.last == entity) { +- _addSuggestion(Keyword.SUPER); +- } +- } +- +- @override +- visitDefaultFormalParameter(DefaultFormalParameter node) { +- if (entity == node.defaultValue) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitExpression(Expression node) { +- _addExpressionKeywords(node); +- } +- +- @override +- visitExpressionFunctionBody(ExpressionFunctionBody node) { +- if (entity == node.expression) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitFieldDeclaration(FieldDeclaration node) { +- VariableDeclarationList fields = node.fields; +- NodeList variables = fields.variables; +- if (variables.length != 1 || +- !variables[0].name.isSynthetic || +- fields.type == null) { +- return; +- } +- if (entity != fields) { +- return; +- } +- List keywords = [Keyword.CONST, Keyword.FINAL]; +- if (!node.isStatic) { +- keywords.add(Keyword.STATIC); +- } +- _addSuggestions(keywords); +- } +- +- @override +- visitForEachStatement(ForEachStatement node) { +- if (entity == node.inKeyword) { +- Token previous = node.inKeyword.previous; +- if (previous is SyntheticStringToken && previous.lexeme == 'in') { +- previous = previous.previous; +- } +- if (previous != null && previous.type == TokenType.EQ) { +- _addSuggestions([ +- Keyword.CONST, +- Keyword.FALSE, +- Keyword.NEW, +- Keyword.NULL, +- Keyword.TRUE +- ]); +- } else { +- _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH); +- } +- } +- } +- +- @override +- visitFormalParameterList(FormalParameterList node) { +- AstNode constructorDeclaration = +- node.getAncestor((p) => p is ConstructorDeclaration); +- if (constructorDeclaration != null) { +- _addSuggestions([Keyword.THIS]); +- } +- if (entity is Token && (entity as Token).type == TokenType.CLOSE_PAREN) { +- _addSuggestion(Keyword.COVARIANT); +- } else if (entity is FormalParameter) { +- Token beginToken = (entity as FormalParameter).beginToken; +- if (beginToken != null && request.target.offset == beginToken.end) { +- _addSuggestion(Keyword.COVARIANT); +- } +- } +- } +- +- @override +- visitForStatement(ForStatement node) { +- // Actual: for (va^) +- // Parsed: for (va^; ;) +- if (node.initialization == entity && entity is SimpleIdentifier) { +- if (_isNextTokenSynthetic(entity, TokenType.SEMICOLON)) { +- _addSuggestion(Keyword.VAR, DART_RELEVANCE_HIGH); +- } +- } +- // Actual: for (int x i^) +- // Parsed: for (int x; i^;) +- // Handle the degenerate case while typing - for (int x i^) +- if (node.condition == entity && +- entity is SimpleIdentifier && +- node.variables != null) { +- if (_isPreviousTokenSynthetic(entity, TokenType.SEMICOLON)) { +- _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH); +- } +- } +- } +- +- @override +- visitFunctionExpression(FunctionExpression node) { +- if (entity == node.body) { +- FunctionBody body = node.body; +- if (!body.isAsynchronous) { +- _addSuggestion(Keyword.ASYNC, DART_RELEVANCE_HIGH); +- if (body is! ExpressionFunctionBody) { +- _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- } +- } +- if (node.body is EmptyFunctionBody && +- node.parent is FunctionDeclaration && +- node.parent.parent is CompilationUnit) { +- _addCompilationUnitKeywords(); +- } +- } +- } +- +- @override +- visitIfStatement(IfStatement node) { +- if (_isPreviousTokenSynthetic(entity, TokenType.CLOSE_PAREN)) { +- // Actual: if (x i^) +- // Parsed: if (x) i^ +- _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH); +- } else if (entity == node.thenStatement || entity == node.elseStatement) { +- _addStatementKeywords(node); +- } else if (entity == node.condition) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitImportDirective(ImportDirective node) { +- if (entity == node.asKeyword) { +- if (node.deferredKeyword == null) { +- _addSuggestion(Keyword.DEFERRED, DART_RELEVANCE_HIGH); +- } +- } +- // Handle degenerate case where import statement does not have a semicolon +- // and the cursor is in the uri string +- if ((entity == node.semicolon && +- node.uri != null && +- node.uri.offset + 1 != request.offset) || +- node.combinators.contains(entity)) { +- _addImportDirectiveKeywords(node); +- } +- } +- +- @override +- visitInstanceCreationExpression(InstanceCreationExpression node) { +- if (entity == node.constructorName) { +- // no keywords in 'new ^' expression +- } else { +- super.visitInstanceCreationExpression(node); +- } +- } +- +- @override +- visitIsExpression(IsExpression node) { +- if (entity == node.isOperator) { +- _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH); +- } else { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitLibraryIdentifier(LibraryIdentifier node) { +- // no suggestions +- } +- +- @override +- visitMethodDeclaration(MethodDeclaration node) { +- if (entity == node.body) { +- if (node.body is EmptyFunctionBody) { +- _addClassBodyKeywords(); +- _addSuggestion(Keyword.ASYNC); +- _addSuggestion2(ASYNC_STAR); +- _addSuggestion2(SYNC_STAR); +- } else { +- _addSuggestion(Keyword.ASYNC, DART_RELEVANCE_HIGH); +- if (node.body is! ExpressionFunctionBody) { +- _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH); +- } +- } +- } +- } +- +- @override +- visitMethodInvocation(MethodInvocation node) { +- if (entity == node.methodName) { +- // no keywords in '.' expression +- } else { +- super.visitMethodInvocation(node); +- } +- } +- +- @override +- visitNamedExpression(NamedExpression node) { +- if (entity is SimpleIdentifier && entity == node.expression) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitNode(AstNode node) { +- // ignored +- } +- +- @override +- visitPrefixedIdentifier(PrefixedIdentifier node) { +- if (entity != node.identifier) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitPropertyAccess(PropertyAccess node) { +- // suggestions before '.' but not after +- if (entity != node.propertyName) { +- super.visitPropertyAccess(node); +- } +- } +- +- @override +- visitReturnStatement(ReturnStatement node) { +- if (entity == node.expression) { +- _addExpressionKeywords(node); +- } +- } +- +- @override +- visitStringLiteral(StringLiteral node) { +- // ignored +- } +- +- @override +- visitSwitchStatement(SwitchStatement node) { +- if (entity == node.expression) { +- _addExpressionKeywords(node); +- } else if (entity == node.rightBracket) { +- if (node.members.isEmpty) { +- _addSuggestions([Keyword.CASE, Keyword.DEFAULT], DART_RELEVANCE_HIGH); +- } else { +- _addSuggestions([Keyword.CASE, Keyword.DEFAULT]); +- _addStatementKeywords(node); +- } +- } +- if (node.members.contains(entity)) { +- if (entity == node.members.first) { +- _addSuggestions([Keyword.CASE, Keyword.DEFAULT], DART_RELEVANCE_HIGH); +- } else { +- _addSuggestions([Keyword.CASE, Keyword.DEFAULT]); +- _addStatementKeywords(node); +- } +- } +- } +- +- @override +- visitTryStatement(TryStatement node) { +- var obj = entity; +- if (obj is CatchClause || +- (obj is KeywordToken && obj.value() == Keyword.FINALLY)) { +- _addSuggestion(Keyword.ON); +- _addSuggestion(Keyword.CATCH); +- return null; +- } +- return visitStatement(node); +- } +- +- @override +- visitVariableDeclaration(VariableDeclaration node) { +- if (entity == node.initializer) { +- _addExpressionKeywords(node); +- } +- } +- +- void _addClassBodyKeywords() { +- _addSuggestions([ +- Keyword.CONST, +- Keyword.DYNAMIC, +- Keyword.FACTORY, +- Keyword.FINAL, +- Keyword.GET, +- Keyword.OPERATOR, +- Keyword.SET, +- Keyword.STATIC, +- Keyword.VAR, +- Keyword.VOID +- ]); +- } +- +- void _addClassDeclarationKeywords(ClassDeclaration node) { +- // Very simplistic suggestion because analyzer will warn if +- // the extends / with / implements keywords are out of order +- if (node.extendsClause == null) { +- _addSuggestion(Keyword.EXTENDS, DART_RELEVANCE_HIGH); +- } else if (node.withClause == null) { +- _addSuggestion(Keyword.WITH, DART_RELEVANCE_HIGH); +- } +- if (node.implementsClause == null) { +- _addSuggestion(Keyword.IMPLEMENTS, DART_RELEVANCE_HIGH); +- } +- } +- +- void _addCompilationUnitKeywords() { +- _addSuggestions([ +- Keyword.ABSTRACT, +- Keyword.CLASS, +- Keyword.CONST, +- Keyword.DYNAMIC, +- Keyword.FINAL, +- Keyword.TYPEDEF, +- Keyword.VAR, +- Keyword.VOID +- ], DART_RELEVANCE_HIGH); +- } +- +- void _addExpressionKeywords(AstNode node) { +- _addSuggestions([ +- Keyword.CONST, +- Keyword.FALSE, +- Keyword.NEW, +- Keyword.NULL, +- Keyword.TRUE, +- ]); +- if (_inClassMemberBody(node)) { +- _addSuggestions([Keyword.SUPER, Keyword.THIS]); +- } +- if (_inAsyncMethodOrFunction(node)) { +- _addSuggestion(Keyword.AWAIT); +- } +- } +- +- void _addImportDirectiveKeywords(ImportDirective node) { +- bool hasDeferredKeyword = node.deferredKeyword != null; +- bool hasAsKeyword = node.asKeyword != null; +- if (!hasAsKeyword) { +- _addSuggestion(Keyword.AS, DART_RELEVANCE_HIGH); +- } +- if (!hasDeferredKeyword) { +- if (!hasAsKeyword) { +- _addSuggestion2(DEFERRED_AS, relevance: DART_RELEVANCE_HIGH); +- } else if (entity == node.asKeyword) { +- _addSuggestion(Keyword.DEFERRED, DART_RELEVANCE_HIGH); +- } +- } +- if (!hasDeferredKeyword || hasAsKeyword) { +- if (node.combinators.isEmpty) { +- _addSuggestion(Keyword.SHOW, DART_RELEVANCE_HIGH); +- _addSuggestion(Keyword.HIDE, DART_RELEVANCE_HIGH); +- } +- } +- } +- +- void _addStatementKeywords(AstNode node) { +- if (_inClassMemberBody(node)) { +- _addSuggestions([Keyword.SUPER, Keyword.THIS]); +- } +- if (_inAsyncMethodOrFunction(node)) { +- _addSuggestion(Keyword.AWAIT); +- } else if (_inAsyncStarOrSyncStarMethodOrFunction(node)) { +- _addSuggestion(Keyword.AWAIT); +- _addSuggestion(Keyword.YIELD); +- _addSuggestion2(YIELD_STAR); +- } +- if (_inLoop(node)) { +- _addSuggestions([Keyword.BREAK, Keyword.CONTINUE]); +- } +- if (_inSwitch(node)) { +- _addSuggestions([Keyword.BREAK]); +- } +- if (_isEntityAfterIfWithoutElse(node)) { +- _addSuggestions([Keyword.ELSE]); +- } +- _addSuggestions([ +- Keyword.ASSERT, +- Keyword.CONST, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SWITCH, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]); +- } +- +- void _addSuggestion(Keyword keyword, +- [int relevance = DART_RELEVANCE_KEYWORD]) { +- _addSuggestion2(keyword.lexeme, relevance: relevance); +- } +- +- void _addSuggestion2(String completion, +- {int offset, int relevance: DART_RELEVANCE_KEYWORD}) { +- if (offset == null) { +- offset = completion.length; +- } +- suggestions.add(new CompletionSuggestion(CompletionSuggestionKind.KEYWORD, +- relevance, completion, offset, 0, false, false)); +- } +- +- void _addSuggestions(List keywords, +- [int relevance = DART_RELEVANCE_KEYWORD]) { +- keywords.forEach((Keyword keyword) { +- _addSuggestion(keyword, relevance); +- }); +- } +- +- bool _inAsyncMethodOrFunction(AstNode node) { +- FunctionBody body = node.getAncestor((n) => n is FunctionBody); +- return body != null && body.isAsynchronous && body.star == null; +- } +- +- bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) { +- FunctionBody body = node.getAncestor((n) => n is FunctionBody); +- return body != null && body.keyword != null && body.star != null; +- } +- +- bool _inCatchClause(Block node) => +- node.getAncestor((p) => p is CatchClause) != null; +- +- bool _inClassMemberBody(AstNode node) { +- while (true) { +- AstNode body = node.getAncestor((n) => n is FunctionBody); +- if (body == null) { +- return false; +- } +- AstNode parent = body.parent; +- if (parent is ConstructorDeclaration || parent is MethodDeclaration) { +- return true; +- } +- node = parent; +- } +- } +- +- bool _inDoLoop(AstNode node) => +- node.getAncestor((p) => p is DoStatement) != null; +- +- bool _inForLoop(AstNode node) => +- node.getAncestor((p) => p is ForStatement || p is ForEachStatement) != +- null; +- +- bool _inLoop(AstNode node) => +- _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node); +- +- bool _inSwitch(AstNode node) => +- node.getAncestor((p) => p is SwitchStatement) != null; +- +- bool _inWhileLoop(AstNode node) => +- node.getAncestor((p) => p is WhileStatement) != null; +- +- bool _isEntityAfterIfWithoutElse(AstNode node) { +- Block block = node?.getAncestor((n) => n is Block); +- if (block == null) { +- return false; +- } +- Object entity = this.entity; +- if (entity is Statement) { +- int entityIndex = block.statements.indexOf(entity); +- if (entityIndex > 0) { +- Statement prevStatement = block.statements[entityIndex - 1]; +- return prevStatement is IfStatement && +- prevStatement.elseStatement == null; +- } +- } +- if (entity is Token) { +- for (Statement statement in block.statements) { +- if (statement.endToken.next == entity) { +- return statement is IfStatement && statement.elseStatement == null; +- } +- } +- } +- return false; +- } +- +- static bool _isNextTokenSynthetic(Object entity, TokenType type) { +- if (entity is AstNode) { +- Token token = entity.beginToken; +- Token nextToken = token.next; +- return nextToken.isSynthetic && nextToken.type == type; +- } +- return false; +- } +- +- static bool _isPreviousTokenSynthetic(Object entity, TokenType type) { +- if (entity is AstNode) { +- Token token = entity.beginToken; +- Token previousToken = token.previous; +- return previousToken.isSynthetic && previousToken.type == type; +- } +- return false; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart +deleted file mode 100644 +index 1e8c52095bc..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart ++++ /dev/null +@@ -1,156 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart' +- show DartCompletionRequestImpl; +-import 'package:analysis_server/src/services/completion/dart/utilities.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol +- show ElementKind; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +-import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart' +- show LocalDeclarationVisitor; +- +-/** +- * A contributor for calculating label suggestions. +- */ +-class LabelContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- OpType optype = (request as DartCompletionRequestImpl).opType; +- +- // Collect suggestions from the specific child [AstNode] that contains +- // the completion offset and all of its parents recursively. +- List suggestions = []; +- if (!optype.isPrefixed) { +- if (optype.includeStatementLabelSuggestions || +- optype.includeCaseLabelSuggestions) { +- new _LabelVisitor(request, optype.includeStatementLabelSuggestions, +- optype.includeCaseLabelSuggestions, suggestions) +- .visit(request.target.containingNode); +- } +- } +- return suggestions; +- } +-} +- +-/** +- * A visitor for collecting suggestions for break and continue labels. +- */ +-class _LabelVisitor extends LocalDeclarationVisitor { +- final DartCompletionRequest request; +- final List suggestions; +- +- /** +- * True if statement labels should be included as suggestions. +- */ +- final bool includeStatementLabels; +- +- /** +- * True if case labels should be included as suggestions. +- */ +- final bool includeCaseLabels; +- +- _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels, +- this.includeCaseLabels, this.suggestions) +- : request = request, +- super(request.offset); +- +- @override +- void declaredClass(ClassDeclaration declaration) { +- // ignored +- } +- +- @override +- void declaredClassTypeAlias(ClassTypeAlias declaration) { +- // ignored +- } +- +- @override +- void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { +- // ignored +- } +- +- @override +- void declaredFunction(FunctionDeclaration declaration) { +- // ignored +- } +- +- @override +- void declaredFunctionTypeAlias(FunctionTypeAlias declaration) { +- // ignored +- } +- +- @override +- void declaredLabel(Label label, bool isCaseLabel) { +- if (isCaseLabel ? includeCaseLabels : includeStatementLabels) { +- CompletionSuggestion suggestion = _addSuggestion(label.label); +- if (suggestion != null) { +- suggestion.element = createLocalElement( +- request.source, protocol.ElementKind.LABEL, label.label, +- returnType: NO_RETURN_TYPE); +- } +- } +- } +- +- @override +- void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type) { +- // ignored +- } +- +- @override +- void declaredMethod(MethodDeclaration declaration) { +- // ignored +- } +- +- @override +- void declaredParam(SimpleIdentifier name, TypeAnnotation type) { +- // ignored +- } +- +- @override +- void declaredTopLevelVar( +- VariableDeclarationList varList, VariableDeclaration varDecl) { +- // ignored +- } +- +- @override +- void visitFunctionExpression(FunctionExpression node) { +- // Labels are only accessible within the local function, so stop visiting +- // once we reach a function boundary. +- finished(); +- } +- +- @override +- void visitMethodDeclaration(MethodDeclaration node) { +- // Labels are only accessible within the local function, so stop visiting +- // once we reach a function boundary. +- finished(); +- } +- +- CompletionSuggestion _addSuggestion(SimpleIdentifier id) { +- if (id != null) { +- String completion = id.name; +- if (completion != null && completion.length > 0 && completion != '_') { +- CompletionSuggestion suggestion = new CompletionSuggestion( +- CompletionSuggestionKind.IDENTIFIER, +- DART_RELEVANCE_DEFAULT, +- completion, +- completion.length, +- 0, +- false, +- false); +- suggestions.add(suggestion); +- return suggestion; +- } +- } +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart +deleted file mode 100644 +index 078959a84b1..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart ++++ /dev/null +@@ -1,73 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-import '../../../protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +- +-/** +- * A contributor for calculating prefixed import library member suggestions +- * `completion.getSuggestions` request results. +- */ +-class LibraryMemberContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- // Determine if the target looks like a library prefix +- Expression targetId = request.dotTarget; +- if (targetId is SimpleIdentifier && !request.target.isCascade) { +- Element elem = targetId.bestElement; +- if (elem is PrefixElement && !elem.isSynthetic) { +- LibraryElement containingLibrary = request.libraryElement; +- // Gracefully degrade if the library or directives +- // could not be determined (e.g. detached part file or source change) +- if (containingLibrary != null) { +- List imports = containingLibrary.imports; +- if (imports != null) { +- return _buildSuggestions(request, elem, containingLibrary, imports); +- } +- } +- } +- } +- return EMPTY_LIST; +- } +- +- List _buildSuggestions( +- DartCompletionRequest request, +- PrefixElement elem, +- LibraryElement containingLibrary, +- List imports) { +- List suggestions = []; +- for (ImportElement importElem in imports) { +- if (importElem.prefix?.name == elem.name) { +- LibraryElement library = importElem.importedLibrary; +- if (library != null) { +- // Suggest elements from the imported library +- AstNode parent = request.target.containingNode.parent; +- bool isConstructor = parent.parent is ConstructorName; +- bool typesOnly = parent is TypeName; +- bool instCreation = typesOnly && isConstructor; +- LibraryElementSuggestionBuilder builder = +- new LibraryElementSuggestionBuilder(containingLibrary, +- CompletionSuggestionKind.INVOCATION, typesOnly, instCreation); +- library.visitChildren(builder); +- suggestions.addAll(builder.suggestions); +- +- // If the import is 'deferred' then suggest 'loadLibrary' +- if (importElem.isDeferred) { +- FunctionElement loadLibFunct = library.loadLibraryFunction; +- suggestions.add(createSuggestion(loadLibFunct)); +- } +- } +- } +- } +- return suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart +deleted file mode 100644 +index 9ba62c4463c..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart ++++ /dev/null +@@ -1,48 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-import '../../../protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +- +-/** +- * A contributor for calculating prefixed import library member suggestions +- * `completion.getSuggestions` request results. +- */ +-class LibraryPrefixContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- if (!request.includeIdentifiers) { +- return EMPTY_LIST; +- } +- +- List imports = request.libraryElement.imports; +- if (imports == null) { +- return EMPTY_LIST; +- } +- +- List suggestions = []; +- for (ImportElement element in imports) { +- String completion = element.prefix?.name; +- if (completion != null && completion.length > 0) { +- LibraryElement libElem = element.importedLibrary; +- if (libElem != null) { +- CompletionSuggestion suggestion = createSuggestion(libElem, +- completion: completion, +- kind: CompletionSuggestionKind.IDENTIFIER); +- if (suggestion != null) { +- suggestions.add(suggestion); +- } +- } +- } +- } +- return suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart +deleted file mode 100644 +index 17fc0c59bbe..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart ++++ /dev/null +@@ -1,161 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart' +- show DartCompletionRequestImpl; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analysis_server/src/services/completion/dart/utilities.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol +- show Element, ElementKind; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +-import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart' +- show LocalDeclarationVisitor; +- +-/** +- * A contributor for calculating constructor suggestions +- * for declarations in the local file. +- */ +-class LocalConstructorContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- OpType optype = (request as DartCompletionRequestImpl).opType; +- +- // Collect suggestions from the specific child [AstNode] that contains +- // the completion offset and all of its parents recursively. +- List suggestions = []; +- if (!optype.isPrefixed) { +- if (optype.includeConstructorSuggestions) { +- new _Visitor(request, suggestions, optype) +- .visit(request.target.containingNode); +- } +- } +- return suggestions; +- } +-} +- +-/** +- * A visitor for collecting constructor suggestions. +- */ +-class _Visitor extends LocalDeclarationVisitor { +- final DartCompletionRequest request; +- final OpType optype; +- final List suggestions; +- +- _Visitor(DartCompletionRequest request, this.suggestions, this.optype) +- : request = request, +- super(request.offset); +- +- @override +- void declaredClass(ClassDeclaration declaration) { +- bool found = false; +- for (ClassMember member in declaration.members) { +- if (member is ConstructorDeclaration) { +- found = true; +- _addSuggestion(declaration, member); +- } +- } +- if (!found) { +- _addSuggestion(declaration, null); +- } +- } +- +- @override +- void declaredClassTypeAlias(ClassTypeAlias declaration) {} +- +- @override +- void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {} +- +- @override +- void declaredFunction(FunctionDeclaration declaration) {} +- +- @override +- void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {} +- +- @override +- void declaredLabel(Label label, bool isCaseLabel) {} +- +- @override +- void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type) {} +- +- @override +- void declaredMethod(MethodDeclaration declaration) {} +- +- @override +- void declaredParam(SimpleIdentifier name, TypeAnnotation type) {} +- +- @override +- void declaredTopLevelVar( +- VariableDeclarationList varList, VariableDeclaration varDecl) {} +- +- /** +- * For the given class and constructor, +- * add a suggestion of the form B(...) or B.name(...). +- * If the given constructor is `null` +- * then add a default constructor suggestion. +- */ +- void _addSuggestion( +- ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) { +- String completion = classDecl.name.name; +- SimpleIdentifier elemId; +- +- ClassElement classElement = +- resolutionMap.elementDeclaredByClassDeclaration(classDecl); +- int relevance = optype.constructorSuggestionsFilter( +- classElement?.type, DART_RELEVANCE_DEFAULT); +- if (relevance == null) { +- return; +- } +- +- // Build a suggestion for explicitly declared constructor +- if (constructorDecl != null) { +- elemId = constructorDecl.name; +- ConstructorElement elem = constructorDecl.element; +- if (elemId != null) { +- String name = elemId.name; +- if (name != null && name.length > 0) { +- completion = '$completion.$name'; +- } +- } +- if (elem != null) { +- CompletionSuggestion suggestion = createSuggestion(elem, +- completion: completion, relevance: relevance); +- if (suggestion != null) { +- suggestions.add(suggestion); +- } +- } +- } +- +- // Build a suggestion for an implicit constructor +- else { +- protocol.Element element = createLocalElement( +- request.source, protocol.ElementKind.CONSTRUCTOR, elemId, +- parameters: '()'); +- element.returnType = classDecl.name.name; +- CompletionSuggestion suggestion = new CompletionSuggestion( +- CompletionSuggestionKind.INVOCATION, +- relevance, +- completion, +- completion.length, +- 0, +- false, +- false, +- declaringType: classDecl.name.name, +- element: element, +- parameterNames: [], +- parameterTypes: [], +- requiredParameterCount: 0, +- hasNamedParameters: false); +- suggestions.add(suggestion); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart +deleted file mode 100644 +index e54e3fb3b25..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart ++++ /dev/null +@@ -1,197 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart' +- show createSuggestion, ElementSuggestionBuilder; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-import '../../../protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +- +-/** +- * A visitor for building suggestions based upon the elements defined by +- * a source file contained in the same library but not the same as +- * the source in which the completions are being requested. +- */ +-class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor +- with ElementSuggestionBuilder { +- final DartCompletionRequest request; +- final OpType optype; +- CompletionSuggestionKind kind; +- final String prefix; +- List showNames; +- List hiddenNames; +- +- /** +- * The set of libraries that have been, or are currently being, visited. +- */ +- final Set visitedLibraries = new Set(); +- +- LibraryElementSuggestionBuilder(this.request, this.optype, [this.prefix]) { +- this.kind = request.target.isFunctionalArgument() +- ? CompletionSuggestionKind.IDENTIFIER +- : optype.suggestKind; +- } +- +- @override +- LibraryElement get containingLibrary => request.libraryElement; +- +- @override +- void visitClassElement(ClassElement element) { +- if (optype.includeTypeNameSuggestions) { +- // if includeTypeNameSuggestions, then use the filter +- int relevance = optype.typeNameSuggestionsFilter( +- element.type, DART_RELEVANCE_DEFAULT); +- if (relevance != null) { +- addSuggestion(element, prefix: prefix, relevance: relevance); +- } +- } +- if (optype.includeConstructorSuggestions) { +- int relevance = optype.constructorSuggestionsFilter( +- element.type, DART_RELEVANCE_DEFAULT); +- if (relevance != null) { +- _addConstructorSuggestions(element, relevance); +- } +- } +- } +- +- @override +- void visitCompilationUnitElement(CompilationUnitElement element) { +- element.visitChildren(this); +- } +- +- @override +- void visitElement(Element element) { +- // ignored +- } +- +- @override +- void visitFunctionElement(FunctionElement element) { +- // Do not suggest operators or local functions +- if (element.isOperator) { +- return; +- } +- if (element.enclosingElement is! CompilationUnitElement) { +- return; +- } +- int relevance = element.library == containingLibrary +- ? DART_RELEVANCE_LOCAL_FUNCTION +- : DART_RELEVANCE_DEFAULT; +- DartType returnType = element.returnType; +- if (returnType != null && returnType.isVoid) { +- if (optype.includeVoidReturnSuggestions) { +- addSuggestion(element, prefix: prefix, relevance: relevance); +- } +- } else { +- if (optype.includeReturnValueSuggestions) { +- addSuggestion(element, prefix: prefix, relevance: relevance); +- } +- } +- } +- +- @override +- void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { +- if (optype.includeTypeNameSuggestions) { +- int relevance = element.library == containingLibrary +- ? DART_RELEVANCE_LOCAL_FUNCTION +- : DART_RELEVANCE_DEFAULT; +- addSuggestion(element, prefix: prefix, relevance: relevance); +- } +- } +- +- @override +- void visitLibraryElement(LibraryElement element) { +- if (visitedLibraries.add(element)) { +- element.visitChildren(this); +- } +- } +- +- @override +- void visitPropertyAccessorElement(PropertyAccessorElement element) { +- if (optype.includeReturnValueSuggestions) { +- int relevance; +- if (element.library == containingLibrary) { +- if (element.enclosingElement is ClassElement) { +- relevance = DART_RELEVANCE_LOCAL_FIELD; +- } else { +- relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE; +- } +- } else { +- relevance = DART_RELEVANCE_DEFAULT; +- } +- addSuggestion(element, prefix: prefix, relevance: relevance); +- } +- } +- +- @override +- void visitTopLevelVariableElement(TopLevelVariableElement element) { +- if (optype.includeReturnValueSuggestions) { +- int relevance = element.library == containingLibrary +- ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE +- : DART_RELEVANCE_DEFAULT; +- addSuggestion(element, prefix: prefix, relevance: relevance); +- } +- } +- +- /** +- * Add constructor suggestions for the given class. +- */ +- void _addConstructorSuggestions(ClassElement classElem, int relevance) { +- String className = classElem.name; +- for (ConstructorElement constructor in classElem.constructors) { +- if (!constructor.isPrivate) { +- CompletionSuggestion suggestion = +- createSuggestion(constructor, relevance: relevance); +- if (suggestion != null) { +- String name = suggestion.completion; +- name = name.length > 0 ? '$className.$name' : className; +- if (prefix != null && prefix.length > 0) { +- name = '$prefix.$name'; +- } +- suggestion.completion = name; +- suggestion.selectionOffset = suggestion.completion.length; +- suggestions.add(suggestion); +- } +- } +- } +- } +-} +- +-/** +- * A contributor for calculating suggestions for top level members +- * in the library in which the completion is requested +- * but outside the file in which the completion is requested. +- */ +-class LocalLibraryContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- if (!request.includeIdentifiers) { +- return EMPTY_LIST; +- } +- +- List libraryUnits = +- request.result.unit.element.library.units; +- if (libraryUnits == null) { +- return EMPTY_LIST; +- } +- +- OpType optype = (request as DartCompletionRequestImpl).opType; +- LibraryElementSuggestionBuilder visitor = +- new LibraryElementSuggestionBuilder(request, optype); +- for (CompilationUnitElement unit in libraryUnits) { +- if (unit != null && unit.source != request.source) { +- unit.accept(visitor); +- } +- } +- return visitor.suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart +deleted file mode 100644 +index 3ae01206584..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart ++++ /dev/null +@@ -1,517 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind, Location; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart' +- show DartCompletionRequestImpl; +-import 'package:analysis_server/src/services/completion/dart/utilities.dart'; +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analysis_server/src/utilities/documentation.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol +- show Element, ElementKind; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +-import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart' +- show LocalDeclarationVisitor; +- +-/** +- * A contributor for calculating suggestions for declarations in the local +- * file and containing library. +- */ +-class LocalReferenceContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- OpType optype = (request as DartCompletionRequestImpl).opType; +- AstNode node = request.target.containingNode; +- +- // Suggest local fields for constructor initializers +- bool suggestLocalFields = node is ConstructorDeclaration && +- node.initializers.contains(request.target.entity); +- +- // Collect suggestions from the specific child [AstNode] that contains +- // the completion offset and all of its parents recursively. +- if (!optype.isPrefixed) { +- if (optype.includeReturnValueSuggestions || +- optype.includeTypeNameSuggestions || +- optype.includeVoidReturnSuggestions || +- suggestLocalFields) { +- // Do not suggest local vars within the current expression +- while (node is Expression) { +- node = node.parent; +- } +- +- // Do not suggest loop variable of a ForEachStatement +- // when completing the expression of the ForEachStatement +- if (node is ForEachStatement) { +- node = node.parent; +- } +- +- _LocalVisitor visitor = new _LocalVisitor( +- request, request.offset, optype, +- suggestLocalFields: suggestLocalFields); +- visitor.visit(node); +- return visitor.suggestions; +- } +- } +- return EMPTY_LIST; +- } +-} +- +-/** +- * A visitor for collecting suggestions from the most specific child [AstNode] +- * that contains the completion offset to the [CompilationUnit]. +- */ +-class _LocalVisitor extends LocalDeclarationVisitor { +- final DartCompletionRequest request; +- final OpType optype; +- final bool suggestLocalFields; +- final Map suggestionMap = +- {}; +- int privateMemberRelevance = DART_RELEVANCE_DEFAULT; +- bool targetIsFunctionalArgument; +- +- _LocalVisitor(this.request, int offset, this.optype, +- {this.suggestLocalFields}) +- : super(offset) { +- // Suggestions for inherited members provided by InheritedReferenceContributor +- targetIsFunctionalArgument = request.target.isFunctionalArgument(); +- +- // If user typed identifier starting with '_' +- // then do not suppress the relevance of private members +- var data = request.result != null +- ? request.result.content +- : request.sourceContents; +- int offset = request.offset; +- if (data != null && 0 < offset && offset <= data.length) { +- bool isIdentifierChar(int index) { +- int code = data.codeUnitAt(index); +- return isLetterOrDigit(code) || code == CHAR_UNDERSCORE; +- } +- +- if (isIdentifierChar(offset - 1)) { +- while (offset > 0 && isIdentifierChar(offset - 1)) { +- --offset; +- } +- if (data.codeUnitAt(offset) == CHAR_UNDERSCORE) { +- privateMemberRelevance = null; +- } +- } +- } +- } +- +- List get suggestions => suggestionMap.values.toList(); +- +- @override +- void declaredClass(ClassDeclaration declaration) { +- if (optype.includeTypeNameSuggestions) { +- _addLocalSuggestion_includeTypeNameSuggestions( +- declaration.documentationComment, +- declaration.name, +- NO_RETURN_TYPE, +- protocol.ElementKind.CLASS, +- isAbstract: declaration.isAbstract, +- isDeprecated: isDeprecated(declaration)); +- } +- } +- +- @override +- void declaredClassTypeAlias(ClassTypeAlias declaration) { +- if (optype.includeTypeNameSuggestions) { +- _addLocalSuggestion_includeTypeNameSuggestions( +- declaration.documentationComment, +- declaration.name, +- NO_RETURN_TYPE, +- protocol.ElementKind.CLASS_TYPE_ALIAS, +- isAbstract: true, +- isDeprecated: isDeprecated(declaration)); +- } +- } +- +- @override +- void declaredEnum(EnumDeclaration declaration) { +- if (optype.includeTypeNameSuggestions) { +- _addLocalSuggestion_includeTypeNameSuggestions( +- declaration.documentationComment, +- declaration.name, +- NO_RETURN_TYPE, +- protocol.ElementKind.ENUM, +- isDeprecated: isDeprecated(declaration)); +- for (EnumConstantDeclaration enumConstant in declaration.constants) { +- if (!enumConstant.isSynthetic) { +- _addLocalSuggestion_includeReturnValueSuggestions_enumConstant( +- enumConstant, declaration, +- isDeprecated: isDeprecated(declaration)); +- } +- } +- } +- } +- +- @override +- void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { +- if ((optype.includeReturnValueSuggestions && +- (!optype.inStaticMethodBody || fieldDecl.isStatic)) || +- suggestLocalFields) { +- bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl); +- TypeAnnotation typeName = fieldDecl.fields.type; +- _addLocalSuggestion_includeReturnValueSuggestions( +- fieldDecl.documentationComment, +- varDecl.name, +- typeName, +- protocol.ElementKind.FIELD, +- isDeprecated: deprecated, +- relevance: DART_RELEVANCE_LOCAL_FIELD, +- classDecl: fieldDecl.parent); +- } +- } +- +- @override +- void declaredFunction(FunctionDeclaration declaration) { +- if (optype.includeReturnValueSuggestions || +- optype.includeVoidReturnSuggestions) { +- TypeAnnotation typeName = declaration.returnType; +- protocol.ElementKind elemKind; +- int relevance = DART_RELEVANCE_DEFAULT; +- if (declaration.isGetter) { +- elemKind = protocol.ElementKind.GETTER; +- relevance = DART_RELEVANCE_LOCAL_ACCESSOR; +- } else if (declaration.isSetter) { +- if (!optype.includeVoidReturnSuggestions) { +- return; +- } +- elemKind = protocol.ElementKind.SETTER; +- typeName = NO_RETURN_TYPE; +- relevance = DART_RELEVANCE_LOCAL_ACCESSOR; +- } else { +- if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) { +- return; +- } +- elemKind = protocol.ElementKind.FUNCTION; +- relevance = DART_RELEVANCE_LOCAL_FUNCTION; +- } +- _addLocalSuggestion_includeReturnValueSuggestions( +- declaration.documentationComment, +- declaration.name, +- typeName, +- elemKind, +- isDeprecated: isDeprecated(declaration), +- param: declaration.functionExpression.parameters, +- relevance: relevance); +- } +- } +- +- @override +- void declaredFunctionTypeAlias(FunctionTypeAlias declaration) { +- if (optype.includeTypeNameSuggestions) { +- // TODO (danrubel) determine parameters and return type +- _addLocalSuggestion_includeTypeNameSuggestions( +- declaration.documentationComment, +- declaration.name, +- declaration.returnType, +- protocol.ElementKind.FUNCTION_TYPE_ALIAS, +- isAbstract: true, +- isDeprecated: isDeprecated(declaration)); +- } +- } +- +- @override +- void declaredLabel(Label label, bool isCaseLabel) { +- // ignored +- } +- +- @override +- void declaredLocalVar(SimpleIdentifier id, TypeAnnotation typeName) { +- if (optype.includeReturnValueSuggestions) { +- _addLocalSuggestion_includeReturnValueSuggestions( +- null, id, typeName, protocol.ElementKind.LOCAL_VARIABLE, +- relevance: DART_RELEVANCE_LOCAL_VARIABLE); +- } +- } +- +- @override +- void declaredMethod(MethodDeclaration declaration) { +- if ((optype.includeReturnValueSuggestions || +- optype.includeVoidReturnSuggestions) && +- (!optype.inStaticMethodBody || declaration.isStatic)) { +- protocol.ElementKind elemKind; +- FormalParameterList param; +- TypeAnnotation typeName = declaration.returnType; +- int relevance = DART_RELEVANCE_DEFAULT; +- if (declaration.isGetter) { +- elemKind = protocol.ElementKind.GETTER; +- param = null; +- relevance = DART_RELEVANCE_LOCAL_ACCESSOR; +- } else if (declaration.isSetter) { +- if (!optype.includeVoidReturnSuggestions) { +- return; +- } +- elemKind = protocol.ElementKind.SETTER; +- typeName = NO_RETURN_TYPE; +- relevance = DART_RELEVANCE_LOCAL_ACCESSOR; +- } else { +- if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) { +- return; +- } +- elemKind = protocol.ElementKind.METHOD; +- param = declaration.parameters; +- relevance = DART_RELEVANCE_LOCAL_METHOD; +- } +- _addLocalSuggestion_includeReturnValueSuggestions( +- declaration.documentationComment, +- declaration.name, +- typeName, +- elemKind, +- isAbstract: declaration.isAbstract, +- isDeprecated: isDeprecated(declaration), +- classDecl: declaration.parent, +- param: param, +- relevance: relevance); +- } +- } +- +- @override +- void declaredParam(SimpleIdentifier id, TypeAnnotation typeName) { +- if (optype.includeReturnValueSuggestions) { +- _addLocalSuggestion_includeReturnValueSuggestions( +- null, id, typeName, protocol.ElementKind.PARAMETER, +- relevance: DART_RELEVANCE_PARAMETER); +- } +- } +- +- @override +- void declaredTopLevelVar( +- VariableDeclarationList varList, VariableDeclaration varDecl) { +- if (optype.includeReturnValueSuggestions) { +- _addLocalSuggestion_includeReturnValueSuggestions( +- varDecl.documentationComment, +- varDecl.name, +- varList.type, +- protocol.ElementKind.TOP_LEVEL_VARIABLE, +- isDeprecated: isDeprecated(varList) || isDeprecated(varDecl), +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- } +- } +- +- void _addLocalSuggestion(Comment documentationComment, SimpleIdentifier id, +- TypeAnnotation typeName, protocol.ElementKind elemKind, +- {bool isAbstract: false, +- bool isDeprecated: false, +- ClassDeclaration classDecl, +- FormalParameterList param, +- int relevance: DART_RELEVANCE_DEFAULT}) { +- CompletionSuggestionKind kind = targetIsFunctionalArgument +- ? CompletionSuggestionKind.IDENTIFIER +- : optype.suggestKind; +- CompletionSuggestion suggestion = createLocalSuggestion( +- id, isDeprecated, relevance, typeName, +- classDecl: classDecl, kind: kind); +- if (suggestion != null) { +- _setDocumentation(suggestion, documentationComment); +- if (privateMemberRelevance != null && +- suggestion.completion.startsWith('_')) { +- suggestion.relevance = privateMemberRelevance; +- } +- suggestionMap.putIfAbsent(suggestion.completion, () => suggestion); +- suggestion.element = createLocalElement(request.source, elemKind, id, +- isAbstract: isAbstract, +- isDeprecated: isDeprecated, +- parameters: param?.toSource(), +- returnType: typeName); +- if ((elemKind == protocol.ElementKind.METHOD || +- elemKind == protocol.ElementKind.FUNCTION) && +- param != null) { +- _addParameterInfo(suggestion, param); +- } +- } +- } +- +- void _addLocalSuggestion_enumConstant( +- EnumConstantDeclaration constantDeclaration, +- EnumDeclaration enumDeclaration, +- {bool isAbstract: false, +- bool isDeprecated: false, +- int relevance: DART_RELEVANCE_DEFAULT}) { +- String completion = +- '${enumDeclaration.name.name}.${constantDeclaration.name.name}'; +- CompletionSuggestion suggestion = new CompletionSuggestion( +- CompletionSuggestionKind.INVOCATION, +- isDeprecated ? DART_RELEVANCE_LOW : relevance, +- completion, +- completion.length, +- 0, +- isDeprecated, +- false, +- returnType: enumDeclaration.name.name); +- +- suggestionMap.putIfAbsent(suggestion.completion, () => suggestion); +- int flags = protocol.Element.makeFlags( +- isAbstract: isAbstract, +- isDeprecated: isDeprecated, +- isPrivate: Identifier.isPrivateName(constantDeclaration.name.name)); +- suggestion.element = new protocol.Element( +- protocol.ElementKind.ENUM_CONSTANT, +- constantDeclaration.name.name, +- flags, +- location: new Location( +- request.source.fullName, +- constantDeclaration.name.offset, +- constantDeclaration.name.length, +- 0, +- 0)); +- } +- +- void _addLocalSuggestion_includeReturnValueSuggestions( +- Comment documentationComment, +- SimpleIdentifier id, +- TypeAnnotation typeName, +- protocol.ElementKind elemKind, +- {bool isAbstract: false, +- bool isDeprecated: false, +- ClassDeclaration classDecl, +- FormalParameterList param, +- int relevance: DART_RELEVANCE_DEFAULT}) { +- relevance = optype.returnValueSuggestionsFilter( +- _staticTypeOfIdentifier(id), relevance); +- if (relevance != null) { +- _addLocalSuggestion(documentationComment, id, typeName, elemKind, +- isAbstract: isAbstract, +- isDeprecated: isDeprecated, +- classDecl: classDecl, +- param: param, +- relevance: relevance); +- } +- } +- +- void _addLocalSuggestion_includeReturnValueSuggestions_enumConstant( +- EnumConstantDeclaration constantDeclaration, +- EnumDeclaration enumDeclaration, +- {bool isAbstract: false, +- bool isDeprecated: false, +- int relevance: DART_RELEVANCE_DEFAULT}) { +- ClassElement classElement = +- resolutionMap.elementDeclaredByEnumDeclaration(enumDeclaration); +- relevance = +- optype.returnValueSuggestionsFilter(classElement?.type, relevance); +- if (relevance != null) { +- _addLocalSuggestion_enumConstant(constantDeclaration, enumDeclaration, +- isAbstract: isAbstract, +- isDeprecated: isDeprecated, +- relevance: relevance); +- } +- } +- +- void _addLocalSuggestion_includeTypeNameSuggestions( +- Comment documentationComment, +- SimpleIdentifier id, +- TypeAnnotation typeName, +- protocol.ElementKind elemKind, +- {bool isAbstract: false, +- bool isDeprecated: false, +- ClassDeclaration classDecl, +- FormalParameterList param, +- int relevance: DART_RELEVANCE_DEFAULT}) { +- relevance = optype.typeNameSuggestionsFilter( +- _staticTypeOfIdentifier(id), relevance); +- if (relevance != null) { +- _addLocalSuggestion(documentationComment, id, typeName, elemKind, +- isAbstract: isAbstract, +- isDeprecated: isDeprecated, +- classDecl: classDecl, +- param: param, +- relevance: relevance); +- } +- } +- +- void _addParameterInfo( +- CompletionSuggestion suggestion, FormalParameterList parameters) { +- var paramList = parameters.parameters; +- suggestion.parameterNames = paramList +- .map((FormalParameter param) => param.identifier.name) +- .toList(); +- suggestion.parameterTypes = paramList.map((FormalParameter param) { +- TypeAnnotation type = null; +- if (param is DefaultFormalParameter) { +- NormalFormalParameter child = param.parameter; +- if (child is SimpleFormalParameter) { +- type = child.type; +- } else if (child is FieldFormalParameter) { +- type = child.type; +- } +- } +- if (param is SimpleFormalParameter) { +- type = param.type; +- } else if (param is FieldFormalParameter) { +- type = param.type; +- } +- if (type == null) { +- return 'dynamic'; +- } +- if (type is TypeName) { +- Identifier typeId = type.name; +- if (typeId == null) { +- return 'dynamic'; +- } +- return typeId.name; +- } +- // TODO(brianwilkerson) Support function types. +- return 'dynamic'; +- }).toList(); +- +- Iterable requiredParameters = paramList +- .where((FormalParameter param) => param.kind == ParameterKind.REQUIRED) +- .map((p) => p.element); +- suggestion.requiredParameterCount = requiredParameters.length; +- +- Iterable namedParameters = paramList +- .where((FormalParameter param) => param.kind == ParameterKind.NAMED) +- .map((p) => p.element); +- suggestion.hasNamedParameters = namedParameters.isNotEmpty; +- +- addDefaultArgDetails(suggestion, null, requiredParameters, namedParameters); +- } +- +- bool _isVoid(TypeAnnotation returnType) { +- if (returnType is TypeName) { +- Identifier id = returnType.name; +- if (id != null && id.name == 'void') { +- return true; +- } +- } +- return false; +- } +- +- DartType _staticTypeOfIdentifier(Identifier id) { +- if (id.staticElement is ClassElement) { +- return (id.staticElement as ClassElement).type; +- } else { +- return id.staticType; +- } +- } +- +- /** +- * If the given [documentationComment] is not `null`, fill the [suggestion] +- * documentation fields. +- */ +- static void _setDocumentation( +- CompletionSuggestion suggestion, Comment documentationComment) { +- if (documentationComment != null) { +- String text = documentationComment.tokens +- .map((Token t) => t.toString()) +- .join('\n') +- .replaceAll('\r\n', '\n'); +- String doc = removeDartDocDelimiters(text); +- suggestion.docComplete = doc; +- suggestion.docSummary = getDartDocSummary(doc); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart +deleted file mode 100644 +index 5874ac51648..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart ++++ /dev/null +@@ -1,61 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +- +-/** +- * A contributor for calculating named constructor suggestions +- * such as suggesting `bar` in `new Foo.bar()`. +- */ +-class NamedConstructorContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- AstNode node = request.target.containingNode; +- LibraryElement libElem = request.libraryElement; +- if (libElem == null) { +- return EMPTY_LIST; +- } +- +- // Build the list of suggestions +- if (node is ConstructorName) { +- TypeName typeName = node.type; +- if (typeName != null) { +- DartType type = typeName.type; +- if (type != null) { +- Element classElem = type.element; +- if (classElem is ClassElement) { +- return _buildSuggestions(libElem, classElem); +- } +- } +- } +- } +- return EMPTY_LIST; +- } +- +- List _buildSuggestions( +- LibraryElement libElem, ClassElement classElem) { +- bool isLocalClassDecl = classElem.library == libElem; +- List suggestions = []; +- for (ConstructorElement elem in classElem.constructors) { +- if (isLocalClassDecl || !elem.isPrivate) { +- String name = elem.name; +- if (name != null) { +- CompletionSuggestion s = createSuggestion(elem, completion: name); +- if (s != null) { +- suggestions.add(s); +- } +- } +- } +- } +- return suggestions; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart +deleted file mode 100644 +index 492567f6f66..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart ++++ /dev/null +@@ -1,150 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/protocol_server.dart' as protocol +- hide CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/provisional/completion/completion_core.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'; +- +-/** +- * A completion contributor used to suggest replacing partial identifiers inside +- * a class declaration with templates for inherited members. +- */ +-class OverrideContributor implements DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- SimpleIdentifier targetId = _getTargetId(request.target); +- if (targetId == null) { +- return EMPTY_LIST; +- } +- ClassDeclaration classDecl = +- targetId.getAncestor((p) => p is ClassDeclaration); +- if (classDecl == null) { +- return EMPTY_LIST; +- } +- +- // Generate a collection of inherited members +- ClassElement classElem = classDecl.element; +- InheritanceManager manager = new InheritanceManager(classElem.library); +- Map map = +- manager.getMembersInheritedFromInterfaces(classElem); +- List memberNames = _computeMemberNames(map, classElem); +- +- // Build suggestions +- List suggestions = []; +- for (String memberName in memberNames) { +- ExecutableElement element = map[memberName]; +- // Gracefully degrade if the overridden element has not been resolved. +- if (element.returnType != null) { +- CompletionSuggestion suggestion = +- _buildSuggestion(request, targetId, element); +- if (suggestion != null) { +- suggestions.add(suggestion); +- } +- } +- } +- return suggestions; +- } +- +- /** +- * Return a template for an override of the given [element] in the given +- * [source]. If selected, the template will replace [targetId]. +- */ +- String _buildRepacementText(Source source, SimpleIdentifier targetId, +- CompilationUnit unit, ExecutableElement element) { +- // AnalysisContext context = element.context; +- // Inject partially resolved unit for use by change builder +- // DartChangeBuilder builder = new DartChangeBuilder(context, unit); +- // builder.addFileEdit(source, context.getModificationStamp(source), +- // (DartFileEditBuilder builder) { +- // builder.addReplacement(targetId.offset, targetId.length, +- // (DartEditBuilder builder) { +- // builder.writeOverrideOfInheritedMember(element); +- // }); +- // }); +- // return builder.sourceChange.edits[0].edits[0].replacement.trim(); +- return ''; +- } +- +- /** +- * Build a suggestion to replace [targetId] in the given [unit] +- * with an override of the given [element]. +- */ +- CompletionSuggestion _buildSuggestion(DartCompletionRequest request, +- SimpleIdentifier targetId, ExecutableElement element) { +- String completion = _buildRepacementText( +- request.source, targetId, request.target.unit, element); +- if (completion == null || completion.length == 0) { +- return null; +- } +- CompletionSuggestion suggestion = new CompletionSuggestion( +- CompletionSuggestionKind.IDENTIFIER, +- DART_RELEVANCE_HIGH, +- completion, +- targetId.offset, +- 0, +- element.isDeprecated, +- false); +- suggestion.element = protocol.convertElement(element); +- return suggestion; +- } +- +- /** +- * Return a list containing the names of all of the inherited but not +- * implemented members of the class represented by the given [element]. +- * The [map] is used to find all of the members that are inherited. +- */ +- List _computeMemberNames( +- Map map, ClassElement element) { +- List memberNames = []; +- for (String memberName in map.keys) { +- if (!_hasMember(element, memberName)) { +- memberNames.add(memberName); +- } +- } +- return memberNames; +- } +- +- /** +- * If the target looks like a partial identifier inside a class declaration +- * then return that identifier, otherwise return `null`. +- */ +- SimpleIdentifier _getTargetId(CompletionTarget target) { +- AstNode node = target.containingNode; +- if (node is ClassDeclaration) { +- Object entity = target.entity; +- if (entity is FieldDeclaration) { +- NodeList variables = entity.fields.variables; +- if (variables.length == 1) { +- SimpleIdentifier targetId = variables[0].name; +- if (targetId.name.isEmpty) { +- return targetId; +- } +- } +- } +- } +- return null; +- } +- +- /** +- * Return `true` if the given [classElement] directly declares a member with +- * the given [memberName]. +- */ +- bool _hasMember(ClassElement classElement, String memberName) { +- return classElement.getField(memberName) != null || +- classElement.getGetter(memberName) != null || +- classElement.getMethod(memberName) != null || +- classElement.getSetter(memberName) != null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart +deleted file mode 100644 +index 8239f37c20d..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart ++++ /dev/null +@@ -1,131 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +- +-import '../../../protocol_server.dart' show CompletionSuggestion; +- +-/** +- * A contributor for calculating static member invocation / access suggestions +- * `completion.getSuggestions` request results. +- */ +-class StaticMemberContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- Expression targetId = request.dotTarget; +- if (targetId is Identifier && !request.target.isCascade) { +- Element elem = targetId.bestElement; +- if (elem is ClassElement) { +- LibraryElement containingLibrary = request.libraryElement; +- // Gracefully degrade if the library could not be determined +- // e.g. detached part file or source change +- if (containingLibrary == null) { +- return EMPTY_LIST; +- } +- +- _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary); +- elem.accept(builder); +- return builder.suggestions; +- } +- } +- return EMPTY_LIST; +- } +-} +- +-/** +- * This class visits elements in a class and provides suggestions based upon +- * the visible static members in that class. +- */ +-class _SuggestionBuilder extends GeneralizingElementVisitor { +- /** +- * The library containing the unit in which the completion is requested. +- */ +- final LibraryElement containingLibrary; +- +- /** +- * A collection of completion suggestions. +- */ +- final List suggestions = []; +- +- _SuggestionBuilder(this.containingLibrary); +- +- @override +- visitClassElement(ClassElement element) { +- element.visitChildren(this); +- } +- +- @override +- visitElement(Element element) { +- // ignored +- } +- +- @override +- visitFieldElement(FieldElement element) { +- if (element.isStatic) { +- _addSuggestion(element); +- } +- } +- +- @override +- visitMethodElement(MethodElement element) { +- if (element.isStatic && !element.isOperator) { +- _addSuggestion(element); +- } +- } +- +- @override +- visitPropertyAccessorElement(PropertyAccessorElement element) { +- if (element.isStatic) { +- _addSuggestion(element); +- } +- } +- +- /** +- * Add a suggestion based upon the given element. +- */ +- void _addSuggestion(Element element) { +- if (element.isPrivate) { +- if (element.library != containingLibrary) { +- // Do not suggest private members for imported libraries +- return; +- } +- } +- if (element.isSynthetic) { +- if ((element is PropertyAccessorElement) || +- element is FieldElement && !_isSpecialEnumField(element)) { +- return; +- } +- } +- String completion = element.displayName; +- if (completion == null || completion.length <= 0) { +- return; +- } +- CompletionSuggestion suggestion = +- createSuggestion(element, completion: completion); +- if (suggestion != null) { +- suggestions.add(suggestion); +- } +- } +- +- /** +- * Determine if the given element is one of the synthetic enum accessors +- * for which we should generate a suggestion. +- */ +- bool _isSpecialEnumField(FieldElement element) { +- Element parent = element.enclosingElement; +- if (parent is ClassElement && parent.isEnum) { +- if (element.name == 'values') { +- return true; +- } +- } +- return false; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart +deleted file mode 100644 +index 83347c9fece..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart ++++ /dev/null +@@ -1,302 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart' as protocol; +-import 'package:analysis_server/src/protocol_server.dart' +- hide Element, ElementKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/utilities.dart'; +-import 'package:analysis_server/src/utilities/documentation.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/utilities_dart.dart'; +-import 'package:path/path.dart' as path; +- +-const String DYNAMIC = 'dynamic'; +- +-/** +- * Return a suggestion based upon the given element +- * or `null` if a suggestion is not appropriate for the given element. +- * If the suggestion is not currently in scope, then specify +- * importForSource as the source to which an import should be added. +- */ +-CompletionSuggestion createSuggestion(Element element, +- {String completion, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- int relevance: DART_RELEVANCE_DEFAULT, +- Source importForSource}) { +- if (element == null) { +- return null; +- } +- if (element is ExecutableElement && element.isOperator) { +- // Do not include operators in suggestions +- return null; +- } +- if (completion == null) { +- completion = element.displayName; +- } +- bool isDeprecated = element.isDeprecated; +- CompletionSuggestion suggestion = new CompletionSuggestion( +- kind, +- isDeprecated ? DART_RELEVANCE_LOW : relevance, +- completion, +- completion.length, +- 0, +- isDeprecated, +- false); +- +- // Attach docs. +- String doc = removeDartDocDelimiters(element.documentationComment); +- suggestion.docComplete = doc; +- suggestion.docSummary = getDartDocSummary(doc); +- +- suggestion.element = protocol.convertElement(element); +- Element enclosingElement = element.enclosingElement; +- if (enclosingElement is ClassElement) { +- suggestion.declaringType = enclosingElement.displayName; +- } +- suggestion.returnType = getReturnTypeString(element); +- if (element is ExecutableElement && element is! PropertyAccessorElement) { +- suggestion.parameterNames = element.parameters +- .map((ParameterElement parameter) => parameter.name) +- .toList(); +- suggestion.parameterTypes = +- element.parameters.map((ParameterElement parameter) { +- DartType paramType = parameter.type; +- // Gracefully degrade if type not resolved yet +- return paramType != null ? paramType.displayName : 'var'; +- }).toList(); +- +- Iterable requiredParameters = element.parameters.where( +- (ParameterElement param) => +- param.parameterKind == ParameterKind.REQUIRED); +- suggestion.requiredParameterCount = requiredParameters.length; +- +- Iterable namedParameters = element.parameters.where( +- (ParameterElement param) => param.parameterKind == ParameterKind.NAMED); +- suggestion.hasNamedParameters = namedParameters.isNotEmpty; +- +- addDefaultArgDetails( +- suggestion, element, requiredParameters, namedParameters); +- } +- if (importForSource != null) { +- String srcPath = path.dirname(importForSource.fullName); +- LibraryElement libElem = element.library; +- if (libElem != null) { +- Source libSource = libElem.source; +- if (libSource != null) { +- UriKind uriKind = libSource.uriKind; +- if (uriKind == UriKind.DART_URI) { +- suggestion.importUri = libSource.uri.toString(); +- } else if (uriKind == UriKind.PACKAGE_URI) { +- suggestion.importUri = libSource.uri.toString(); +- } else if (uriKind == UriKind.FILE_URI && +- element.source.uriKind == UriKind.FILE_URI) { +- try { +- suggestion.importUri = +- path.relative(libSource.fullName, from: srcPath); +- } catch (_) { +- // ignored +- } +- } +- } +- } +- if (suggestion.importUri == null) { +- // Do not include out of scope suggestions +- // for which we cannot determine an import +- return null; +- } +- } +- return suggestion; +-} +- +-/** +- * Common mixin for sharing behavior +- */ +-abstract class ElementSuggestionBuilder { +- /** +- * A collection of completion suggestions. +- */ +- final List suggestions = []; +- +- /** +- * A set of existing completions used to prevent duplicate suggestions. +- */ +- final Set _completions = new Set(); +- +- /** +- * A map of element names to suggestions for synthetic getters and setters. +- */ +- final Map _syntheticMap = +- {}; +- +- /** +- * Return the library in which the completion is requested. +- */ +- LibraryElement get containingLibrary; +- +- /** +- * Return the kind of suggestions that should be built. +- */ +- CompletionSuggestionKind get kind; +- +- /** +- * Add a suggestion based upon the given element. +- */ +- void addSuggestion(Element element, +- {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) { +- if (element.isPrivate) { +- if (element.library != containingLibrary) { +- return; +- } +- } +- String completion = element.displayName; +- if (prefix != null && prefix.length > 0) { +- if (completion == null || completion.length <= 0) { +- completion = prefix; +- } else { +- completion = '$prefix.$completion'; +- } +- } +- if (completion == null || completion.length <= 0) { +- return; +- } +- CompletionSuggestion suggestion = createSuggestion(element, +- completion: completion, kind: kind, relevance: relevance); +- if (suggestion != null) { +- if (element.isSynthetic && element is PropertyAccessorElement) { +- String cacheKey; +- if (element.isGetter) { +- cacheKey = element.name; +- } +- if (element.isSetter) { +- cacheKey = element.name; +- cacheKey = cacheKey.substring(0, cacheKey.length - 1); +- } +- if (cacheKey != null) { +- CompletionSuggestion existingSuggestion = _syntheticMap[cacheKey]; +- +- // Pair getter/setter by updating the existing suggestion +- if (existingSuggestion != null) { +- CompletionSuggestion getter = +- element.isGetter ? suggestion : existingSuggestion; +- protocol.ElementKind elemKind = +- element.enclosingElement is ClassElement +- ? protocol.ElementKind.FIELD +- : protocol.ElementKind.TOP_LEVEL_VARIABLE; +- existingSuggestion.element = new protocol.Element( +- elemKind, +- existingSuggestion.element.name, +- existingSuggestion.element.flags, +- location: getter.element.location, +- typeParameters: getter.element.typeParameters, +- parameters: null, +- returnType: getter.returnType); +- return; +- } +- +- // Cache lone getter/setter so that it can be paired +- _syntheticMap[cacheKey] = suggestion; +- } +- } +- if (_completions.add(suggestion.completion)) { +- suggestions.add(suggestion); +- } +- } +- } +-} +- +-/** +- * This class visits elements in a library and provides suggestions based upon +- * the visible members in that library. +- */ +-class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor +- with ElementSuggestionBuilder { +- final LibraryElement containingLibrary; +- final CompletionSuggestionKind kind; +- final bool typesOnly; +- final bool instCreation; +- +- /** +- * The set of libraries that have been, or are currently being, visited. +- */ +- final Set visitedLibraries = new Set(); +- +- LibraryElementSuggestionBuilder( +- this.containingLibrary, this.kind, this.typesOnly, this.instCreation); +- +- @override +- visitClassElement(ClassElement element) { +- if (instCreation) { +- element.visitChildren(this); +- } else { +- addSuggestion(element); +- } +- } +- +- @override +- visitCompilationUnitElement(CompilationUnitElement element) { +- element.visitChildren(this); +- LibraryElement containingLibrary = element.library; +- if (containingLibrary != null) { +- for (var lib in containingLibrary.exportedLibraries) { +- lib.accept(this); +- } +- } +- } +- +- @override +- visitConstructorElement(ConstructorElement element) { +- if (instCreation) { +- ClassElement classElem = element.enclosingElement; +- if (classElem != null) { +- String prefix = classElem.name; +- if (prefix != null && prefix.length > 0) { +- addSuggestion(element, prefix: prefix); +- } +- } +- } +- } +- +- @override +- visitElement(Element element) { +- // ignored +- } +- +- @override +- visitFunctionElement(FunctionElement element) { +- if (!typesOnly) { +- int relevance = element.library == containingLibrary +- ? DART_RELEVANCE_LOCAL_FUNCTION +- : DART_RELEVANCE_DEFAULT; +- addSuggestion(element, relevance: relevance); +- } +- } +- +- @override +- visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { +- if (!instCreation) { +- addSuggestion(element); +- } +- } +- +- @override +- visitLibraryElement(LibraryElement element) { +- if (visitedLibraries.add(element)) { +- element.visitChildren(this); +- } +- } +- +- @override +- visitTopLevelVariableElement(TopLevelVariableElement element) { +- if (!typesOnly) { +- int relevance = element.library == containingLibrary +- ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE +- : DART_RELEVANCE_DEFAULT; +- addSuggestion(element, relevance: relevance); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart +deleted file mode 100644 +index e49bdab5ddb..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart ++++ /dev/null +@@ -1,411 +0,0 @@ +-// Copyright (c) 2014, 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:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart'; +- +-import '../../../protocol_server.dart' show CompletionSuggestion; +- +-/** +- * A contributor for calculating instance invocation / access suggestions +- * `completion.getSuggestions` request results. +- */ +-class TypeMemberContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- LibraryElement containingLibrary = request.libraryElement; +- // Gracefully degrade if the library element is not resolved +- // e.g. detached part file or source change +- if (containingLibrary == null) { +- return EMPTY_LIST; +- } +- +- // Recompute the target since resolution may have changed it +- Expression expression = request.dotTarget; +- if (expression == null || expression.isSynthetic) { +- return EMPTY_LIST; +- } +- if (expression is Identifier) { +- Element elem = expression.bestElement; +- if (elem is ClassElement) { +- // Suggestions provided by StaticMemberContributor +- return EMPTY_LIST; +- } +- if (elem is PrefixElement) { +- // Suggestions provided by LibraryMemberContributor +- return EMPTY_LIST; +- } +- } +- +- // Determine the target expression's type +- DartType type = expression.bestType; +- if (type.isDynamic) { +- // If the expression does not provide a good type +- // then attempt to get a better type from the element +- if (expression is Identifier) { +- Element elem = expression.bestElement; +- if (elem is FunctionTypedElement) { +- type = elem.returnType; +- } else if (elem is ParameterElement) { +- type = elem.type; +- } else if (elem is LocalVariableElement) { +- type = elem.type; +- } +- if ((type == null || type.isDynamic) && +- expression is SimpleIdentifier) { +- // If the element does not provide a good type +- // then attempt to get a better type from a local declaration +- _LocalBestTypeVisitor visitor = +- new _LocalBestTypeVisitor(expression.name, request.offset); +- if (visitor.visit(expression) && visitor.typeFound != null) { +- type = visitor.typeFound; +- } +- } +- } +- } +- String containingMethodName; +- if (expression is SuperExpression && type is InterfaceType) { +- // Suggest members from superclass if target is "super" +- type = (type as InterfaceType).superclass; +- // Determine the name of the containing method because +- // the most likely completion is a super expression with same name +- MethodDeclaration containingMethod = +- expression.getAncestor((p) => p is MethodDeclaration); +- if (containingMethod != null) { +- SimpleIdentifier id = containingMethod.name; +- if (id != null) { +- containingMethodName = id.name; +- } +- } +- } +- if (type.isDynamic) { +- // Suggest members from object if target is "dynamic" +- type = request.objectType; +- } +- +- // Build the suggestions +- if (type is InterfaceType) { +- _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary); +- builder.buildSuggestions(type, containingMethodName); +- return builder.suggestions.toList(); +- } +- return EMPTY_LIST; +- } +-} +- +-/** +- * An [AstVisitor] which looks for a declaration with the given name +- * and if found, tries to determine a type for that declaration. +- */ +-class _LocalBestTypeVisitor extends LocalDeclarationVisitor { +- /** +- * The name for the declaration to be found. +- */ +- final String targetName; +- +- /** +- * The best type for the found declaration, +- * or `null` if no declaration found or failed to determine a type. +- */ +- DartType typeFound; +- +- /** +- * Construct a new instance to search for a declaration +- */ +- _LocalBestTypeVisitor(this.targetName, int offset) : super(offset); +- +- @override +- void declaredClass(ClassDeclaration declaration) { +- if (declaration.name.name == targetName) { +- // no type +- finished(); +- } +- } +- +- @override +- void declaredClassTypeAlias(ClassTypeAlias declaration) { +- if (declaration.name.name == targetName) { +- // no type +- finished(); +- } +- } +- +- @override +- void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { +- if (varDecl.name.name == targetName) { +- // Type provided by the element in computeFull above +- finished(); +- } +- } +- +- @override +- void declaredFunction(FunctionDeclaration declaration) { +- if (declaration.name.name == targetName) { +- TypeAnnotation typeName = declaration.returnType; +- if (typeName != null) { +- typeFound = typeName.type; +- } +- finished(); +- } +- } +- +- @override +- void declaredFunctionTypeAlias(FunctionTypeAlias declaration) { +- if (declaration.name.name == targetName) { +- TypeAnnotation typeName = declaration.returnType; +- if (typeName != null) { +- typeFound = typeName.type; +- } +- finished(); +- } +- } +- +- @override +- void declaredLabel(Label label, bool isCaseLabel) { +- if (label.label.name == targetName) { +- // no type +- finished(); +- } +- } +- +- @override +- void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type) { +- if (name.name == targetName) { +- typeFound = name.bestType; +- finished(); +- } +- } +- +- @override +- void declaredMethod(MethodDeclaration declaration) { +- if (declaration.name.name == targetName) { +- TypeAnnotation typeName = declaration.returnType; +- if (typeName != null) { +- typeFound = typeName.type; +- } +- finished(); +- } +- } +- +- @override +- void declaredParam(SimpleIdentifier name, TypeAnnotation type) { +- if (name.name == targetName) { +- // Type provided by the element in computeFull above +- finished(); +- } +- } +- +- @override +- void declaredTopLevelVar( +- VariableDeclarationList varList, VariableDeclaration varDecl) { +- if (varDecl.name.name == targetName) { +- // Type provided by the element in computeFull above +- finished(); +- } +- } +-} +- +-/** +- * This class provides suggestions based upon the visible instance members in +- * an interface type. +- */ +-class _SuggestionBuilder { +- /** +- * Enumerated value indicating that we have not generated any completions for +- * a given identifier yet. +- */ +- static const int _COMPLETION_TYPE_NONE = 0; +- +- /** +- * Enumerated value indicating that we have generated a completion for a +- * getter. +- */ +- static const int _COMPLETION_TYPE_GETTER = 1; +- +- /** +- * Enumerated value indicating that we have generated a completion for a +- * setter. +- */ +- static const int _COMPLETION_TYPE_SETTER = 2; +- +- /** +- * Enumerated value indicating that we have generated a completion for a +- * field, a method, or a getter/setter pair. +- */ +- static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3; +- +- /** +- * The library containing the unit in which the completion is requested. +- */ +- final LibraryElement containingLibrary; +- +- /** +- * Map indicating, for each possible completion identifier, whether we have +- * already generated completions for a getter, setter, or both. The "both" +- * case also handles the case where have generated a completion for a method +- * or a field. +- * +- * Note: the enumerated values stored in this map are intended to be bitwise +- * compared. +- */ +- Map _completionTypesGenerated = new HashMap(); +- +- /** +- * Map from completion identifier to completion suggestion +- */ +- Map _suggestionMap = +- {}; +- +- _SuggestionBuilder(this.containingLibrary); +- +- Iterable get suggestions => _suggestionMap.values; +- +- /** +- * Return completion suggestions for 'dot' completions on the given [type]. +- * If the 'dot' completion is a super expression, then [containingMethodName] +- * is the name of the method in which the completion is requested. +- */ +- void buildSuggestions(InterfaceType type, String containingMethodName) { +- // Visit all of the types in the class hierarchy, collecting possible +- // completions. If multiple elements are found that complete to the same +- // identifier, addSuggestion will discard all but the first (with a few +- // exceptions to handle getter/setter pairs). +- List types = _getTypeOrdering(type); +- for (InterfaceType targetType in types) { +- for (MethodElement method in targetType.methods) { +- // Exclude static methods when completion on an instance +- if (!method.isStatic) { +- // Boost the relevance of a super expression +- // calling a method of the same name as the containing method +- _addSuggestion(method, +- relevance: method.name == containingMethodName +- ? DART_RELEVANCE_HIGH +- : DART_RELEVANCE_DEFAULT); +- } +- } +- for (PropertyAccessorElement propertyAccessor in targetType.accessors) { +- if (!propertyAccessor.isStatic) { +- if (propertyAccessor.isSynthetic) { +- // Avoid visiting a field twice +- if (propertyAccessor.isGetter) { +- _addSuggestion(propertyAccessor.variable); +- } +- } else { +- _addSuggestion(propertyAccessor); +- } +- } +- } +- } +- } +- +- /** +- * Add a suggestion based upon the given element, provided that it is not +- * shadowed by a previously added suggestion. +- */ +- void _addSuggestion(Element element, +- {int relevance: DART_RELEVANCE_DEFAULT}) { +- if (element.isPrivate) { +- if (element.library != containingLibrary) { +- // Do not suggest private members for imported libraries +- return; +- } +- } +- String identifier = element.displayName; +- +- if (relevance == DART_RELEVANCE_DEFAULT && identifier != null) { +- // Decrease relevance of suggestions starting with $ +- // https://github.com/dart-lang/sdk/issues/27303 +- if (identifier.startsWith(r'$')) { +- relevance = DART_RELEVANCE_LOW; +- } +- } +- +- int alreadyGenerated = _completionTypesGenerated.putIfAbsent( +- identifier, () => _COMPLETION_TYPE_NONE); +- if (element is MethodElement) { +- // Anything shadows a method. +- if (alreadyGenerated != _COMPLETION_TYPE_NONE) { +- return; +- } +- _completionTypesGenerated[identifier] = +- _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET; +- } else if (element is PropertyAccessorElement) { +- if (element.isGetter) { +- // Getters, fields, and methods shadow a getter. +- if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) { +- return; +- } +- _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER; +- } else { +- // Setters, fields, and methods shadow a setter. +- if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) { +- return; +- } +- _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER; +- } +- } else if (element is FieldElement) { +- // Fields and methods shadow a field. A getter/setter pair shadows a +- // field, but a getter or setter by itself doesn't. +- if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) { +- return; +- } +- _completionTypesGenerated[identifier] = +- _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET; +- } else { +- // Unexpected element type; skip it. +- assert(false); +- return; +- } +- CompletionSuggestion suggestion = +- createSuggestion(element, relevance: relevance); +- if (suggestion != null) { +- _suggestionMap[suggestion.completion] = suggestion; +- } +- } +- +- /** +- * Get a list of [InterfaceType]s that should be searched to find the +- * possible completions for an object having type [type]. +- */ +- List _getTypeOrdering(InterfaceType type) { +- // Candidate completions can come from [type] as well as any types above it +- // in the class hierarchy (including mixins, superclasses, and interfaces). +- // If a given completion identifier shows up in multiple types, we should +- // use the element that is nearest in the superclass chain, so we will +- // visit [type] first, then its mixins, then its superclass, then its +- // superclass's mixins, etc., and only afterwards visit interfaces. +- // +- // We short-circuit loops in the class hierarchy by keeping track of the +- // classes seen (not the interfaces) so that we won't be fooled by nonsense +- // like "class C extends C> {}" +- List result = []; +- Set classesSeen = new HashSet(); +- List typesToVisit = [type]; +- while (typesToVisit.isNotEmpty) { +- InterfaceType nextType = typesToVisit.removeLast(); +- if (!classesSeen.add(nextType.element)) { +- // Class had already been seen, so ignore this type. +- continue; +- } +- result.add(nextType); +- // typesToVisit is a stack, so push on the interfaces first, then the +- // superclass, then the mixins. This will ensure that they are visited +- // in the reverse order. +- typesToVisit.addAll(nextType.interfaces); +- if (nextType.superclass != null) { +- typesToVisit.add(nextType.superclass); +- } +- typesToVisit.addAll(nextType.mixins); +- } +- return result; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart +deleted file mode 100644 +index 59c0f2befbe..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart ++++ /dev/null +@@ -1,242 +0,0 @@ +-// Copyright (c) 2014, 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:core'; +- +-import 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:path/path.dart' show posix; +-import 'package:path/src/context.dart'; +- +-/** +- * A contributor for calculating uri suggestions +- * for import and part directives. +- */ +-class UriContributor extends DartCompletionContributor { +- _UriSuggestionBuilder builder; +- +- /** +- * A flag indicating whether file: and package: URI suggestions should +- * be included in the list of completion suggestions. +- */ +- // TODO(danrubel): remove this flag and related functionality +- // once the UriContributor limits file: and package: URI suggestions +- // to only those paths within context roots. +- static bool suggestFilePaths = true; +- +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- builder = new _UriSuggestionBuilder(request); +- request.target.containingNode.accept(builder); +- return builder.suggestions; +- } +-} +- +-class _UriSuggestionBuilder extends SimpleAstVisitor { +- final DartCompletionRequest request; +- final List suggestions = []; +- +- _UriSuggestionBuilder(this.request); +- +- @override +- visitExportDirective(ExportDirective node) { +- visitNamespaceDirective(node); +- } +- +- @override +- visitImportDirective(ImportDirective node) { +- visitNamespaceDirective(node); +- } +- +- visitNamespaceDirective(NamespaceDirective node) { +- StringLiteral uri = node.uri; +- if (uri is SimpleStringLiteral) { +- int offset = request.offset; +- int start = uri.offset; +- int end = uri.end; +- if (offset > start) { +- if (offset < end) { +- // Quoted non-empty string +- visitSimpleStringLiteral(uri); +- } else if (offset == end) { +- if (end == start + 1) { +- // Quoted empty string +- visitSimpleStringLiteral(uri); +- } else { +- String data = request.sourceContents; +- if (end == data.length) { +- String ch = data[end - 1]; +- if (ch != '"' && ch != "'") { +- // Insertion point at end of file +- // and missing closing quote on non-empty string +- visitSimpleStringLiteral(uri); +- } +- } +- } +- } +- } else if (offset == start && offset == end) { +- String data = request.sourceContents; +- if (end == data.length) { +- String ch = data[end - 1]; +- if (ch == '"' || ch == "'") { +- // Insertion point at end of file +- // and missing closing quote on empty string +- visitSimpleStringLiteral(uri); +- } +- } +- } +- } +- } +- +- @override +- visitSimpleStringLiteral(SimpleStringLiteral node) { +- AstNode parent = node.parent; +- if (parent is NamespaceDirective && parent.uri == node) { +- String partialUri = _extractPartialUri(node); +- if (partialUri != null) { +- _addDartSuggestions(); +- if (UriContributor.suggestFilePaths) { +- _addPackageSuggestions(partialUri); +- _addFileSuggestions(partialUri); +- } +- } +- } else if (parent is PartDirective && parent.uri == node) { +- String partialUri = _extractPartialUri(node); +- if (partialUri != null) { +- if (UriContributor.suggestFilePaths) { +- _addFileSuggestions(partialUri); +- } +- } +- } +- } +- +- void _addDartSuggestions() { +- _addSuggestion('dart:'); +- SourceFactory factory = request.sourceFactory; +- for (SdkLibrary lib in factory.dartSdk.sdkLibraries) { +- if (!lib.isInternal && !lib.isImplementation) { +- if (!lib.shortName.startsWith('dart:_')) { +- _addSuggestion(lib.shortName, +- relevance: lib.shortName == 'dart:core' +- ? DART_RELEVANCE_LOW +- : DART_RELEVANCE_DEFAULT); +- } +- } +- } +- } +- +- void _addFileSuggestions(String partialUri) { +- ResourceProvider resProvider = request.resourceProvider; +- Context resContext = resProvider.pathContext; +- Source source = request.source; +- +- String parentUri; +- if ((partialUri.endsWith('/'))) { +- parentUri = partialUri; +- } else { +- parentUri = posix.dirname(partialUri); +- if (parentUri != '.' && !parentUri.endsWith('/')) { +- parentUri = '$parentUri/'; +- } +- } +- String uriPrefix = parentUri == '.' ? '' : parentUri; +- +- String dirPath = resContext.normalize(parentUri); +- if (resContext.isRelative(dirPath)) { +- String sourceDirPath = resContext.dirname(source.fullName); +- if (resContext.isAbsolute(sourceDirPath)) { +- dirPath = resContext.normalize(resContext.join(sourceDirPath, dirPath)); +- } else { +- return; +- } +- // Do not suggest relative paths reaching outside the 'lib' directory. +- bool srcInLib = resContext.split(sourceDirPath).contains('lib'); +- bool dstInLib = resContext.split(dirPath).contains('lib'); +- if (srcInLib && !dstInLib) { +- return; +- } +- } +- if (dirPath.endsWith('\\.')) { +- dirPath = dirPath.substring(0, dirPath.length - 1); +- } +- +- Resource dir = resProvider.getResource(dirPath); +- if (dir is Folder) { +- try { +- for (Resource child in dir.getChildren()) { +- String completion; +- if (child is Folder) { +- completion = '$uriPrefix${child.shortName}/'; +- } else { +- completion = '$uriPrefix${child.shortName}'; +- } +- if (completion != source.shortName) { +- _addSuggestion(completion); +- } +- } +- } on FileSystemException { +- // Guard against I/O exceptions. +- } +- } +- } +- +- void _addPackageFolderSuggestions( +- String partial, String prefix, Folder folder) { +- try { +- for (Resource child in folder.getChildren()) { +- if (child is Folder) { +- String childPrefix = '$prefix${child.shortName}/'; +- _addSuggestion(childPrefix); +- if (partial.startsWith(childPrefix)) { +- _addPackageFolderSuggestions(partial, childPrefix, child); +- } +- } else { +- _addSuggestion('$prefix${child.shortName}'); +- } +- } +- } on FileSystemException { +- // Guard against I/O exceptions. +- return; +- } +- } +- +- void _addPackageSuggestions(String partial) { +- SourceFactory factory = request.sourceFactory; +- Map> packageMap = factory.packageMap; +- if (packageMap != null) { +- _addSuggestion('package:'); +- packageMap.forEach((String pkgName, List folders) { +- String prefix = 'package:$pkgName/'; +- _addSuggestion(prefix); +- for (Folder folder in folders) { +- if (folder.exists) { +- _addPackageFolderSuggestions(partial, prefix, folder); +- } +- } +- }); +- } +- } +- +- void _addSuggestion(String completion, +- {int relevance: DART_RELEVANCE_DEFAULT}) { +- suggestions.add(new CompletionSuggestion(CompletionSuggestionKind.IMPORT, +- relevance, completion, completion.length, 0, false, false)); +- } +- +- String _extractPartialUri(SimpleStringLiteral node) { +- if (request.offset < node.contentsOffset) { +- return null; +- } +- return node.literal.lexeme.substring( +- node.contentsOffset - node.offset, request.offset - node.offset); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart +deleted file mode 100644 +index baf199e6cd3..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart ++++ /dev/null +@@ -1,237 +0,0 @@ +-// 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. +- +-/** +- * A collection of utility methods used by completion contributors. +- */ +-import 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind, Location; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_ast_factory.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/dart/ast/token.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol +- show Element, ElementKind; +- +-/** +- * The name of the type `dynamic`; +- */ +-const DYNAMIC = 'dynamic'; +- +-/** +- * A marker used in place of `null` when a function has no return type. +- */ +-final TypeName NO_RETURN_TYPE = astFactory.typeName( +- astFactory.simpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), +- null); +- +-/** +- * Add default argument list text and ranges based on the given [requiredParams] +- * and [namedParams]. +- */ +-void addDefaultArgDetails( +- CompletionSuggestion suggestion, +- Element element, +- Iterable requiredParams, +- Iterable namedParams) { +- StringBuffer sb = new StringBuffer(); +- List ranges = []; +- +- int offset; +- +- for (ParameterElement param in requiredParams) { +- if (sb.isNotEmpty) { +- sb.write(', '); +- } +- offset = sb.length; +- String name = param.name; +- sb.write(name); +- ranges.addAll([offset, name.length]); +- } +- +- for (ParameterElement param in namedParams) { +- if (param.isRequired) { +- if (sb.isNotEmpty) { +- sb.write(', '); +- } +- String name = param.name; +- sb.write('$name: '); +- offset = sb.length; +- String defaultValue = _getDefaultValue(param); +- sb.write(defaultValue); +- ranges.addAll([offset, defaultValue.length]); +- } +- } +- +- suggestion.defaultArgumentListString = sb.isNotEmpty ? sb.toString() : null; +- suggestion.defaultArgumentListTextRanges = ranges.isNotEmpty ? ranges : null; +-} +- +-/** +- * Create a new protocol Element for inclusion in a completion suggestion. +- */ +-protocol.Element createLocalElement( +- Source source, protocol.ElementKind kind, SimpleIdentifier id, +- {String parameters, +- TypeAnnotation returnType, +- bool isAbstract: false, +- bool isDeprecated: false}) { +- String name; +- Location location; +- if (id != null) { +- name = id.name; +- // TODO(danrubel) use lineInfo to determine startLine and startColumn +- location = new Location(source.fullName, id.offset, id.length, 0, 0); +- } else { +- name = ''; +- location = new Location(source.fullName, -1, 0, 1, 0); +- } +- int flags = protocol.Element.makeFlags( +- isAbstract: isAbstract, +- isDeprecated: isDeprecated, +- isPrivate: Identifier.isPrivateName(name)); +- return new protocol.Element(kind, name, flags, +- location: location, +- parameters: parameters, +- returnType: nameForType(returnType)); +-} +- +-/** +- * Create a new suggestion for the given [fieldDecl]. Return the new suggestion +- * or `null` if it could not be created. +- */ +-CompletionSuggestion createLocalFieldSuggestion( +- Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) { +- bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl); +- TypeAnnotation type = fieldDecl.fields.type; +- return createLocalSuggestion( +- varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type, +- classDecl: fieldDecl.parent, +- element: createLocalElement( +- source, protocol.ElementKind.FIELD, varDecl.name, +- returnType: type, isDeprecated: deprecated)); +-} +- +-/** +- * Create a new suggestion based upon the given information. Return the new +- * suggestion or `null` if it could not be created. +- */ +-CompletionSuggestion createLocalSuggestion(SimpleIdentifier id, +- bool isDeprecated, int defaultRelevance, TypeAnnotation returnType, +- {ClassDeclaration classDecl, +- CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION, +- protocol.Element element}) { +- if (id == null) { +- return null; +- } +- String completion = id.name; +- if (completion == null || completion.length <= 0 || completion == '_') { +- return null; +- } +- CompletionSuggestion suggestion = new CompletionSuggestion( +- kind, +- isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance, +- completion, +- completion.length, +- 0, +- isDeprecated, +- false, +- returnType: nameForType(returnType), +- element: element); +- if (classDecl != null) { +- SimpleIdentifier classId = classDecl.name; +- if (classId != null) { +- String className = classId.name; +- if (className != null && className.length > 0) { +- suggestion.declaringType = className; +- } +- } +- } +- return suggestion; +-} +- +-String getDefaultStringParameterValue(ParameterElement param) { +- if (param != null) { +- DartType type = param.type; +- if (type is InterfaceType && isDartList(type)) { +- List typeArguments = type.typeArguments; +- if (typeArguments.length == 1) { +- DartType typeArg = typeArguments.first; +- String typeInfo = !typeArg.isDynamic ? '<${typeArg.name}>' : ''; +- return '$typeInfo[]'; +- } +- } +- if (type is FunctionType) { +- String params = type.parameters +- .map((p) => '${getTypeString(p.type)}${p.name}') +- .join(', '); +- //TODO(pq): consider adding a `TODO:` message in generated stub +- return '($params) {}'; +- } +- //TODO(pq): support map literals +- } +- return null; +-} +- +-String getTypeString(DartType type) => type.isDynamic ? '' : '${type.name} '; +- +-bool isDartList(DartType type) { +- ClassElement element = type.element; +- if (element != null) { +- return element.name == "List" && element.library.isDartCore; +- } +- return false; +-} +- +-/** +- * Return `true` if the @deprecated annotation is present on the given [node]. +- */ +-bool isDeprecated(AnnotatedNode node) { +- if (node != null) { +- NodeList metadata = node.metadata; +- if (metadata != null) { +- return metadata.any((Annotation a) { +- return a.name is SimpleIdentifier && a.name.name == 'deprecated'; +- }); +- } +- } +- return false; +-} +- +-/** +- * Return the name for the given [type]. +- */ +-String nameForType(TypeAnnotation type) { +- if (type == NO_RETURN_TYPE) { +- return null; +- } +- if (type == null) { +- return DYNAMIC; +- } +- if (type is TypeName) { +- Identifier id = type.name; +- if (id == null) { +- return DYNAMIC; +- } +- String name = id.name; +- if (name == null || name.length <= 0) { +- return DYNAMIC; +- } +- TypeArgumentList typeArgs = type.typeArguments; +- if (typeArgs != null) { +- //TODO (danrubel) include type arguments +- } +- return name; +- } else if (type is GenericFunctionType) { +- // TODO(brianwilkerson) Implement this. +- } +- return DYNAMIC; +-} +- +-//TODO(pq): fix to use getDefaultStringParameterValue() +-String _getDefaultValue(ParameterElement param) => 'null'; +diff --git a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart +deleted file mode 100644 +index 92a8389e4c3..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart ++++ /dev/null +@@ -1,99 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/protocol_server.dart' +- show CompletionSuggestion, CompletionSuggestionKind; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart' +- show DartCompletionRequestImpl; +-import 'package:analysis_server/src/services/correction/name_suggestion.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer_plugin/src/utilities/completion/optype.dart'; +- +-CompletionSuggestion _createNameSuggestion(String name) { +- if (name == null || name.isEmpty) { +- return null; +- } +- return new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER, +- DART_RELEVANCE_DEFAULT, name, name.length, 0, false, false); +-} +- +-String _getStringName(Identifier id) { +- if (id == null) { +- return null; +- } +- if (id is SimpleIdentifier) { +- return id.name; +- } else if (id is PrefixedIdentifier) { +- return id.identifier.name; +- } +- return id.name; +-} +- +-/** +- * A contributor for calculating suggestions for variable names. +- */ +-class VariableNameContributor extends DartCompletionContributor { +- @override +- Future> computeSuggestions( +- DartCompletionRequest request) async { +- OpType optype = (request as DartCompletionRequestImpl).opType; +- +- // Collect suggestions from the specific child [AstNode] that contains +- // the completion offset and all of its parents recursively. +- if (optype.includeVarNameSuggestions) { +- // Resolution not needed for this completion +- +- AstNode node = request.target.containingNode; +- String strName = null; +- if (node is ExpressionStatement) { +- if (node.expression is Identifier) { +- strName = _getStringName(node.expression as Identifier); +- } +- } else if (node is VariableDeclarationList) { +- TypeAnnotation typeAnnotation = node.type; +- if (typeAnnotation is TypeName) { +- strName = _getStringName(typeAnnotation.name); +- } +- } else if (node is TopLevelVariableDeclaration) { +- // The parser parses 'Foo ' and 'Foo ;' differently, resulting in the +- // following. +- // 'Foo ': handled above +- // 'Foo ;': TopLevelVariableDeclaration with type null, and a first +- // variable of 'Foo' +- VariableDeclarationList varDeclarationList = node.variables; +- TypeAnnotation typeAnnotation = varDeclarationList.type; +- if (typeAnnotation != null) { +- if (typeAnnotation is TypeName) { +- strName = _getStringName(typeAnnotation.name); +- } +- } else { +- NodeList varDeclarations = +- varDeclarationList.variables; +- if (varDeclarations.length == 1) { +- VariableDeclaration varDeclaration = varDeclarations.first; +- strName = _getStringName(varDeclaration.name); +- } +- } +- } +- if (strName == null) { +- return EMPTY_LIST; +- } +- +- List variableNameSuggestions = getCamelWordCombinations(strName); +- variableNameSuggestions.remove(strName); +- List suggestions = []; +- for (String varName in variableNameSuggestions) { +- CompletionSuggestion suggestion = _createNameSuggestion(varName); +- if (suggestion != null) { +- suggestions.add(suggestion); +- } +- } +- return suggestions; +- } +- return EMPTY_LIST; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart +deleted file mode 100644 +index 704ffdb26a4..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart ++++ /dev/null +@@ -1,567 +0,0 @@ +-// 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analyzer/dart/analysis/session.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/resolver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * An enumeration of possible postfix completion kinds. +- */ +-class DartPostfixCompletion { +- static const NO_TEMPLATE = +- const PostfixCompletionKind('', 'no change', null, null); +- static const ALL_TEMPLATES = const [ +- const PostfixCompletionKind("assert", "expr.assert -> assert(expr);", +- isAssertContext, expandAssert), +- const PostfixCompletionKind( +- "fori", +- "limit.fori -> for(var i = 0; i < limit; i++) {}", +- isIntContext, +- expandFori), +- const PostfixCompletionKind( +- "for", +- "values.for -> for(var value in values) {}", +- isIterableContext, +- expandFor), +- const PostfixCompletionKind( +- "iter", +- "values.iter -> for(var value in values) {}", +- isIterableContext, +- expandFor), +- const PostfixCompletionKind( +- "not", "bool.not -> !bool", isBoolContext, expandNegate), +- const PostfixCompletionKind( +- "!", "bool! -> !bool", isBoolContext, expandNegate), +- const PostfixCompletionKind( +- "else", "bool.else -> if (!bool) {}", isBoolContext, expandElse), +- const PostfixCompletionKind( +- "if", "bool.if -> if (bool) {}", isBoolContext, expandIf), +- const PostfixCompletionKind("nn", "expr.nn -> if (expr != null) {}", +- isObjectContext, expandNotNull), +- const PostfixCompletionKind("notnull", +- "expr.notnull -> if (expr != null) {}", isObjectContext, expandNotNull), +- const PostfixCompletionKind("null", "expr.null -> if (expr == null) {}", +- isObjectContext, expandNull), +- const PostfixCompletionKind( +- "par", "expr.par -> (expr)", isObjectContext, expandParen), +- const PostfixCompletionKind( +- "return", "expr.return -> return expr", isObjectContext, expandReturn), +- const PostfixCompletionKind("switch", "expr.switch -> switch (expr) {}", +- isSwitchContext, expandSwitch), +- const PostfixCompletionKind("try", "stmt.try -> try {stmt} catch (e,s) {}", +- isStatementContext, expandTry), +- const PostfixCompletionKind( +- "tryon", +- "stmt.try -> try {stmt} on Exception catch (e,s) {}", +- isStatementContext, +- expandTryon), +- const PostfixCompletionKind( +- "while", "expr.while -> while (expr) {}", isBoolContext, expandWhile), +- ]; +- +- static Future expandAssert( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findAssertExpression, (expr) { +- return "assert(${processor.utils.getNodeText(expr)});"; +- }, withBraces: false); +- } +- +- static Future expandElse( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findBoolExpression, +- (expr) => "if (${processor.makeNegatedBoolExpr(expr)})"); +- } +- +- static Future expandFor( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findIterableExpression, (expr) { +- String value = processor.newVariable("value"); +- return "for (var $value in ${processor.utils.getNodeText(expr)})"; +- }); +- } +- +- static Future expandFori( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findIntExpression, (expr) { +- String index = processor.newVariable("i"); +- return "for (int $index = 0; $index < ${processor.utils.getNodeText( +- expr)}; $index++)"; +- }); +- } +- +- static Future expandIf( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findBoolExpression, +- (expr) => "if (${processor.utils.getNodeText(expr)})"); +- } +- +- static Future expandNegate( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findBoolExpression, +- (expr) => processor.makeNegatedBoolExpr(expr), +- withBraces: false); +- } +- +- static Future expandNotNull( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findObjectExpression, (expr) { +- return expr is NullLiteral +- ? "if (false)" +- : "if (${processor.utils.getNodeText(expr)} != null)"; +- }); +- } +- +- static Future expandNull( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findObjectExpression, (expr) { +- return expr is NullLiteral +- ? "if (true)" +- : "if (${processor.utils.getNodeText(expr)} == null)"; +- }); +- } +- +- static Future expandParen( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findObjectExpression, +- (expr) => "(${processor.utils.getNodeText(expr)})", +- withBraces: false); +- } +- +- static Future expandReturn( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findObjectExpression, +- (expr) => "return ${processor.utils.getNodeText(expr)};", +- withBraces: false); +- } +- +- static Future expandSwitch( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findObjectExpression, +- (expr) => "switch (${processor.utils.getNodeText(expr)})"); +- } +- +- static Future expandTry( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expandTry(kind, processor.findStatement, withOn: false); +- } +- +- static Future expandTryon( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expandTry(kind, processor.findStatement, withOn: true); +- } +- +- static Future expandWhile( +- PostfixCompletionProcessor processor, PostfixCompletionKind kind) async { +- return processor.expand(kind, processor.findBoolExpression, +- (expr) => "while (${processor.utils.getNodeText(expr)})"); +- } +- +- static PostfixCompletionKind forKey(String key) => +- ALL_TEMPLATES.firstWhere((kind) => kind.key == key, orElse: () => null); +- +- static bool isAssertContext(PostfixCompletionProcessor processor) { +- return processor.findAssertExpression() != null; +- } +- +- static bool isBoolContext(PostfixCompletionProcessor processor) { +- return processor.findBoolExpression() != null; +- } +- +- static bool isIntContext(PostfixCompletionProcessor processor) { +- return processor.findIntExpression() != null; +- } +- +- static bool isIterableContext(PostfixCompletionProcessor processor) { +- return processor.findIterableExpression() != null; +- } +- +- static bool isObjectContext(PostfixCompletionProcessor processor) { +- return processor.findObjectExpression() != null; +- } +- +- static bool isStatementContext(PostfixCompletionProcessor processor) { +- return processor.findStatement() != null; +- } +- +- static bool isSwitchContext(PostfixCompletionProcessor processor) { +- return processor.findObjectExpression() != null; +- } +-} +- +-/** +- * A description of a postfix completion. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class PostfixCompletion { +- /** +- * A description of the assist being proposed. +- */ +- final PostfixCompletionKind kind; +- +- /** +- * The change to be made in order to apply the assist. +- */ +- final SourceChange change; +- +- /** +- * Initialize a newly created completion to have the given [kind] and [change]. +- */ +- PostfixCompletion(this.kind, this.change); +-} +- +-/** +- * The context for computing a postfix completion. +- */ +-class PostfixCompletionContext { +- final String file; +- final LineInfo lineInfo; +- final int selectionOffset; +- final String key; +- final AnalysisDriver driver; +- final CompilationUnit unit; +- final CompilationUnitElement unitElement; +- final List errors; +- +- PostfixCompletionContext(this.file, this.lineInfo, this.selectionOffset, +- this.key, this.driver, this.unit, this.unitElement, this.errors) { +- if (unitElement.context == null) { +- throw new Error(); // not reached +- } +- } +-} +- +-/** +- * A description of a template for postfix completion. Instances are intended to +- * hold the functions required to determine applicability and expand the +- * template, in addition to its name and simple example. The example is shown +- * (in IntelliJ) in a code-completion menu, so must be quite short. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class PostfixCompletionKind { +- final String name, example; +- final Function selector; +- final Function computer; +- +- const PostfixCompletionKind( +- this.name, this.example, this.selector, this.computer); +- +- String get key => name == '!' ? name : '.$name'; +- +- String get message => 'Expand $key'; +- +- @override +- String toString() => name; +-} +- +-/** +- * The computer for Dart postfix completions. +- */ +-class PostfixCompletionProcessor { +- static final NO_COMPLETION = new PostfixCompletion( +- DartPostfixCompletion.NO_TEMPLATE, new SourceChange("", edits: [])); +- +- final PostfixCompletionContext completionContext; +- final CorrectionUtils utils; +- AstNode node; +- PostfixCompletion completion; +- SourceChange change = new SourceChange('postfix-completion'); +- final Map linkedPositionGroups = +- {}; +- Position exitPosition = null; +- TypeProvider _typeProvider; +- +- PostfixCompletionProcessor(this.completionContext) +- : utils = new CorrectionUtils(completionContext.unit); +- +- AnalysisDriver get driver => completionContext.driver; +- +- String get eol => utils.endOfLine; +- +- String get file => completionContext.file; +- +- String get key => completionContext.key; +- +- LineInfo get lineInfo => completionContext.lineInfo; +- +- int get requestLine => lineInfo.getLocation(selectionOffset).lineNumber; +- +- int get selectionOffset => completionContext.selectionOffset; +- +- /** +- * Return the analysis session to be used to create the change builder. +- */ +- AnalysisSession get session => driver.currentSession; +- +- Source get source => completionContext.unitElement.source; +- +- TypeProvider get typeProvider { +- return _typeProvider ??= unitElement.context.typeProvider; +- } +- +- CompilationUnit get unit => completionContext.unit; +- +- CompilationUnitElement get unitElement => completionContext.unitElement; +- +- Future compute() async { +- node = _selectedNode(); +- if (node == null) { +- return NO_COMPLETION; +- } +- PostfixCompletionKind completer = DartPostfixCompletion.forKey(key); +- return completer?.computer(this, completer) ?? NO_COMPLETION; +- } +- +- Future expand( +- PostfixCompletionKind kind, Function contexter, Function sourcer, +- {bool withBraces: true}) async { +- AstNode expr = contexter(); +- if (expr == null) { +- return null; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(expr), (DartEditBuilder builder) { +- String newSrc = sourcer(expr); +- if (newSrc == null) { +- return null; +- } +- builder.write(newSrc); +- if (withBraces) { +- builder.write(" {"); +- builder.write(eol); +- String indent = utils.getNodePrefix(expr); +- builder.write(indent); +- builder.write(utils.getIndent(1)); +- builder.selectHere(); +- builder.write(eol); +- builder.write(indent); +- builder.write("}"); +- } else { +- builder.selectHere(); +- } +- }); +- }); +- _setCompletionFromBuilder(changeBuilder, kind); +- return completion; +- } +- +- Future expandTry( +- PostfixCompletionKind kind, Function contexter, +- {bool withOn: false}) async { +- AstNode stmt = contexter(); +- if (stmt == null) { +- return null; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // Embed the full line(s) of the statement in the try block. +- var startLine = lineInfo.getLocation(stmt.offset).lineNumber - 1; +- var endLine = lineInfo.getLocation(stmt.end).lineNumber - 1; +- if (stmt is ExpressionStatement && !stmt.semicolon.isSynthetic) { +- endLine += 1; +- } +- var startOffset = lineInfo.getOffsetOfLine(startLine); +- var endOffset = lineInfo.getOffsetOfLine(endLine); +- var src = utils.getText(startOffset, endOffset - startOffset); +- String indent = utils.getLinePrefix(stmt.offset); +- builder.addReplacement(range.startOffsetEndOffset(startOffset, endOffset), +- (DartEditBuilder builder) { +- builder.write(indent); +- builder.write('try {'); +- builder.write(eol); +- builder.write(src.replaceAll(new RegExp("^$indent", multiLine: true), +- "$indent${utils.getIndent(1)}")); +- builder.selectHere(); +- builder.write(indent); +- builder.write('}'); +- if (withOn) { +- builder.write(' on '); +- builder.addSimpleLinkedEdit('NAME', nameOfExceptionThrownBy(stmt)); +- } +- builder.write(' catch (e, s) {'); +- builder.write(eol); +- builder.write(indent); +- builder.write(utils.getIndent(1)); +- builder.write('print(s);'); +- builder.write(eol); +- builder.write(indent); +- builder.write("}"); +- builder.write(eol); +- }); +- }); +- _setCompletionFromBuilder(changeBuilder, kind); +- return completion; +- } +- +- Expression findAssertExpression() { +- if (node is Expression) { +- Expression boolExpr = _findOuterExpression(node, typeProvider.boolType); +- if (boolExpr == null) { +- return null; +- } +- if (boolExpr.parent is ExpressionFunctionBody && +- boolExpr.parent.parent is FunctionExpression) { +- FunctionExpression fnExpr = boolExpr.parent.parent; +- var type = fnExpr.bestType; +- if (type is! FunctionType) { +- return boolExpr; +- } +- FunctionType fnType = type; +- if (fnType.returnType == typeProvider.boolType) { +- return fnExpr; +- } +- } +- if (boolExpr.bestType == typeProvider.boolType) { +- return boolExpr; +- } +- } +- return null; +- } +- +- Expression findBoolExpression() => +- _findOuterExpression(node, typeProvider.boolType); +- +- Expression findIntExpression() => +- _findOuterExpression(node, typeProvider.intType); +- +- Expression findIterableExpression() => +- _findOuterExpression(node, typeProvider.iterableType); +- +- Expression findObjectExpression() => +- _findOuterExpression(node, typeProvider.objectType); +- +- AstNode findStatement() { +- var astNode = node; +- while (astNode != null) { +- if (astNode is Statement && astNode is! Block) { +- // Disallow control-flow statements. +- if (astNode is DoStatement || +- astNode is IfStatement || +- astNode is ForEachStatement || +- astNode is ForStatement || +- astNode is SwitchStatement || +- astNode is TryStatement || +- astNode is WhileStatement) { +- return null; +- } +- return astNode; +- } +- astNode = astNode.parent; +- } +- return null; +- } +- +- Future isApplicable() async { +- node = _selectedNode(); +- if (node == null) { +- return false; +- } +- PostfixCompletionKind completer = DartPostfixCompletion.forKey(key); +- return completer?.selector(this); +- } +- +- String makeNegatedBoolExpr(Expression expr) { +- String originalSrc = utils.getNodeText(expr); +- String newSrc = utils.invertCondition(expr); +- if (newSrc != originalSrc) { +- return newSrc; +- } else { +- return "!${utils.getNodeText(expr)}"; +- } +- } +- +- String nameOfExceptionThrownBy(AstNode astNode) { +- if (astNode is ExpressionStatement) { +- astNode = (astNode as ExpressionStatement).expression; +- } +- if (astNode is ThrowExpression) { +- ThrowExpression expr = astNode; +- var type = expr.expression.bestType; +- return type.displayName; +- } +- return 'Exception'; +- } +- +- String newVariable(String base) { +- String name = base; +- int i = 1; +- Set vars = +- utils.findPossibleLocalVariableConflicts(selectionOffset); +- while (vars.contains(name)) { +- name = "$base${i++}"; +- } +- return name; +- } +- +- Expression _findOuterExpression(AstNode start, InterfaceType builtInType) { +- AstNode parent; +- if (start is Expression) { +- parent = start; +- } else if (start is ArgumentList) { +- parent = start.parent; +- } +- if (parent == null) { +- return null; +- } +- var list = []; +- while (parent is Expression) { +- list.add(parent); +- parent = parent.parent; +- } +- Expression expr = list.firstWhere((expr) { +- DartType type = expr.bestType; +- if (type.isSubtypeOf(builtInType)) return true; +- Element element = type.element; +- if (element is TypeDefiningElement) { +- TypeDefiningElement typeDefElem = element; +- type = typeDefElem.type; +- if (type is ParameterizedType) { +- ParameterizedType pType = type; +- type = pType.instantiate(new List.filled( +- pType.typeParameters.length, typeProvider.dynamicType)); +- } +- } +- return type.isSubtypeOf(builtInType); +- }, orElse: () => null); +- if (expr is SimpleIdentifier && expr.parent is PropertyAccess) { +- expr = expr.parent; +- } +- if (expr?.parent is CascadeExpression) { +- expr = expr.parent; +- } +- return expr; +- } +- +- AstNode _selectedNode({int at: null}) => +- new NodeLocator(at == null ? selectionOffset : at).searchWithin(unit); +- +- void _setCompletionFromBuilder( +- DartChangeBuilder builder, PostfixCompletionKind kind, +- [List args]) { +- SourceChange change = builder.sourceChange; +- if (change.edits.isEmpty) { +- completion = null; +- return; +- } +- change.message = formatList(kind.message, args); +- completion = new PostfixCompletion(kind, change); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/completion/statement/design_notes.md b/pkg/analysis_server/lib/src/services/completion/statement/design_notes.md +deleted file mode 100644 +index 238c83c59f2..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/statement/design_notes.md ++++ /dev/null +@@ -1,144 +0,0 @@ +-# Statement Completion +- +-### Mission Statement +- +-The purpose of this feature is to add required syntax to the current +-statement. The goal is to make the statement syntactically complete. +-That is not possible to do in all cases. A best-effort attempt is made +-when it cannot be done. +- +-### Current Statement +- +-The term _statement completion_ comes from IntelliJ. It is also called +-_smart enter_ there, which is a more general term. See the IntelliJ +-[documentation.](https://www.jetbrains.com/help/idea/2017.1/auto-completing-code.html#statements_completion) +- +-Rather than restricting the functionality to statements, in the sense of the grammar construct +-called _statement_, it is best to think of code constructs. Statement completion +-can be used to add syntax to declarations, statements, and some expressions. +-Generally, the syntax additions are punctuation marks, such as semicolons, +-parentheses, and braces. +- +-The _current statement_ then, is the code construct being written in the +-editor, as identified by the position of the editing cursor. The _cursor_ is the +-primary editing cursor of the active editor in IntelliJ. We ignore multiple +-secondary cursors. +- +-If the _current statement_ is already syntactically complete then the feature +-just adds a newline. This will be the case when the cursor follows the closing +-brace of the body of a for-statement or while-statement, for example. The model +-used is that the user is creating code going forward, and when the +-_smart enter_ keystroke is typed the user expects to see forward progress. +-The cursor should end up at the most likely place to continue editing, regardless +-of what errors may exist in previous code. It is as if the user said "I'm done +-with this line. Finish it up and move me to the next line." +- +-## Code Constructs +- +-There are a number of cases where a matching right parenthesis could be added +-if it is missing. This feature has not been considered a priority since the +-editor by default adds parenthesis in pairs. +- +-Generics are not currently handled. +- +-#### Declarations +- +-There is limited work to be done. +- +-- [x] Functions, methods, and classes can have a pair of braces added if they do not already have a body defined. +-- [x] Functions and methods can have a closing parenthesis added to the parameter list. +-- [x] Variables can have a semicolon added to terminate them. +- +-#### Expressions +- +-Also limited. +- +-- [x] Unterminated strings can have appropriate string +-terminators added. +-- [x] Lists that have not been properly terminated can +-have closing brackets added (potentially with trailing commas). +-- [x] Maps are not currently handled. The parser error recovery +-gets confused by braces of code blocks too easily. +- +-#### Statements +- +-With actual statements, there are many more possibilities. +-Statements that start with a keyword must have at least the +-keyword in the partial statement in order for completion to +-happen. +- +-###### Do Statement +- +-This is one of the few cases where an actual word may be included. +-If the `while` keyword is missing it will be added. +-As long as the `do` keyword is present the braces for the body +-will be added. If the `while` keyword is present or can be added +-then the parentheses for the condition will be added, too. Finally, +-the terminating semicolon will be added. +- +-###### For Statement +- +-The parser cannot distinguish a for-statement from a for-each unless +-either at least one semicolon or the `in` keyword is present in the +-control parts. If neither is present then completion cannot do any +-more than possibly add braces for the body. +- +-Given that the statement is actually a for-statement then the control +-parts will be adjusted to ensure there are two semicolons. If the braces +-for the body are missing then they will be added. +- +-###### For-each Statement +- +-Braces for the body can be added if missing. +- +-###### If Statement +- +-The if-else-etc construct could get arbitrarily complex, so +-for simplicity the `else` keyword is ignored. Starting with nothing +-but the `if` keyword, the parentheses for the condition will be added +-and the braces for the body will be added. +- +-###### Switch Statement +- +-Given the `switch` keyword, parentheses for the selector will be added +-if absent and the braces for the body will be added. Also, for an +-individual case or default clause the terminating colon will be added +-if needed. To be clear, only the colon for the clause containing +-the cursor will be added. +- +-###### Try Statement +- +-If the statement is nothing more than the `try` keyword then the braces +-for the body will be added. No clauses (on, catch, or finally) will be added. +- +-An on-clause will be completed by adding braces for its body, if absent. +- +-A catch-clause will be completed by adding parentheses for its +-parameter list and braces for the body. +- +-A finally-clause will be completed by adding braces for its body. +- +-###### While Statement +- +-This is structurally identical to the if-statement and the implementation +-for both is shared. +- +-###### Expression Statements +- +-These include method and function invocations. +-- [x] Add closing parenthesis, if the expression is an invocation. +-- [x] Add terminating semicolon. +- +-###### Control-flow Blocks +- +-After finishing a `return` or `throw` in a block that is the +-body of a control-flow statement (do, for, for-each, if, while) +-then the cursor will be moved outside the block, ready to begin +-the next statement following the control-flow statement. +-```dart +-if (isFinished()) { +-releaseResources(); +-return; // invoke 'smart enter' here +-} +-// continue typing here +-``` +diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart +deleted file mode 100644 +index 2277f99ff2b..00000000000 +--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart ++++ /dev/null +@@ -1,1237 +0,0 @@ +-// 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:math'; +- +-import 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/source_buffer.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/error/hint_codes.dart'; +-import 'package:analyzer/src/dart/error/syntactic_errors.dart'; +-import 'package:analyzer/src/error/codes.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * An enumeration of possible statement completion kinds. +- */ +-class DartStatementCompletion { +- static const NO_COMPLETION = +- const StatementCompletionKind('No_COMPLETION', 'No completion available'); +- static const SIMPLE_ENTER = const StatementCompletionKind( +- 'SIMPLE_ENTER', "Insert a newline at the end of the current line"); +- static const SIMPLE_SEMICOLON = const StatementCompletionKind( +- 'SIMPLE_SEMICOLON', "Add a semicolon and newline"); +- static const COMPLETE_CLASS_DECLARATION = const StatementCompletionKind( +- 'COMPLETE_CLASS_DECLARATION', "Complete class declaration"); +- static const COMPLETE_CONTROL_FLOW_BLOCK = const StatementCompletionKind( +- 'COMPLETE_CONTROL_FLOW_BLOCK', "Complete control flow block"); +- static const COMPLETE_DO_STMT = const StatementCompletionKind( +- 'COMPLETE_DO_STMT', "Complete do-statement"); +- static const COMPLETE_IF_STMT = const StatementCompletionKind( +- 'COMPLETE_IF_STMT', "Complete if-statement"); +- static const COMPLETE_FOR_STMT = const StatementCompletionKind( +- 'COMPLETE_FOR_STMT', "Complete for-statement"); +- static const COMPLETE_FOR_EACH_STMT = const StatementCompletionKind( +- 'COMPLETE_FOR_EACH_STMT', "Complete for-each-statement"); +- static const COMPLETE_FUNCTION_DECLARATION = const StatementCompletionKind( +- 'COMPLETE_FUNCTION_DECLARATION', "Complete function declaration"); +- static const COMPLETE_SWITCH_STMT = const StatementCompletionKind( +- 'COMPLETE_SWITCH_STMT', "Complete switch-statement"); +- static const COMPLETE_TRY_STMT = const StatementCompletionKind( +- 'COMPLETE_TRY_STMT', "Complete try-statement"); +- static const COMPLETE_VARIABLE_DECLARATION = const StatementCompletionKind( +- 'COMPLETE_VARIABLE_DECLARATION', "Complete variable declaration"); +- static const COMPLETE_WHILE_STMT = const StatementCompletionKind( +- 'COMPLETE_WHILE_STMT', "Complete while-statement"); +-} +- +-/** +- * A description of a statement completion. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class StatementCompletion { +- /** +- * A description of the assist being proposed. +- */ +- final StatementCompletionKind kind; +- +- /** +- * The change to be made in order to apply the assist. +- */ +- final SourceChange change; +- +- /** +- * Initialize a newly created completion to have the given [kind] and [change]. +- */ +- StatementCompletion(this.kind, this.change); +-} +- +-/** +- * The context for computing a statement completion. +- */ +-class StatementCompletionContext { +- final String file; +- final LineInfo lineInfo; +- final int selectionOffset; +- final CompilationUnit unit; +- final CompilationUnitElement unitElement; +- final List errors; +- +- StatementCompletionContext(this.file, this.lineInfo, this.selectionOffset, +- this.unit, this.unitElement, this.errors) { +- if (unitElement.context == null) { +- throw new Error(); // not reached; see getStatementCompletion() +- } +- } +-} +- +-/** +- * A description of a class of statement completions. Instances are intended to +- * hold the information that is common across a number of completions and to be +- * shared by those completions. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class StatementCompletionKind { +- /** +- * The name of this kind of statement completion, used for debugging. +- */ +- final String name; +- +- /** +- * A human-readable description of the changes that will be applied by this +- * kind of statement completion. +- */ +- final String message; +- +- /** +- * Initialize a newly created kind of statement completion to have the given +- * [name] and [message]. +- */ +- const StatementCompletionKind(this.name, this.message); +- +- @override +- String toString() => name; +-} +- +-/** +- * The computer for Dart statement completions. +- */ +-class StatementCompletionProcessor { +- static final NO_COMPLETION = new StatementCompletion( +- DartStatementCompletion.NO_COMPLETION, new SourceChange("", edits: [])); +- +- final StatementCompletionContext statementContext; +- final CorrectionUtils utils; +- AstNode node; +- StatementCompletion completion; +- SourceChange change = new SourceChange('statement-completion'); +- List errors = []; +- final Map linkedPositionGroups = +- {}; +- Position exitPosition = null; +- +- StatementCompletionProcessor(this.statementContext) +- : utils = new CorrectionUtils(statementContext.unit); +- +- String get eol => utils.endOfLine; +- +- String get file => statementContext.file; +- +- LineInfo get lineInfo => statementContext.lineInfo; +- +- int get requestLine => lineInfo.getLocation(selectionOffset).lineNumber; +- +- int get selectionOffset => statementContext.selectionOffset; +- +- Source get source => statementContext.unitElement.source; +- +- CompilationUnit get unit => statementContext.unit; +- +- CompilationUnitElement get unitElement => statementContext.unitElement; +- +- Future compute() async { +- node = _selectedNode(); +- if (node == null) { +- return NO_COMPLETION; +- } +- node = node +- .getAncestor((n) => n is Statement || _isNonStatementDeclaration(n)); +- if (node == null) { +- return _complete_simpleEnter() ? completion : NO_COMPLETION; +- } +- if (node is Block) { +- Block blockNode = node; +- if (blockNode.statements.isNotEmpty) { +- node = blockNode.statements.last; +- } +- } +- if (_isEmptyStatement(node)) { +- node = node.parent; +- } +- for (engine.AnalysisError error in statementContext.errors) { +- if (error.offset >= node.offset && +- error.offset <= node.offset + node.length) { +- if (error.errorCode is! HintCode) { +- errors.add(error); +- } +- } +- } +- +- _checkExpressions(); +- if (node is Statement) { +- if (errors.isEmpty) { +- if (_complete_ifStatement() || +- _complete_forStatement() || +- _complete_forEachStatement() || +- _complete_whileStatement() || +- _complete_controlFlowBlock()) { +- return completion; +- } +- } else { +- if (_complete_ifStatement() || +- _complete_doStatement() || +- _complete_forStatement() || +- _complete_forEachStatement() || +- _complete_functionDeclarationStatement() || +- _complete_switchStatement() || +- _complete_tryStatement() || +- _complete_whileStatement() || +- _complete_controlFlowBlock() || +- _complete_simpleSemicolon() || +- _complete_methodCall()) { +- return completion; +- } +- } +- } else if (node is Declaration) { +- if (errors.isNotEmpty) { +- if (_complete_classDeclaration() || +- _complete_functionDeclaration() || +- _complete_variableDeclaration()) { +- return completion; +- } +- } +- } +- if (_complete_simpleEnter()) { +- return completion; +- } +- return NO_COMPLETION; +- } +- +- void _addInsertEdit(int offset, String text) { +- SourceEdit edit = new SourceEdit(offset, 0, text); +- doSourceChange_addElementEdit(change, unitElement, edit); +- } +- +- void _addReplaceEdit(SourceRange range, String text) { +- SourceEdit edit = new SourceEdit(range.offset, range.length, text); +- doSourceChange_addElementEdit(change, unitElement, edit); +- } +- +- void _appendEmptyBraces(SourceBuilder sb, [bool needsExitMark = false]) { +- sb.append('{'); +- sb.append(eol); +- String indent = utils.getLinePrefix(selectionOffset); +- sb.append(indent); +- sb.append(utils.getIndent(1)); +- if (needsExitMark && sb.exitOffset == null) { +- sb.setExitOffset(); +- } +- sb.append(eol); +- sb.append(indent); +- sb.append('}'); +- } +- +- int _appendNewlinePlusIndent() { +- return _appendNewlinePlusIndentAt(selectionOffset); +- } +- +- int _appendNewlinePlusIndentAt(int offset) { +- // Append a newline plus proper indent and another newline. +- // Return the position before the second newline. +- String indent = utils.getLinePrefix(offset); +- int loc = utils.getLineNext(offset); +- _addInsertEdit(loc, indent + eol); +- return loc + indent.length; +- } +- +- String _baseNodeText(AstNode astNode) { +- String text = utils.getNodeText(astNode); +- if (text.endsWith(eol)) { +- text = text.substring(0, text.length - eol.length); +- } +- return text; +- } +- +- void _checkExpressions() { +- // Note: This may queue edits that have to be accounted for later. +- // See _lengthOfInsertions(). +- AstNode errorMatching(errorCode, {partialMatch = null}) { +- var error = _findError(errorCode, partialMatch: partialMatch); +- if (error == null) { +- return null; +- } +- AstNode expr = _selectedNode(); +- return (expr.getAncestor((n) => n is StringInterpolation) == null) +- ? expr +- : null; +- } +- +- var expr = errorMatching(ScannerErrorCode.UNTERMINATED_STRING_LITERAL); +- if (expr != null) { +- String source = utils.getNodeText(expr); +- String content = source; +- int char = content.codeUnitAt(0); +- if (char == 'r'.codeUnitAt(0)) { +- content = source.substring(1); +- char = content.codeUnitAt(0); +- } +- String delimiter; +- int loc; +- if (content.length >= 3 && +- char == content.codeUnitAt(1) && +- char == content.codeUnitAt(2)) { +- // multi-line string +- delimiter = content.substring(0, 3); +- int newlineLoc = source.indexOf(eol, selectionOffset - expr.offset); +- if (newlineLoc < 0) { +- newlineLoc = source.length; +- } +- loc = newlineLoc + expr.offset; +- } else { +- // add first char of src +- delimiter = content.substring(0, 1); +- loc = expr.offset + source.length; +- } +- _removeError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL); +- _addInsertEdit(loc, delimiter); +- } +- expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'") ?? +- errorMatching(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); +- if (expr != null) { +- expr = expr.getAncestor((n) => n is ListLiteral); +- if (expr != null) { +- ListLiteral lit = expr; +- if (lit.rightBracket.isSynthetic) { +- String src = utils.getNodeText(expr).trim(); +- int loc = expr.offset + src.length; +- if (src.contains(eol)) { +- String indent = utils.getNodePrefix(node); +- _addInsertEdit(loc, ',' + eol + indent + ']'); +- } else { +- _addInsertEdit(loc, ']'); +- } +- _removeError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); +- _removeError(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'"); +- var ms = +- _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); +- if (ms != null) { +- // Ensure the semicolon gets inserted in the correct location. +- ms.offset = loc - 1; +- } +- } +- } +- } +- // The following code is similar to the code for ']' but does not work well. +- // A closing brace is recognized as belong to the map even if it is intended +- // to close a block of code. +- /* +- expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "'}'"); +- if (expr != null) { +- expr = expr.getAncestor((n) => n is MapLiteral); +- if (expr != null) { +- MapLiteral lit = expr; +- String src = utils.getNodeText(expr).trim(); +- int loc = expr.offset + src.length; +- if (lit.entries.last.separator.isSynthetic) { +- _addInsertEdit(loc, ': '); +- } +- if (!src.endsWith('}')/*lit.rightBracket.isSynthetic*/) { +- _addInsertEdit(loc, '}'); +- } +- _removeError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "'}'"); +- var ms = +- _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); +- if (ms != null) { +- // Ensure the semicolon gets inserted in the correct location. +- ms.offset = loc - 1; +- } +- } +- } +- */ +- } +- +- bool _complete_classDeclaration() { +- if (node is! ClassDeclaration) { +- return false; +- } +- ClassDeclaration decl = node; +- if (decl.leftBracket.isSynthetic && errors.length == 1) { +- // The space before the left brace is assumed to exist, even if it does not. +- SourceBuilder sb = new SourceBuilder(file, decl.end - 1); +- sb.append(' '); +- _appendEmptyBraces(sb, true); +- _insertBuilder(sb); +- _setCompletion(DartStatementCompletion.COMPLETE_CLASS_DECLARATION); +- return true; +- } +- return false; +- } +- +- bool _complete_controlFlowBlock() { +- Expression expr = (node is ExpressionStatement) +- ? (node as ExpressionStatement).expression +- : (node is ReturnStatement +- ? (node as ReturnStatement).expression +- : null); +- if (!(node is ReturnStatement || expr is ThrowExpression)) { +- return false; +- } +- if (node.parent is! Block) { +- return false; +- } +- AstNode outer = node.parent.parent; +- if (!(outer is DoStatement || +- outer is ForStatement || +- outer is ForEachStatement || +- outer is IfStatement || +- outer is WhileStatement)) { +- return false; +- } +- int previousInsertions = _lengthOfInsertions(); +- int delta = 0; +- if (errors.isNotEmpty) { +- var error = +- _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); +- if (error != null) { +- int insertOffset; +- // Fasta scanner reports unterminated string literal errors +- // and generates a synthetic string token with non-zero length. +- // Because of this, check for length == 0 rather than isSynthetic. +- if (expr == null || expr.length == 0) { +- if (node is ReturnStatement) { +- insertOffset = (node as ReturnStatement).returnKeyword.end; +- } else if (node is ExpressionStatement) { +- insertOffset = +- ((node as ExpressionStatement).expression as ThrowExpression) +- .throwKeyword +- .end; +- } else { +- insertOffset = node.end; // Not reached. +- } +- } else { +- insertOffset = expr.end; +- } +- //TODO(messick) Uncomment the following line when error location is fixed. +- //insertOffset = error.offset + error.length; +- _addInsertEdit(insertOffset, ';'); +- delta = 1; +- } +- } +- int offset = _appendNewlinePlusIndentAt(node.parent.end); +- exitPosition = new Position(file, offset + delta + previousInsertions); +- _setCompletion(DartStatementCompletion.COMPLETE_CONTROL_FLOW_BLOCK); +- return true; +- } +- +- bool _complete_doStatement() { +- if (node is! DoStatement) { +- return false; +- } +- DoStatement statement = node; +- SourceBuilder sb = _sourceBuilderAfterKeyword(statement.doKeyword); +- bool hasWhileKeyword = statement.whileKeyword.lexeme == "while"; +- int exitDelta = 0; +- if (!_statementHasValidBody(statement.doKeyword, statement.body)) { +- String text = utils.getNodeText(statement.body); +- int delta = 0; +- if (text.startsWith(';')) { +- delta = 1; +- _addReplaceEdit(range.startLength(statement.body, delta), ''); +- if (hasWhileKeyword) { +- text = utils.getNodeText(statement); +- if (text.indexOf(new RegExp(r'do\s*;\s*while')) == 0) { +- int end = text.indexOf('while'); +- int start = text.indexOf(';') + 1; +- delta += end - start - 1; +- _addReplaceEdit( +- new SourceRange(start + statement.offset, end - start), ' '); +- } +- } +- sb = new SourceBuilder(file, sb.offset + delta); +- sb.append(' '); +- } +- _appendEmptyBraces(sb, +- !(hasWhileKeyword && _isSyntheticExpression(statement.condition))); +- if (delta != 0) { +- exitDelta = sb.length - delta; +- } +- } else if (_isEmptyBlock(statement.body)) { +- sb = new SourceBuilder(sb.file, statement.body.end); +- } +- SourceBuilder sb2; +- if (hasWhileKeyword) { +- var stmt = new _KeywordConditionBlockStructure( +- statement.whileKeyword, +- statement.leftParenthesis, +- statement.condition, +- statement.rightParenthesis, +- null); +- sb2 = _complete_keywordCondition(stmt); +- if (sb2 == null) { +- return false; +- } +- if (sb2.length == 0) { +- // true if condition is '()' +- if (exitPosition != null) { +- if (statement.semicolon.isSynthetic) { +- _insertBuilder(sb); +- sb = new SourceBuilder(file, exitPosition.offset + 1); +- sb.append(';'); +- } +- } +- } else { +- if (sb.exitOffset == null && sb2?.exitOffset != null) { +- _insertBuilder(sb); +- sb = sb2; +- sb.append(';'); +- } else { +- sb.append(sb2.toString()); +- } +- } +- } else { +- sb.append(" while ("); +- sb.setExitOffset(); +- sb.append(");"); +- } +- _insertBuilder(sb); +- if (exitDelta != 0) { +- exitPosition = +- new Position(exitPosition.file, exitPosition.offset + exitDelta); +- } +- _setCompletion(DartStatementCompletion.COMPLETE_DO_STMT); +- return true; +- } +- +- bool _complete_forEachStatement() { +- if (node is! ForEachStatement) { +- return false; +- } +- ForEachStatement forNode = node; +- if (forNode.inKeyword.isSynthetic) { +- return false; // Can't happen -- would be parsed as a for-statement. +- } +- SourceBuilder sb = +- new SourceBuilder(file, forNode.rightParenthesis.offset + 1); +- AstNode name = forNode.identifier; +- name ??= forNode.loopVariable; +- String src = utils.getNodeText(forNode); +- if (name == null) { +- exitPosition = new Position(file, forNode.leftParenthesis.offset + 1); +- src = src.substring(forNode.leftParenthesis.offset - forNode.offset); +- if (src.startsWith(new RegExp(r'\(\s*in\s*\)'))) { +- _addReplaceEdit( +- range.startOffsetEndOffset(forNode.leftParenthesis.offset + 1, +- forNode.rightParenthesis.offset), +- ' in '); +- } else if (src.startsWith(new RegExp(r'\(\s*in'))) { +- _addReplaceEdit( +- range.startOffsetEndOffset( +- forNode.leftParenthesis.offset + 1, forNode.inKeyword.offset), +- ' '); +- } +- } else if (_isSyntheticExpression(forNode.iterable)) { +- exitPosition = new Position(file, forNode.rightParenthesis.offset + 1); +- src = src.substring(forNode.inKeyword.offset - forNode.offset); +- if (src.startsWith(new RegExp(r'in\s*\)'))) { +- _addReplaceEdit( +- range.startOffsetEndOffset( +- forNode.inKeyword.offset + forNode.inKeyword.length, +- forNode.rightParenthesis.offset), +- ' '); +- } +- } +- if (!_statementHasValidBody(forNode.forKeyword, forNode.body)) { +- sb.append(' '); +- _appendEmptyBraces(sb, exitPosition == null); +- } +- _insertBuilder(sb); +- _setCompletion(DartStatementCompletion.COMPLETE_FOR_EACH_STMT); +- return true; +- } +- +- bool _complete_forStatement() { +- if (node is! ForStatement) { +- return false; +- } +- ForStatement forNode = node; +- SourceBuilder sb; +- int replacementLength = 0; +- if (forNode.leftParenthesis.isSynthetic) { +- if (!forNode.rightParenthesis.isSynthetic) { +- return false; +- } +- // keywordOnly (unit test name suffix that exercises this branch) +- sb = _sourceBuilderAfterKeyword(forNode.forKeyword); +- sb.append('('); +- sb.setExitOffset(); +- sb.append(')'); +- } else { +- if (!forNode.rightSeparator.isSynthetic) { +- // Fully-defined init, cond, updaters so nothing more needed here. +- // emptyParts, noError +- sb = new SourceBuilder(file, forNode.rightParenthesis.offset + 1); +- } else if (!forNode.leftSeparator.isSynthetic) { +- if (_isSyntheticExpression(forNode.condition)) { +- String text = utils +- .getNodeText(forNode) +- .substring(forNode.leftSeparator.offset - forNode.offset); +- Match match = +- new RegExp(r';\s*(/\*.*\*/\s*)?\)[ \t]*').matchAsPrefix(text); +- if (match != null) { +- // emptyCondition, emptyInitializersEmptyCondition +- replacementLength = match.end - match.start; +- sb = new SourceBuilder(file, forNode.leftSeparator.offset); +- sb.append('; ${match.group(1) == null ? '' : match.group(1)}; )'); +- String suffix = text.substring(match.end); +- if (suffix.trim().isNotEmpty) { +- sb.append(' '); +- sb.append(suffix.trim()); +- replacementLength += suffix.length; +- if (suffix.endsWith(eol)) { +- // emptyCondition +- replacementLength -= eol.length; +- } +- } +- exitPosition = _newPosition(forNode.leftSeparator.offset + 2); +- } else { +- return false; // Line comment in condition +- } +- } else { +- // emptyUpdaters +- sb = new SourceBuilder(file, forNode.rightParenthesis.offset); +- replacementLength = 1; +- sb.append('; )'); +- exitPosition = _newPosition(forNode.rightSeparator.offset + 2); +- } +- } else if (_isSyntheticExpression(forNode.initialization)) { +- // emptyInitializers +- exitPosition = _newPosition(forNode.rightParenthesis.offset); +- sb = new SourceBuilder(file, forNode.rightParenthesis.offset); +- } else { +- int start = forNode.condition.offset + forNode.condition.length; +- String text = +- utils.getNodeText(forNode).substring(start - forNode.offset); +- if (text.startsWith(new RegExp(r'\s*\)'))) { +- // missingLeftSeparator +- int end = text.indexOf(')'); +- sb = new SourceBuilder(file, start); +- _addReplaceEdit(new SourceRange(start, end), '; ; '); +- exitPosition = new Position(file, start - (end - '; '.length)); +- } else { +- // Not possible; any comment following init is attached to init. +- exitPosition = _newPosition(forNode.rightParenthesis.offset); +- sb = new SourceBuilder(file, forNode.rightParenthesis.offset); +- } +- } +- } +- if (!_statementHasValidBody(forNode.forKeyword, forNode.body)) { +- // keywordOnly, noError +- sb.append(' '); +- _appendEmptyBraces(sb, true /*exitPosition == null*/); +- } else if (forNode.body is Block) { +- Block body = forNode.body; +- if (body.rightBracket.end <= selectionOffset) { +- // emptyInitializersAfterBody +- errors = []; // Ignore errors; they are for previous statement. +- return false; // If cursor is after closing brace just add newline. +- } +- } +- _insertBuilder(sb, replacementLength); +- _setCompletion(DartStatementCompletion.COMPLETE_FOR_STMT); +- return true; +- } +- +- bool _complete_functionDeclaration() { +- if (node is! MethodDeclaration && node is! FunctionDeclaration) { +- return false; +- } +- bool needsParen = false; +- int computeExitPos(FormalParameterList parameters) { +- if (needsParen = parameters.rightParenthesis.isSynthetic) { +- var error = _findError(ParserErrorCode.MISSING_CLOSING_PARENTHESIS); +- if (error != null) { +- return error.offset - 1; +- } +- } +- return node.end - 1; +- } +- +- int paramListEnd; +- if (node is FunctionDeclaration) { +- FunctionDeclaration func = node; +- paramListEnd = computeExitPos(func.functionExpression.parameters); +- } else { +- MethodDeclaration meth = node; +- paramListEnd = computeExitPos(meth.parameters); +- } +- SourceBuilder sb = new SourceBuilder(file, paramListEnd); +- if (needsParen) { +- sb.append(')'); +- } +- sb.append(' '); +- _appendEmptyBraces(sb, true); +- _insertBuilder(sb); +- _setCompletion(DartStatementCompletion.COMPLETE_FUNCTION_DECLARATION); +- return true; +- } +- +- bool _complete_functionDeclarationStatement() { +- if (node is! FunctionDeclarationStatement) { +- return false; +- } +- var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); +- if (error != null) { +- FunctionDeclarationStatement stmt = node; +- String src = utils.getNodeText(stmt); +- int insertOffset = stmt.functionDeclaration.end - 1; +- if (stmt.functionDeclaration.functionExpression.body +- is ExpressionFunctionBody) { +- ExpressionFunctionBody fnb = +- stmt.functionDeclaration.functionExpression.body; +- int fnbOffset = fnb.functionDefinition.offset; +- String fnSrc = src.substring(fnbOffset - stmt.offset); +- if (!fnSrc.startsWith('=>')) { +- return false; +- } +- int delta = 0; +- if (fnb.expression.isSynthetic) { +- if (!fnSrc.startsWith('=> ')) { +- _addInsertEdit(insertOffset, ' '); +- delta = 1; +- } +- _addInsertEdit(insertOffset, ';'); +- _appendNewlinePlusIndentAt(insertOffset); +- } else { +- delta = 1; +- _addInsertEdit(insertOffset, ';'); +- insertOffset = _appendNewlinePlusIndent(); +- } +- _setCompletionAt( +- DartStatementCompletion.SIMPLE_SEMICOLON, insertOffset + delta); +- return true; +- } +- } +- return false; +- } +- +- bool _complete_ifOrWhileStatement( +- _KeywordConditionBlockStructure statement, StatementCompletionKind kind) { +- if (_statementHasValidBody(statement.keyword, statement.block)) { +- return false; +- } +- SourceBuilder sb = _complete_keywordCondition(statement); +- if (sb == null) { +- return false; +- } +- int overshoot = _lengthOfDeletions(); +- sb.append(' '); +- _appendEmptyBraces(sb, exitPosition == null); +- _insertBuilder(sb); +- if (overshoot != 0) { +- exitPosition = _newPosition(exitPosition.offset - overshoot); +- } +- _setCompletion(kind); +- return true; +- } +- +- bool _complete_ifStatement() { +- if (node is! IfStatement) { +- return false; +- } +- IfStatement ifNode = node; +- if (ifNode.elseKeyword != null) { +- if (selectionOffset >= ifNode.elseKeyword.end && +- ifNode.elseStatement is EmptyStatement) { +- SourceBuilder sb = new SourceBuilder(file, selectionOffset); +- String src = utils.getNodeText(ifNode); +- if (!src +- .substring(ifNode.elseKeyword.end - node.offset) +- .startsWith(new RegExp(r'[ \t]'))) { +- sb.append(' '); +- } +- _appendEmptyBraces(sb, true); +- _insertBuilder(sb); +- _setCompletion(DartStatementCompletion.COMPLETE_IF_STMT); +- return true; +- } +- return false; +- } +- var stmt = new _KeywordConditionBlockStructure( +- ifNode.ifKeyword, +- ifNode.leftParenthesis, +- ifNode.condition, +- ifNode.rightParenthesis, +- ifNode.thenStatement); +- return _complete_ifOrWhileStatement( +- stmt, DartStatementCompletion.COMPLETE_IF_STMT); +- } +- +- SourceBuilder _complete_keywordCondition( +- _KeywordConditionBlockStructure statement) { +- SourceBuilder sb; +- if (statement.leftParenthesis.isSynthetic) { +- if (!statement.rightParenthesis.isSynthetic) { +- // Quite unlikely to see this so don't try to fix it. +- return null; +- } +- sb = _sourceBuilderAfterKeyword(statement.keyword); +- sb.append('('); +- sb.setExitOffset(); +- sb.append(')'); +- } else { +- if (_isSyntheticExpression(statement.condition)) { +- exitPosition = _newPosition(statement.leftParenthesis.offset + 1); +- sb = new SourceBuilder(file, statement.rightParenthesis.offset + 1); +- } else { +- int afterParen = statement.rightParenthesis.offset + 1; +- if (utils +- .getNodeText(node) +- .substring(afterParen - node.offset) +- .startsWith(new RegExp(r'[ \t]'))) { +- _addReplaceEdit(new SourceRange(afterParen, 1), ''); +- sb = new SourceBuilder(file, afterParen + 1); +- } else { +- sb = new SourceBuilder(file, afterParen); +- } +- } +- } +- return sb; +- } +- +- bool _complete_methodCall() { +- var parenError = +- _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "')'") ?? +- _findError(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "')'"); +- if (parenError == null) { +- return false; +- } +- AstNode argList = _selectedNode(at: selectionOffset) +- .getAncestor((n) => n is ArgumentList); +- if (argList == null) { +- argList = _selectedNode(at: parenError.offset) +- .getAncestor((n) => n is ArgumentList); +- } +- if (argList?.getAncestor((n) => n == node) == null) { +- return false; +- } +- int previousInsertions = _lengthOfInsertions(); +- int loc = min(selectionOffset, argList.end - 1); +- int delta = 1; +- var semicolonError = +- _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); +- if (semicolonError == null) { +- loc += 1; +- delta = 0; +- } +- _addInsertEdit(loc, ')'); +- if (semicolonError != null) { +- _addInsertEdit(loc, ';'); +- } +- String indent = utils.getLinePrefix(selectionOffset); +- int exit = utils.getLineNext(selectionOffset); +- _addInsertEdit(exit, indent + eol); +- exit += indent.length + eol.length + previousInsertions; +- +- _setCompletionAt(DartStatementCompletion.SIMPLE_ENTER, exit + delta); +- return true; +- } +- +- bool _complete_simpleEnter() { +- int offset; +- if (!errors.isEmpty) { +- offset = selectionOffset; +- } else { +- String indent = utils.getLinePrefix(selectionOffset); +- int loc = utils.getLineNext(selectionOffset); +- _addInsertEdit(loc, indent + eol); +- offset = loc + indent.length; +- } +- _setCompletionAt(DartStatementCompletion.SIMPLE_ENTER, offset); +- return true; +- } +- +- bool _complete_simpleSemicolon() { +- if (errors.length != 1) { +- return false; +- } +- var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); +- if (error != null) { +- int previousInsertions = _lengthOfInsertions(); +- // TODO(messick) Fix this to find the correct place in all cases. +- int insertOffset = error.offset + error.length; +- _addInsertEdit(insertOffset, ';'); +- int offset = _appendNewlinePlusIndent() + 1 /*';'*/ + previousInsertions; +- _setCompletionAt(DartStatementCompletion.SIMPLE_SEMICOLON, offset); +- return true; +- } +- return false; +- } +- +- bool _complete_switchStatement() { +- if (node is! SwitchStatement) { +- return false; +- } +- SourceBuilder sb; +- SwitchStatement switchNode = node; +- if (switchNode.leftParenthesis.isSynthetic && +- switchNode.rightParenthesis.isSynthetic) { +- exitPosition = new Position(file, switchNode.switchKeyword.end + 2); +- String src = utils.getNodeText(switchNode); +- if (src +- .substring(switchNode.switchKeyword.end - switchNode.offset) +- .startsWith(new RegExp(r'[ \t]+'))) { +- sb = new SourceBuilder(file, switchNode.switchKeyword.end + 1); +- } else { +- sb = new SourceBuilder(file, switchNode.switchKeyword.end); +- sb.append(' '); +- } +- sb.append('()'); +- } else if (switchNode.leftParenthesis.isSynthetic || +- switchNode.rightParenthesis.isSynthetic) { +- return false; +- } else { +- sb = new SourceBuilder(file, switchNode.rightParenthesis.offset + 1); +- if (_isSyntheticExpression(switchNode.expression)) { +- exitPosition = +- new Position(file, switchNode.leftParenthesis.offset + 1); +- } +- } +- if (switchNode +- .leftBracket.isSynthetic /*&& switchNode.rightBracket.isSynthetic*/) { +- // See https://github.com/dart-lang/sdk/issues/29391 +- sb.append(' '); +- _appendEmptyBraces(sb, exitPosition == null); +- } else { +- SwitchMember member = _findInvalidElement(switchNode.members); +- if (member != null) { +- if (member.colon.isSynthetic) { +- int loc = +- member is SwitchCase ? member.expression.end : member.keyword.end; +- sb = new SourceBuilder(file, loc); +- sb.append(': '); +- exitPosition = new Position(file, loc + 2); +- } +- } +- } +- _insertBuilder(sb); +- _setCompletion(DartStatementCompletion.COMPLETE_SWITCH_STMT); +- return true; +- } +- +- bool _complete_tryStatement() { +- if (node is! TryStatement) { +- return false; +- } +- TryStatement tryNode = node; +- SourceBuilder sb; +- CatchClause catchNode; +- bool addSpace = true; +- if (tryNode.body.leftBracket.isSynthetic) { +- String src = utils.getNodeText(tryNode); +- if (src +- .substring(tryNode.tryKeyword.end - tryNode.offset) +- .startsWith(new RegExp(r'[ \t]+'))) { +- // keywordSpace +- sb = new SourceBuilder(file, tryNode.tryKeyword.end + 1); +- } else { +- // keywordOnly +- sb = new SourceBuilder(file, tryNode.tryKeyword.end); +- sb.append(' '); +- } +- _appendEmptyBraces(sb, true); +- _insertBuilder(sb); +- sb = null; +- } else if ((catchNode = _findInvalidElement(tryNode.catchClauses)) != +- null) { +- if (catchNode.onKeyword != null) { +- if (catchNode.exceptionType.length == 0 || +- null != +- _findError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, +- partialMatch: "name 'catch")) { +- String src = utils.getNodeText(catchNode); +- if (src.startsWith(new RegExp(r'on[ \t]+'))) { +- if (src.startsWith(new RegExp(r'on[ \t][ \t]+'))) { +- // onSpaces +- exitPosition = new Position(file, catchNode.onKeyword.end + 1); +- sb = new SourceBuilder(file, catchNode.onKeyword.end + 2); +- addSpace = false; +- } else { +- // onSpace +- sb = new SourceBuilder(file, catchNode.onKeyword.end + 1); +- sb.setExitOffset(); +- } +- } else { +- // onOnly +- sb = new SourceBuilder(file, catchNode.onKeyword.end); +- sb.append(' '); +- sb.setExitOffset(); +- } +- } else { +- // onType +- sb = new SourceBuilder(file, catchNode.exceptionType.end); +- } +- } +- if (catchNode.catchKeyword != null) { +- // catchOnly +- var struct = new _KeywordConditionBlockStructure( +- catchNode.catchKeyword, +- catchNode.leftParenthesis, +- catchNode.exceptionParameter, +- catchNode.rightParenthesis, +- catchNode.body); +- if (sb != null) { +- // onCatch +- _insertBuilder(sb); +- } +- sb = _complete_keywordCondition(struct); +- if (sb == null) { +- return false; +- } +- } +- if (catchNode.body.leftBracket.isSynthetic) { +- // onOnly and others +- if (addSpace) { +- sb.append(' '); +- } +- _appendEmptyBraces(sb, exitPosition == null); +- } +- _insertBuilder(sb); +- } else if (tryNode.finallyKeyword != null) { +- if (tryNode.finallyBlock.leftBracket.isSynthetic) { +- // finallyOnly +- sb = new SourceBuilder(file, tryNode.finallyKeyword.end); +- sb.append(' '); +- _appendEmptyBraces(sb, true); +- _insertBuilder(sb); +- } +- } +- _setCompletion(DartStatementCompletion.COMPLETE_TRY_STMT); +- return true; +- } +- +- bool _complete_variableDeclaration() { +- if (node is! VariableDeclaration) { +- return false; +- } +- _addInsertEdit(node.end, ';'); +- exitPosition = new Position(file, _appendNewlinePlusIndentAt(node.end) + 1); +- _setCompletion(DartStatementCompletion.COMPLETE_VARIABLE_DECLARATION); +- return true; +- } +- +- bool _complete_whileStatement() { +- if (node is! WhileStatement) { +- return false; +- } +- WhileStatement whileNode = node; +- if (whileNode != null) { +- var stmt = new _KeywordConditionBlockStructure( +- whileNode.whileKeyword, +- whileNode.leftParenthesis, +- whileNode.condition, +- whileNode.rightParenthesis, +- whileNode.body); +- return _complete_ifOrWhileStatement( +- stmt, DartStatementCompletion.COMPLETE_WHILE_STMT); +- } +- return false; +- } +- +- engine.AnalysisError _findError(ErrorCode code, {partialMatch: null}) { +- return errors.firstWhere( +- (err) => +- err.errorCode == code && +- (partialMatch == null ? true : err.message.contains(partialMatch)), +- orElse: () => null); +- } +- +- T _findInvalidElement(NodeList list) { +- return list.firstWhere( +- (item) => selectionOffset >= item.offset && selectionOffset <= item.end, +- orElse: () => null); +- } +- +- LinkedEditGroup _getLinkedPosition(String groupId) { +- LinkedEditGroup group = linkedPositionGroups[groupId]; +- if (group == null) { +- group = new LinkedEditGroup.empty(); +- linkedPositionGroups[groupId] = group; +- } +- return group; +- } +- +- void _insertBuilder(SourceBuilder builder, [int length = 0]) { +- { +- SourceRange range = new SourceRange(builder.offset, length); +- String text = builder.toString(); +- _addReplaceEdit(range, text); +- } +- // add linked positions +- builder.linkedPositionGroups.forEach((String id, LinkedEditGroup group) { +- LinkedEditGroup fixGroup = _getLinkedPosition(id); +- group.positions.forEach((Position position) { +- fixGroup.addPosition(position, group.length); +- }); +- group.suggestions.forEach((LinkedEditSuggestion suggestion) { +- fixGroup.addSuggestion(suggestion); +- }); +- }); +- // add exit position +- { +- int exitOffset = builder.exitOffset; +- if (exitOffset != null) { +- exitPosition = _newPosition(exitOffset); +- } +- } +- } +- +- bool _isEmptyBlock(AstNode stmt) { +- return stmt is Block && stmt.statements.isEmpty; +- } +- +- bool _isEmptyStatement(AstNode stmt) { +- return stmt is EmptyStatement || _isEmptyBlock(stmt); +- } +- +- bool _isNonStatementDeclaration(AstNode n) { +- if (n is! Declaration) { +- return false; +- } +- if (n is! VariableDeclaration && n is! FunctionDeclaration) { +- return true; +- } +- AstNode p = n.parent; +- return p is! Statement && p?.parent is! Statement; +- } +- +- bool _isSyntheticExpression(Expression expr) { +- return expr is SimpleIdentifier && expr.isSynthetic; +- } +- +- int _lengthOfDeletions() { +- if (change.edits.isEmpty) { +- return 0; +- } +- int length = 0; +- for (SourceFileEdit edit in change.edits) { +- for (SourceEdit srcEdit in edit.edits) { +- if (srcEdit.length > 0) { +- length += srcEdit.length - srcEdit.replacement.length; +- } +- } +- } +- return length; +- } +- +- int _lengthOfInsertions() { +- // Any _complete_*() that may follow changes made by _checkExpressions() +- // must cache the result of this method and add that value to its +- // exit position. That's assuming all edits are done in increasing position. +- // There are currently no editing sequences that produce both insertions and +- // deletions, but if there were this approach would have to be generalized. +- if (change.edits.isEmpty) { +- return 0; +- } +- int length = 0; +- for (SourceFileEdit edit in change.edits) { +- for (SourceEdit srcEdit in edit.edits) { +- if (srcEdit.length == 0) { +- length += srcEdit.replacement.length; +- } +- } +- } +- return length; +- } +- +- Position _newPosition(int offset) { +- return new Position(file, offset); +- } +- +- void _removeError(errorCode, {partialMatch = null}) { +- var error = _findError(errorCode, partialMatch: partialMatch); +- if (error != null) { +- errors.remove(error); +- } +- } +- +- AstNode _selectedNode({int at: null}) => +- new NodeLocator(at == null ? selectionOffset : at).searchWithin(unit); +- +- void _setCompletion(StatementCompletionKind kind, [List args]) { +- assert(exitPosition != null); +- change.selection = exitPosition; +- change.message = formatList(kind.message, args); +- linkedPositionGroups.values +- .forEach((group) => change.addLinkedEditGroup(group)); +- completion = new StatementCompletion(kind, change); +- } +- +- void _setCompletionAt(StatementCompletionKind kind, int offset, [List args]) { +- exitPosition = _newPosition(offset); +- _setCompletion(kind, args); +- } +- +- SourceBuilder _sourceBuilderAfterKeyword(Token keyword) { +- SourceBuilder sb; +- String text = _baseNodeText(node); +- text = text.substring(keyword.offset - node.offset); +- int len = keyword.length; +- if (text.length == len || // onCatchComment +- !text.substring(len, len + 1).contains(new RegExp(r'[ \t]'))) { +- sb = new SourceBuilder(file, keyword.offset + len); +- sb.append(' '); +- } else { +- sb = new SourceBuilder(file, keyword.offset + len + 1); +- } +- return sb; +- } +- +- bool _statementHasValidBody(Token keyword, Statement body) { +- // A "valid" body is either a non-synthetic block or a single statement +- // on the same line as the parent statement, similar to dart_style. +- if (body.isSynthetic) { +- return false; +- } +- if (body is Block) { +- Block block = body; +- return (!(block.leftBracket.isSynthetic)); +- } +- return (lineInfo.getLocation(keyword.offset) == +- lineInfo.getLocation(body.offset)); +- } +-} +- +-// Encapsulate common structure of if-statement and while-statement. +-class _KeywordConditionBlockStructure { +- final Token keyword; +- final Token leftParenthesis, rightParenthesis; +- final Expression condition; +- final Statement block; +- +- _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, +- this.condition, this.rightParenthesis, this.block); +- +- int get offset => keyword.offset; +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart +deleted file mode 100644 +index 013e7cec40c..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/assist.dart ++++ /dev/null +@@ -1,126 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/assist/assist.dart'; +- +-/** +- * The implementation of [AssistContext]. +- */ +-class AssistContextImpl implements AssistContext { +- @override +- final AnalysisDriver analysisDriver; +- +- @override +- final Source source; +- +- @override +- final int selectionOffset; +- +- @override +- final int selectionLength; +- +- AssistContextImpl(this.analysisDriver, this.source, this.selectionOffset, +- this.selectionLength); +-} +- +-/** +- * An enumeration of possible assist kinds. +- */ +-class DartAssistKind { +- static const ADD_PART_DIRECTIVE = +- const AssistKind('ADD_PART_DIRECTIVE', 30, "Add 'part' directive"); +- static const ADD_TYPE_ANNOTATION = +- const AssistKind('ADD_TYPE_ANNOTATION', 30, "Add type annotation"); +- static const ASSIGN_TO_LOCAL_VARIABLE = const AssistKind( +- 'ASSIGN_TO_LOCAL_VARIABLE', 30, "Assign value to new local variable"); +- static const CONVERT_DOCUMENTATION_INTO_BLOCK = const AssistKind( +- 'CONVERT_DOCUMENTATION_INTO_BLOCK', +- 30, +- "Convert into block documentation comment"); +- static const CONVERT_DOCUMENTATION_INTO_LINE = const AssistKind( +- 'CONVERT_DOCUMENTATION_INTO_LINE', +- 30, +- "Convert into line documentation comment"); +- static const CONVERT_FLUTTER_CHILD = +- const AssistKind('CONVERT_FLUTTER_CHILD', 30, "Convert to children:"); +- static const CONVERT_INTO_BLOCK_BODY = const AssistKind( +- 'CONVERT_INTO_BLOCK_BODY', 30, "Convert into block body"); +- static const CONVERT_INTO_EXPRESSION_BODY = const AssistKind( +- 'CONVERT_INTO_EXPRESSION_BODY', 30, "Convert into expression body"); +- static const CONVERT_INTO_FOR_INDEX = const AssistKind( +- 'CONVERT_INTO_FOR_INDEX', 30, "Convert into for-index loop"); +- static const CONVERT_INTO_FINAL_FIELD = const AssistKind( +- 'CONVERT_INTO_FINAL_FIELD', 30, "Convert into final field"); +- static const CONVERT_INTO_GETTER = +- const AssistKind('CONVERT_INTO_GETTER', 30, "Convert into getter"); +- static const CONVERT_INTO_IS_NOT = +- const AssistKind('CONVERT_INTO_IS_NOT', 30, "Convert into is!"); +- static const CONVERT_INTO_IS_NOT_EMPTY = const AssistKind( +- 'CONVERT_INTO_IS_NOT_EMPTY', 30, "Convert into 'isNotEmpty'"); +- static const CONVERT_PART_OF_TO_URI = +- const AssistKind('CONVERT_PART_OF_TO_URI', 30, "Convert to use a URI"); +- static const CONVERT_TO_FIELD_PARAMETER = const AssistKind( +- 'CONVERT_TO_FIELD_PARAMETER', 30, "Convert to field formal parameter"); +- static const CONVERT_TO_NORMAL_PARAMETER = const AssistKind( +- 'CONVERT_TO_NORMAL_PARAMETER', 30, "Convert to normal parameter"); +- static const ENCAPSULATE_FIELD = +- const AssistKind('ENCAPSULATE_FIELD', 30, "Encapsulate field"); +- static const EXCHANGE_OPERANDS = +- const AssistKind('EXCHANGE_OPERANDS', 30, "Exchange operands"); +- static const EXTRACT_CLASS = +- const AssistKind('EXTRACT_CLASS', 30, "Extract class into file '{0}'"); +- static const IMPORT_ADD_SHOW = +- const AssistKind('IMPORT_ADD_SHOW', 30, "Add explicit 'show' combinator"); +- static const INTRODUCE_LOCAL_CAST_TYPE = const AssistKind( +- 'INTRODUCE_LOCAL_CAST_TYPE', 30, "Introduce new local with tested type"); +- static const INVERT_IF_STATEMENT = +- const AssistKind('INVERT_IF_STATEMENT', 30, "Invert 'if' statement"); +- static const JOIN_IF_WITH_INNER = const AssistKind('JOIN_IF_WITH_INNER', 30, +- "Join 'if' statement with inner 'if' statement"); +- static const JOIN_IF_WITH_OUTER = const AssistKind('JOIN_IF_WITH_OUTER', 30, +- "Join 'if' statement with outer 'if' statement"); +- static const JOIN_VARIABLE_DECLARATION = const AssistKind( +- 'JOIN_VARIABLE_DECLARATION', 30, "Join variable declaration"); +- static const MOVE_FLUTTER_WIDGET_DOWN = +- const AssistKind("MOVE_FLUTTER_WIDGET_DOWN", 30, "Move widget down"); +- static const MOVE_FLUTTER_WIDGET_UP = +- const AssistKind("MOVE_FLUTTER_WIDGET_UP", 30, "Move widget up"); +- static const REPARENT_FLUTTER_LIST = +- const AssistKind("REPARENT_FLUTTER_LIST", 30, "Wrap with new widget"); +- static const REPARENT_FLUTTER_WIDGET = +- const AssistKind("REPARENT_FLUTTER_WIDGET", 30, "Wrap with new widget"); +- static const REMOVE_TYPE_ANNOTATION = +- const AssistKind('REMOVE_TYPE_ANNOTATION', 29, "Remove type annotation"); +- static const REPLACE_CONDITIONAL_WITH_IF_ELSE = const AssistKind( +- 'REPLACE_CONDITIONAL_WITH_IF_ELSE', +- 30, +- "Replace conditional with 'if-else'"); +- static const REPLACE_IF_ELSE_WITH_CONDITIONAL = const AssistKind( +- 'REPLACE_IF_ELSE_WITH_CONDITIONAL', +- 30, +- "Replace 'if-else' with conditional ('c ? x : y')"); +- static const SPLIT_AND_CONDITION = +- const AssistKind('SPLIT_AND_CONDITION', 30, "Split && condition"); +- static const SPLIT_VARIABLE_DECLARATION = const AssistKind( +- 'SPLIT_VARIABLE_DECLARATION', 30, "Split variable declaration"); +- static const SURROUND_WITH_BLOCK = +- const AssistKind('SURROUND_WITH_BLOCK', 30, "Surround with block"); +- static const SURROUND_WITH_DO_WHILE = const AssistKind( +- 'SURROUND_WITH_DO_WHILE', 30, "Surround with 'do-while'"); +- static const SURROUND_WITH_FOR = +- const AssistKind('SURROUND_WITH_FOR', 30, "Surround with 'for'"); +- static const SURROUND_WITH_FOR_IN = +- const AssistKind('SURROUND_WITH_FOR_IN', 30, "Surround with 'for-in'"); +- static const SURROUND_WITH_IF = +- const AssistKind('SURROUND_WITH_IF', 30, "Surround with 'if'"); +- static const SURROUND_WITH_TRY_CATCH = const AssistKind( +- 'SURROUND_WITH_TRY_CATCH', 30, "Surround with 'try-catch'"); +- static const SURROUND_WITH_TRY_FINALLY = const AssistKind( +- 'SURROUND_WITH_TRY_FINALLY', 30, "Surround with 'try-finally'"); +- static const SURROUND_WITH_WHILE = +- const AssistKind('SURROUND_WITH_WHILE', 30, "Surround with 'while'"); +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart +deleted file mode 100644 +index 4ca94bf1d18..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart ++++ /dev/null +@@ -1,2617 +0,0 @@ +-// Copyright (c) 2014, 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:analysis_server/plugin/edit/assist/assist_core.dart'; +-import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; +-import 'package:analysis_server/src/services/correction/assist.dart'; +-import 'package:analysis_server/src/services/correction/name_suggestion.dart'; +-import 'package:analysis_server/src/services/correction/statement_analyzer.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/utilities/flutter.dart' as flutter; +-import 'package:analyzer/dart/analysis/session.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/ast/token.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/resolver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +-import 'package:analyzer_plugin/utilities/assist/assist.dart' +- hide AssistContributor; +-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +-import 'package:path/path.dart'; +- +-typedef _SimpleIdentifierVisitor(SimpleIdentifier node); +- +-/** +- * The computer for Dart assists. +- */ +-class AssistProcessor { +- /** +- * The analysis driver being used to perform analysis. +- */ +- AnalysisDriver driver; +- +- Source source; +- String file; +- +- CompilationUnit unit; +- CompilationUnitElement unitElement; +- +- LibraryElement unitLibraryElement; +- String unitLibraryFile; +- String unitLibraryFolder; +- +- int selectionOffset; +- int selectionLength; +- int selectionEnd; +- +- final List assists = []; +- +- Position exitPosition = null; +- +- CorrectionUtils utils; +- +- AstNode node; +- +- TypeProvider _typeProvider; +- +- AssistProcessor(DartAssistContext dartContext) { +- driver = dartContext.analysisDriver; +- // source +- source = dartContext.source; +- file = dartContext.source.fullName; +- // unit +- unit = dartContext.unit; +- unitElement = dartContext.unit.element; +- // library +- unitLibraryElement = resolutionMap +- .elementDeclaredByCompilationUnit(dartContext.unit) +- .library; +- unitLibraryFile = unitLibraryElement.source.fullName; +- unitLibraryFolder = dirname(unitLibraryFile); +- // selection +- selectionOffset = dartContext.selectionOffset; +- selectionLength = dartContext.selectionLength; +- selectionEnd = selectionOffset + selectionLength; +- } +- +- /** +- * Returns the EOL to use for this [CompilationUnit]. +- */ +- String get eol => utils.endOfLine; +- +- /** +- * Return the analysis session to be used to create the change builder. +- */ +- AnalysisSession get session => driver.currentSession; +- +- TypeProvider get typeProvider { +- if (_typeProvider == null) { +- _typeProvider = unitElement.context.typeProvider; +- } +- return _typeProvider; +- } +- +- Future> compute() async { +- try { +- utils = new CorrectionUtils(unit); +- } catch (e) { +- throw new CancelCorrectionException(exception: e); +- } +- +- node = new NodeLocator(selectionOffset, selectionEnd).searchWithin(unit); +- if (node == null) { +- return assists; +- } +- +- await _addProposal_addTypeAnnotation_DeclaredIdentifier(); +- await _addProposal_addTypeAnnotation_SimpleFormalParameter(); +- await _addProposal_addTypeAnnotation_VariableDeclaration(); +- await _addProposal_assignToLocalVariable(); +- await _addProposal_convertIntoFinalField(); +- await _addProposal_convertIntoGetter(); +- await _addProposal_convertDocumentationIntoBlock(); +- await _addProposal_convertDocumentationIntoLine(); +- await _addProposal_convertToBlockFunctionBody(); +- await _addProposal_convertToExpressionFunctionBody(); +- await _addProposal_convertFlutterChild(); +- await _addProposal_convertPartOfToUri(); +- await _addProposal_convertToForIndexLoop(); +- await _addProposal_convertToIsNot_onIs(); +- await _addProposal_convertToIsNot_onNot(); +- await _addProposal_convertToIsNotEmpty(); +- await _addProposal_convertToFieldParameter(); +- await _addProposal_convertToNormalParameter(); +- await _addProposal_encapsulateField(); +- await _addProposal_exchangeOperands(); +- await _addProposal_importAddShow(); +- await _addProposal_introduceLocalTestedType(); +- await _addProposal_invertIf(); +- await _addProposal_joinIfStatementInner(); +- await _addProposal_joinIfStatementOuter(); +- await _addProposal_joinVariableDeclaration_onAssignment(); +- await _addProposal_joinVariableDeclaration_onDeclaration(); +- await _addProposal_moveFlutterWidgetDown(); +- await _addProposal_moveFlutterWidgetUp(); +- await _addProposal_removeTypeAnnotation(); +- await _addProposal_reparentFlutterList(); +- await _addProposal_reparentFlutterWidget(); +- await _addProposal_replaceConditionalWithIfElse(); +- await _addProposal_replaceIfElseWithConditional(); +- await _addProposal_splitAndCondition(); +- await _addProposal_splitVariableDeclaration(); +- await _addProposal_surroundWith(); +- +- return assists; +- } +- +- FunctionBody getEnclosingFunctionBody() { +- { +- FunctionExpression function = +- node.getAncestor((node) => node is FunctionExpression); +- if (function != null) { +- return function.body; +- } +- } +- { +- FunctionDeclaration function = +- node.getAncestor((node) => node is FunctionDeclaration); +- if (function != null) { +- return function.functionExpression.body; +- } +- } +- { +- ConstructorDeclaration constructor = +- node.getAncestor((node) => node is ConstructorDeclaration); +- if (constructor != null) { +- return constructor.body; +- } +- } +- { +- MethodDeclaration method = +- node.getAncestor((node) => node is MethodDeclaration); +- if (method != null) { +- return method.body; +- } +- } +- return null; +- } +- +- void _addAssistFromBuilder(DartChangeBuilder builder, AssistKind kind, +- {List args: null}) { +- SourceChange change = builder.sourceChange; +- if (change.edits.isEmpty) { +- _coverageMarker(); +- return; +- } +- change.message = formatList(kind.message, args); +- assists.add(new Assist(kind, change)); +- } +- +- Future _addProposal_addTypeAnnotation_DeclaredIdentifier() async { +- DeclaredIdentifier declaredIdentifier = +- node.getAncestor((n) => n is DeclaredIdentifier); +- if (declaredIdentifier == null) { +- ForEachStatement forEach = node.getAncestor((n) => n is ForEachStatement); +- int offset = node.offset; +- if (forEach != null && +- forEach.iterable != null && +- offset < forEach.iterable.offset) { +- declaredIdentifier = forEach.loopVariable; +- } +- } +- if (declaredIdentifier == null) { +- _coverageMarker(); +- return; +- } +- // Ensure that there isn't already a type annotation. +- if (declaredIdentifier.type != null) { +- _coverageMarker(); +- return; +- } +- DartType type = declaredIdentifier.identifier.bestType; +- if (type is! InterfaceType && type is! FunctionType) { +- _coverageMarker(); +- return; +- } +- _configureTargetLocation(node); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- bool validChange = true; +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- Token keyword = declaredIdentifier.keyword; +- if (keyword.keyword == Keyword.VAR) { +- builder.addReplacement(range.token(keyword), (DartEditBuilder builder) { +- validChange = builder.writeType(type); +- }); +- } else { +- builder.addInsertion(declaredIdentifier.identifier.offset, +- (DartEditBuilder builder) { +- validChange = builder.writeType(type); +- builder.write(' '); +- }); +- } +- }); +- if (validChange) { +- _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- } +- +- Future _addProposal_addTypeAnnotation_SimpleFormalParameter() async { +- AstNode node = this.node; +- // should be the name of a simple parameter +- if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) { +- _coverageMarker(); +- return; +- } +- SimpleIdentifier name = node; +- SimpleFormalParameter parameter = node.parent; +- // the parameter should not have a type +- if (parameter.type != null) { +- _coverageMarker(); +- return; +- } +- // prepare the type +- DartType type = parameter.element.type; +- // TODO(scheglov) If the parameter is in a method declaration, and if the +- // method overrides a method that has a type for the corresponding +- // parameter, it would be nice to copy down the type from the overridden +- // method. +- if (type is! InterfaceType) { +- _coverageMarker(); +- return; +- } +- // prepare type source +- _configureTargetLocation(node); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- bool validChange = true; +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(name.offset, (DartEditBuilder builder) { +- validChange = builder.writeType(type); +- builder.write(' '); +- }); +- }); +- if (validChange) { +- _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- } +- +- Future _addProposal_addTypeAnnotation_VariableDeclaration() async { +- AstNode node = this.node; +- // prepare VariableDeclarationList +- VariableDeclarationList declarationList = +- node.getAncestor((node) => node is VariableDeclarationList); +- if (declarationList == null) { +- _coverageMarker(); +- return; +- } +- // may be has type annotation already +- if (declarationList.type != null) { +- _coverageMarker(); +- return; +- } +- // prepare single VariableDeclaration +- List variables = declarationList.variables; +- if (variables.length != 1) { +- _coverageMarker(); +- return; +- } +- VariableDeclaration variable = variables[0]; +- // must be not after the name of the variable +- if (selectionOffset > variable.name.end) { +- _coverageMarker(); +- return; +- } +- // we need an initializer to get the type from +- Expression initializer = variable.initializer; +- if (initializer == null) { +- _coverageMarker(); +- return; +- } +- DartType type = initializer.bestType; +- // prepare type source +- if ((type is! InterfaceType || type.isDartCoreNull) && +- type is! FunctionType) { +- _coverageMarker(); +- return; +- } +- _configureTargetLocation(node); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- bool validChange = true; +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- Token keyword = declarationList.keyword; +- if (keyword?.keyword == Keyword.VAR) { +- builder.addReplacement(range.token(keyword), (DartEditBuilder builder) { +- validChange = builder.writeType(type); +- }); +- } else { +- builder.addInsertion(variable.offset, (DartEditBuilder builder) { +- validChange = builder.writeType(type); +- builder.write(' '); +- }); +- } +- }); +- if (validChange) { +- _addAssistFromBuilder(changeBuilder, DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- } +- +- Future _addProposal_assignToLocalVariable() async { +- // prepare enclosing ExpressionStatement +- ExpressionStatement expressionStatement; +- for (AstNode node = this.node; node != null; node = node.parent) { +- if (node is ExpressionStatement) { +- expressionStatement = node; +- break; +- } +- if (node is ArgumentList || +- node is AssignmentExpression || +- node is Statement || +- node is ThrowExpression) { +- _coverageMarker(); +- return; +- } +- } +- if (expressionStatement == null) { +- _coverageMarker(); +- return; +- } +- // prepare expression +- Expression expression = expressionStatement.expression; +- int offset = expression.offset; +- // prepare expression type +- DartType type = expression.bestType; +- if (type.isVoid) { +- _coverageMarker(); +- return; +- } +- // prepare excluded names +- Set excluded = new Set(); +- ScopedNameFinder scopedNameFinder = new ScopedNameFinder(offset); +- expression.accept(scopedNameFinder); +- excluded.addAll(scopedNameFinder.locals.keys.toSet()); +- List suggestions = +- getVariableNameSuggestionsForExpression(type, expression, excluded); +- +- if (suggestions.isNotEmpty) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(offset, (DartEditBuilder builder) { +- builder.write('var '); +- builder.addSimpleLinkedEdit('NAME', suggestions[0], +- kind: LinkedEditSuggestionKind.VARIABLE, +- suggestions: suggestions); +- builder.write(' = '); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE); +- } +- } +- +- Future _addProposal_convertDocumentationIntoBlock() async { +- Comment comment = node.getAncestor((n) => n is Comment); +- if (comment == null || !comment.isDocumentation) { +- return; +- } +- var tokens = comment.tokens; +- if (tokens.isEmpty || +- tokens.any((Token token) => +- token is! DocumentationCommentToken || +- token.type != TokenType.SINGLE_LINE_COMMENT)) { +- return; +- } +- String prefix = utils.getNodePrefix(comment); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(comment), (DartEditBuilder builder) { +- builder.writeln('/**'); +- for (Token token in comment.tokens) { +- builder.write(prefix); +- builder.write(' *'); +- builder.writeln(token.lexeme.substring('///'.length)); +- } +- builder.write(prefix); +- builder.write(' */'); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK); +- } +- +- Future _addProposal_convertDocumentationIntoLine() async { +- Comment comment = node.getAncestor((n) => n is Comment); +- if (comment == null || +- !comment.isDocumentation || +- comment.tokens.length != 1) { +- _coverageMarker(); +- return; +- } +- Token token = comment.tokens.first; +- if (token.type != TokenType.MULTI_LINE_COMMENT) { +- _coverageMarker(); +- return; +- } +- String text = token.lexeme; +- List lines = text.split('\n'); +- String prefix = utils.getNodePrefix(comment); +- List newLines = []; +- bool firstLine = true; +- String linePrefix = ''; +- for (String line in lines) { +- if (firstLine) { +- firstLine = false; +- String expectedPrefix = '/**'; +- if (!line.startsWith(expectedPrefix)) { +- _coverageMarker(); +- return; +- } +- line = line.substring(expectedPrefix.length).trim(); +- if (line.isNotEmpty) { +- newLines.add('/// $line'); +- linePrefix = eol + prefix; +- } +- } else { +- if (line.startsWith(prefix + ' */')) { +- break; +- } +- String expectedPrefix = prefix + ' * '; +- if (!line.startsWith(expectedPrefix)) { +- _coverageMarker(); +- return; +- } +- line = line.substring(expectedPrefix.length).trim(); +- newLines.add('$linePrefix/// $line'); +- linePrefix = eol + prefix; +- } +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(comment), (DartEditBuilder builder) { +- for (String newLine in newLines) { +- builder.write(newLine); +- } +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE); +- } +- +- Future _addProposal_convertFlutterChild() async { +- NamedExpression namedExp; +- // Allow assist to activate from either the new-expr or the child: arg. +- if (node is SimpleIdentifier && +- node.parent is Label && +- node.parent.parent is NamedExpression) { +- namedExp = node.parent.parent as NamedExpression; +- if ((node as SimpleIdentifier).name != 'child' || +- namedExp.expression == null) { +- return; +- } +- if (namedExp.parent?.parent is! InstanceCreationExpression) { +- return; +- } +- InstanceCreationExpression newExpr = namedExp.parent.parent; +- if (newExpr == null || !flutter.isWidgetCreation(newExpr)) { +- return; +- } +- } else { +- InstanceCreationExpression newExpr = flutter.identifyNewExpression(node); +- if (newExpr == null || !flutter.isWidgetCreation(newExpr)) { +- _coverageMarker(); +- return; +- } +- namedExp = flutter.findChildArgument(newExpr); +- if (namedExp == null || namedExp.expression == null) { +- _coverageMarker(); +- return; +- } +- } +- InstanceCreationExpression childArg = +- flutter.getChildWidget(namedExp, false); +- if (childArg == null) { +- _coverageMarker(); +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- _convertFlutterChildToChildren(childArg, namedExp, eol, utils.getNodeText, +- utils.getLinePrefix, utils.getIndent, utils.getText, builder); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_FLUTTER_CHILD); +- } +- +- Future _addProposal_convertIntoFinalField() async { +- // Find the enclosing getter. +- MethodDeclaration getter; +- for (AstNode n = node; n != null; n = n.parent) { +- if (n is MethodDeclaration) { +- getter = n; +- break; +- } +- if (n is SimpleIdentifier || +- n is TypeAnnotation || +- n is TypeArgumentList) { +- continue; +- } +- break; +- } +- if (getter == null || !getter.isGetter) { +- return; +- } +- // Check that there is no corresponding setter. +- { +- ExecutableElement element = getter.element; +- if (element == null) { +- return; +- } +- Element enclosing = element.enclosingElement; +- if (enclosing is ClassElement) { +- if (enclosing.getSetter(element.name) != null) { +- return; +- } +- } +- } +- // Try to find the returned expression. +- Expression expression; +- { +- FunctionBody body = getter.body; +- if (body is ExpressionFunctionBody) { +- expression = body.expression; +- } else if (body is BlockFunctionBody) { +- List statements = body.block.statements; +- if (statements.length == 1) { +- Statement statement = statements.first; +- if (statement is ReturnStatement) { +- expression = statement.expression; +- } +- } +- } +- } +- // Use the returned expression as the field initializer. +- if (expression != null) { +- AstNode beginNodeToReplace = getter.name; +- String code = 'final'; +- if (getter.returnType != null) { +- beginNodeToReplace = getter.returnType; +- code += ' ' + _getNodeText(getter.returnType); +- } +- code += ' ' + _getNodeText(getter.name); +- if (expression is! NullLiteral) { +- code += ' = ' + _getNodeText(expression); +- } +- code += ';'; +- SourceRange replacementRange = range.startEnd(beginNodeToReplace, getter); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(replacementRange, code); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_INTO_FINAL_FIELD); +- } +- } +- +- Future _addProposal_convertIntoGetter() async { +- // Find the enclosing field declaration. +- FieldDeclaration fieldDeclaration; +- for (AstNode n = node; n != null; n = n.parent) { +- if (n is FieldDeclaration) { +- fieldDeclaration = n; +- break; +- } +- if (n is SimpleIdentifier || +- n is VariableDeclaration || +- n is VariableDeclarationList || +- n is TypeAnnotation || +- n is TypeArgumentList) { +- continue; +- } +- break; +- } +- if (fieldDeclaration == null) { +- return; +- } +- // The field must be final and has only one variable. +- VariableDeclarationList fieldList = fieldDeclaration.fields; +- if (!fieldList.isFinal || fieldList.variables.length != 1) { +- return; +- } +- VariableDeclaration field = fieldList.variables.first; +- // Prepare the initializer. +- Expression initializer = field.initializer; +- if (initializer == null) { +- return; +- } +- // Add proposal. +- String code = ''; +- if (fieldList.type != null) { +- code += _getNodeText(fieldList.type) + ' '; +- } +- code += 'get'; +- code += ' ' + _getNodeText(field.name); +- code += ' => ' + _getNodeText(initializer); +- code += ';'; +- SourceRange replacementRange = +- range.startEnd(fieldList.keyword, fieldDeclaration); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(replacementRange, code); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_GETTER); +- } +- +- Future _addProposal_convertPartOfToUri() async { +- PartOfDirective directive = +- node.getAncestor((node) => node is PartOfDirective); +- if (directive == null || directive.libraryName == null) { +- return; +- } +- String libraryPath = unitLibraryElement.source.fullName; +- String partPath = unit.element.source.fullName; +- String relativePath = relative(libraryPath, from: dirname(partPath)); +- SourceRange replacementRange = range.node(directive.libraryName); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(replacementRange, "'$relativePath'"); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_PART_OF_TO_URI); +- } +- +- Future _addProposal_convertToBlockFunctionBody() async { +- FunctionBody body = getEnclosingFunctionBody(); +- // prepare expression body +- if (body is! ExpressionFunctionBody || body.isGenerator) { +- _coverageMarker(); +- return; +- } +- +- Expression returnValue = (body as ExpressionFunctionBody).expression; +- +- // Return expressions can be quite large, e.g. Flutter build() methods. +- // It is surprising to see this Quick Assist deep in the function body. +- if (selectionOffset >= returnValue.offset) { +- _coverageMarker(); +- return; +- } +- +- DartType returnValueType = returnValue.staticType; +- String returnValueCode = _getNodeText(returnValue); +- // prepare prefix +- String prefix = utils.getNodePrefix(body.parent); +- String indent = utils.getIndent(1); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(body), (DartEditBuilder builder) { +- if (body.isAsynchronous) { +- builder.write('async '); +- } +- builder.write('{$eol$prefix$indent'); +- if (!returnValueType.isVoid) { +- builder.write('return '); +- } +- builder.write(returnValueCode); +- builder.write(';'); +- builder.selectHere(); +- builder.write('$eol$prefix}'); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_INTO_BLOCK_BODY); +- } +- +- Future _addProposal_convertToExpressionFunctionBody() async { +- // prepare current body +- FunctionBody body = getEnclosingFunctionBody(); +- if (body is! BlockFunctionBody || body.isGenerator) { +- _coverageMarker(); +- return; +- } +- // prepare return statement +- List statements = (body as BlockFunctionBody).block.statements; +- if (statements.length != 1) { +- _coverageMarker(); +- return; +- } +- Statement onlyStatement = statements.first; +- // prepare returned expression +- Expression returnExpression; +- if (onlyStatement is ReturnStatement) { +- returnExpression = onlyStatement.expression; +- } else if (onlyStatement is ExpressionStatement) { +- returnExpression = onlyStatement.expression; +- } +- if (returnExpression == null) { +- _coverageMarker(); +- return; +- } +- +- // Return expressions can be quite large, e.g. Flutter build() methods. +- // It is surprising to see this Quick Assist deep in the function body. +- if (selectionOffset >= returnExpression.offset) { +- _coverageMarker(); +- return; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(body), (DartEditBuilder builder) { +- if (body.isAsynchronous) { +- builder.write('async '); +- } +- builder.write('=> '); +- builder.write(_getNodeText(returnExpression)); +- if (body.parent is! FunctionExpression || +- body.parent.parent is FunctionDeclaration) { +- builder.write(';'); +- } +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- Future _addProposal_convertToFieldParameter() async { +- if (node == null) { +- return; +- } +- // prepare ConstructorDeclaration +- ConstructorDeclaration constructor = +- node.getAncestor((node) => node is ConstructorDeclaration); +- if (constructor == null) { +- return; +- } +- FormalParameterList parameterList = constructor.parameters; +- List initializers = constructor.initializers; +- // prepare parameter +- SimpleFormalParameter parameter; +- if (node.parent is SimpleFormalParameter && +- node.parent.parent is FormalParameterList && +- node.parent.parent.parent is ConstructorDeclaration) { +- parameter = node.parent; +- } +- if (node is SimpleIdentifier && +- node.parent is ConstructorFieldInitializer) { +- String name = (node as SimpleIdentifier).name; +- ConstructorFieldInitializer initializer = node.parent; +- if (initializer.expression == node) { +- for (FormalParameter formalParameter in parameterList.parameters) { +- if (formalParameter is SimpleFormalParameter && +- formalParameter.identifier.name == name) { +- parameter = formalParameter; +- } +- } +- } +- } +- // analyze parameter +- if (parameter != null) { +- String parameterName = parameter.identifier.name; +- ParameterElement parameterElement = parameter.element; +- // check number of references +- { +- int numOfReferences = 0; +- AstVisitor visitor = +- new _SimpleIdentifierRecursiveAstVisitor((SimpleIdentifier node) { +- if (node.staticElement == parameterElement) { +- numOfReferences++; +- } +- }); +- for (ConstructorInitializer initializer in initializers) { +- initializer.accept(visitor); +- } +- if (numOfReferences != 1) { +- return; +- } +- } +- // find the field initializer +- ConstructorFieldInitializer parameterInitializer; +- for (ConstructorInitializer initializer in initializers) { +- if (initializer is ConstructorFieldInitializer) { +- Expression expression = initializer.expression; +- if (expression is SimpleIdentifier && +- expression.name == parameterName) { +- parameterInitializer = initializer; +- } +- } +- } +- if (parameterInitializer == null) { +- return; +- } +- String fieldName = parameterInitializer.fieldName.name; +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // replace parameter +- builder.addSimpleReplacement(range.node(parameter), 'this.$fieldName'); +- // remove initializer +- int initializerIndex = initializers.indexOf(parameterInitializer); +- if (initializers.length == 1) { +- builder +- .addDeletion(range.endEnd(parameterList, parameterInitializer)); +- } else { +- if (initializerIndex == 0) { +- ConstructorInitializer next = initializers[initializerIndex + 1]; +- builder.addDeletion(range.startStart(parameterInitializer, next)); +- } else { +- ConstructorInitializer prev = initializers[initializerIndex - 1]; +- builder.addDeletion(range.endEnd(prev, parameterInitializer)); +- } +- } +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_TO_FIELD_PARAMETER); +- } +- } +- +- Future _addProposal_convertToForIndexLoop() async { +- // find enclosing ForEachStatement +- ForEachStatement forEachStatement = +- node.getAncestor((n) => n is ForEachStatement); +- if (forEachStatement == null) { +- _coverageMarker(); +- return; +- } +- if (selectionOffset < forEachStatement.offset || +- forEachStatement.rightParenthesis.end < selectionOffset) { +- _coverageMarker(); +- return; +- } +- // loop should declare variable +- DeclaredIdentifier loopVariable = forEachStatement.loopVariable; +- if (loopVariable == null) { +- _coverageMarker(); +- return; +- } +- // iterable should be VariableElement +- String listName; +- Expression iterable = forEachStatement.iterable; +- if (iterable is SimpleIdentifier && +- iterable.staticElement is VariableElement) { +- listName = iterable.name; +- } else { +- _coverageMarker(); +- return; +- } +- // iterable should be List +- { +- DartType iterableType = iterable.bestType; +- InterfaceType listType = typeProvider.listType; +- if (iterableType is! InterfaceType || +- iterableType.element != listType.element) { +- _coverageMarker(); +- return; +- } +- } +- // body should be Block +- if (forEachStatement.body is! Block) { +- _coverageMarker(); +- return; +- } +- Block body = forEachStatement.body; +- // prepare a name for the index variable +- String indexName; +- { +- Set conflicts = +- utils.findPossibleLocalVariableConflicts(forEachStatement.offset); +- if (!conflicts.contains('i')) { +- indexName = 'i'; +- } else if (!conflicts.contains('j')) { +- indexName = 'j'; +- } else if (!conflicts.contains('k')) { +- indexName = 'k'; +- } else { +- _coverageMarker(); +- return; +- } +- } +- // prepare environment +- String prefix = utils.getNodePrefix(forEachStatement); +- String indent = utils.getIndent(1); +- int firstBlockLine = utils.getLineContentEnd(body.leftBracket.end); +- // add change +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // TODO(brianwilkerson) Create linked positions for the loop variable. +- builder.addSimpleReplacement( +- range.startEnd(forEachStatement, forEachStatement.rightParenthesis), +- 'for (int $indexName = 0; $indexName < $listName.length; $indexName++)'); +- builder.addSimpleInsertion(firstBlockLine, +- '$prefix$indent$loopVariable = $listName[$indexName];$eol'); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_FOR_INDEX); +- } +- +- Future _addProposal_convertToIsNot_onIs() async { +- // may be child of "is" +- AstNode node = this.node; +- while (node != null && node is! IsExpression) { +- node = node.parent; +- } +- // prepare "is" +- if (node is! IsExpression) { +- _coverageMarker(); +- return; +- } +- IsExpression isExpression = node as IsExpression; +- if (isExpression.notOperator != null) { +- _coverageMarker(); +- return; +- } +- // prepare enclosing () +- AstNode parent = isExpression.parent; +- if (parent is! ParenthesizedExpression) { +- _coverageMarker(); +- return; +- } +- ParenthesizedExpression parExpression = parent as ParenthesizedExpression; +- // prepare enclosing !() +- AstNode parent2 = parent.parent; +- if (parent2 is! PrefixExpression) { +- _coverageMarker(); +- return; +- } +- PrefixExpression prefExpression = parent2 as PrefixExpression; +- if (prefExpression.operator.type != TokenType.BANG) { +- _coverageMarker(); +- return; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- if (getExpressionParentPrecedence(prefExpression) >= +- TokenClass.RELATIONAL_OPERATOR.precedence) { +- builder.addDeletion(range.token(prefExpression.operator)); +- } else { +- builder.addDeletion( +- range.startEnd(prefExpression, parExpression.leftParenthesis)); +- builder.addDeletion( +- range.startEnd(parExpression.rightParenthesis, prefExpression)); +- } +- builder.addSimpleInsertion(isExpression.isOperator.end, '!'); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- Future _addProposal_convertToIsNot_onNot() async { +- // may be () in prefix expression +- if (node is ParenthesizedExpression && node.parent is PrefixExpression) { +- node = node.parent; +- } +- // prepare !() +- if (node is! PrefixExpression) { +- _coverageMarker(); +- return; +- } +- PrefixExpression prefExpression = node as PrefixExpression; +- // should be ! operator +- if (prefExpression.operator.type != TokenType.BANG) { +- _coverageMarker(); +- return; +- } +- // prepare !() +- Expression operand = prefExpression.operand; +- if (operand is! ParenthesizedExpression) { +- _coverageMarker(); +- return; +- } +- ParenthesizedExpression parExpression = operand as ParenthesizedExpression; +- operand = parExpression.expression; +- // prepare "is" +- if (operand is! IsExpression) { +- _coverageMarker(); +- return; +- } +- IsExpression isExpression = operand as IsExpression; +- if (isExpression.notOperator != null) { +- _coverageMarker(); +- return; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- if (getExpressionParentPrecedence(prefExpression) >= +- TokenClass.RELATIONAL_OPERATOR.precedence) { +- builder.addDeletion(range.token(prefExpression.operator)); +- } else { +- builder.addDeletion( +- range.startEnd(prefExpression, parExpression.leftParenthesis)); +- builder.addDeletion( +- range.startEnd(parExpression.rightParenthesis, prefExpression)); +- } +- builder.addSimpleInsertion(isExpression.isOperator.end, '!'); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- /** +- * Converts "!isEmpty" -> "isNotEmpty" if possible. +- */ +- Future _addProposal_convertToIsNotEmpty() async { +- // prepare "expr.isEmpty" +- AstNode isEmptyAccess = null; +- SimpleIdentifier isEmptyIdentifier = null; +- if (node is SimpleIdentifier) { +- SimpleIdentifier identifier = node as SimpleIdentifier; +- AstNode parent = identifier.parent; +- // normal case (but rare) +- if (parent is PropertyAccess) { +- isEmptyIdentifier = parent.propertyName; +- isEmptyAccess = parent; +- } +- // usual case +- if (parent is PrefixedIdentifier) { +- isEmptyIdentifier = parent.identifier; +- isEmptyAccess = parent; +- } +- } +- if (isEmptyIdentifier == null) { +- _coverageMarker(); +- return; +- } +- // should be "isEmpty" +- Element propertyElement = isEmptyIdentifier.bestElement; +- if (propertyElement == null || 'isEmpty' != propertyElement.name) { +- _coverageMarker(); +- return; +- } +- // should have "isNotEmpty" +- Element propertyTarget = propertyElement.enclosingElement; +- if (propertyTarget == null || +- getChildren(propertyTarget, 'isNotEmpty').isEmpty) { +- _coverageMarker(); +- return; +- } +- // should be in PrefixExpression +- if (isEmptyAccess.parent is! PrefixExpression) { +- _coverageMarker(); +- return; +- } +- PrefixExpression prefixExpression = +- isEmptyAccess.parent as PrefixExpression; +- // should be ! +- if (prefixExpression.operator.type != TokenType.BANG) { +- _coverageMarker(); +- return; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion( +- range.startStart(prefixExpression, prefixExpression.operand)); +- builder.addSimpleReplacement(range.node(isEmptyIdentifier), 'isNotEmpty'); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY); +- } +- +- Future _addProposal_convertToNormalParameter() async { +- if (node is SimpleIdentifier && +- node.parent is FieldFormalParameter && +- node.parent.parent is FormalParameterList && +- node.parent.parent.parent is ConstructorDeclaration) { +- ConstructorDeclaration constructor = node.parent.parent.parent; +- FormalParameterList parameterList = node.parent.parent; +- FieldFormalParameter parameter = node.parent; +- ParameterElement parameterElement = parameter.element; +- String name = (node as SimpleIdentifier).name; +- // prepare type +- DartType type = parameterElement.type; +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // replace parameter +- if (type.isDynamic) { +- builder.addSimpleReplacement(range.node(parameter), name); +- } else { +- builder.addReplacement(range.node(parameter), +- (DartEditBuilder builder) { +- builder.writeType(type); +- builder.write(' '); +- builder.write(name); +- }); +- } +- // add field initializer +- List initializers = constructor.initializers; +- if (initializers.isEmpty) { +- builder.addSimpleInsertion(parameterList.end, ' : $name = $name'); +- } else { +- builder.addSimpleInsertion(initializers.last.end, ', $name = $name'); +- } +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.CONVERT_TO_NORMAL_PARAMETER); +- } +- } +- +- Future _addProposal_encapsulateField() async { +- // find FieldDeclaration +- FieldDeclaration fieldDeclaration = +- node.getAncestor((x) => x is FieldDeclaration); +- if (fieldDeclaration == null) { +- _coverageMarker(); +- return; +- } +- // not interesting for static +- if (fieldDeclaration.isStatic) { +- _coverageMarker(); +- return; +- } +- // has a parse error +- VariableDeclarationList variableList = fieldDeclaration.fields; +- if (variableList.keyword == null && variableList.type == null) { +- _coverageMarker(); +- return; +- } +- // not interesting for final +- if (variableList.isFinal) { +- _coverageMarker(); +- return; +- } +- // should have exactly one field +- List fields = variableList.variables; +- if (fields.length != 1) { +- _coverageMarker(); +- return; +- } +- VariableDeclaration field = fields.first; +- SimpleIdentifier nameNode = field.name; +- FieldElement fieldElement = nameNode.staticElement; +- // should have a public name +- String name = nameNode.name; +- if (Identifier.isPrivateName(name)) { +- _coverageMarker(); +- return; +- } +- // should be on the name +- if (nameNode != node) { +- _coverageMarker(); +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // rename field +- builder.addSimpleReplacement(range.node(nameNode), '_$name'); +- // update references in constructors +- ClassDeclaration classDeclaration = fieldDeclaration.parent; +- for (ClassMember member in classDeclaration.members) { +- if (member is ConstructorDeclaration) { +- for (FormalParameter parameter in member.parameters.parameters) { +- ParameterElement parameterElement = parameter.element; +- if (parameterElement is FieldFormalParameterElement && +- parameterElement.field == fieldElement) { +- SimpleIdentifier identifier = parameter.identifier; +- builder.addSimpleReplacement(range.node(identifier), '_$name'); +- } +- } +- } +- } +- // add accessors +- String eol2 = eol + eol; +- String typeNameCode = variableList.type != null +- ? _getNodeText(variableList.type) + ' ' +- : ''; +- String getterCode = '$eol2 ${typeNameCode}get $name => _$name;'; +- String setterCode = '$eol2' +- ' void set $name($typeNameCode$name) {$eol' +- ' _$name = $name;$eol' +- ' }'; +- builder.addSimpleInsertion(fieldDeclaration.end, getterCode + setterCode); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- Future _addProposal_exchangeOperands() async { +- // check that user invokes quick assist on binary expression +- if (node is! BinaryExpression) { +- _coverageMarker(); +- return; +- } +- BinaryExpression binaryExpression = node as BinaryExpression; +- // prepare operator position +- if (!_isOperatorSelected( +- binaryExpression, selectionOffset, selectionLength)) { +- _coverageMarker(); +- return; +- } +- // add edits +- Expression leftOperand = binaryExpression.leftOperand; +- Expression rightOperand = binaryExpression.rightOperand; +- // find "wide" enclosing binary expression with same operator +- while (binaryExpression.parent is BinaryExpression) { +- BinaryExpression newBinaryExpression = +- binaryExpression.parent as BinaryExpression; +- if (newBinaryExpression.operator.type != binaryExpression.operator.type) { +- _coverageMarker(); +- break; +- } +- binaryExpression = newBinaryExpression; +- } +- // exchange parts of "wide" expression parts +- SourceRange leftRange = range.startEnd(binaryExpression, leftOperand); +- SourceRange rightRange = range.startEnd(rightOperand, binaryExpression); +- // maybe replace the operator +- Token operator = binaryExpression.operator; +- // prepare a new operator +- String newOperator = null; +- TokenType operatorType = operator.type; +- if (operatorType == TokenType.LT) { +- newOperator = '>'; +- } else if (operatorType == TokenType.LT_EQ) { +- newOperator = '>='; +- } else if (operatorType == TokenType.GT) { +- newOperator = '<'; +- } else if (operatorType == TokenType.GT_EQ) { +- newOperator = '<='; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(leftRange, _getRangeText(rightRange)); +- builder.addSimpleReplacement(rightRange, _getRangeText(leftRange)); +- // Optionally replace the operator. +- if (newOperator != null) { +- builder.addSimpleReplacement(range.token(operator), newOperator); +- } +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.EXCHANGE_OPERANDS); +- } +- +- Future _addProposal_importAddShow() async { +- // prepare ImportDirective +- ImportDirective importDirective = +- node.getAncestor((node) => node is ImportDirective); +- if (importDirective == null) { +- _coverageMarker(); +- return; +- } +- // there should be no existing combinators +- if (importDirective.combinators.isNotEmpty) { +- _coverageMarker(); +- return; +- } +- // prepare whole import namespace +- ImportElement importElement = importDirective.element; +- if (importElement == null) { +- _coverageMarker(); +- return; +- } +- Map namespace = getImportNamespace(importElement); +- // prepare names of referenced elements (from this import) +- SplayTreeSet referencedNames = new SplayTreeSet(); +- _SimpleIdentifierRecursiveAstVisitor visitor = +- new _SimpleIdentifierRecursiveAstVisitor((SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element != null && namespace[node.name] == element) { +- referencedNames.add(element.displayName); +- } +- }); +- unit.accept(visitor); +- // ignore if unused +- if (referencedNames.isEmpty) { +- _coverageMarker(); +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- String showCombinator = ' show ${referencedNames.join(', ')}'; +- builder.addSimpleInsertion(importDirective.end - 1, showCombinator); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.IMPORT_ADD_SHOW); +- } +- +- Future _addProposal_introduceLocalTestedType() async { +- AstNode node = this.node; +- if (node is IfStatement) { +- node = (node as IfStatement).condition; +- } else if (node is WhileStatement) { +- node = (node as WhileStatement).condition; +- } +- // prepare IsExpression +- if (node is! IsExpression) { +- _coverageMarker(); +- return; +- } +- IsExpression isExpression = node; +- DartType castType = isExpression.type.type; +- String castTypeCode = _getNodeText(isExpression.type); +- // prepare environment +- String indent = utils.getIndent(1); +- String prefix; +- Block targetBlock; +- { +- Statement statement = node.getAncestor((n) => n is Statement); +- if (statement is IfStatement && statement.thenStatement is Block) { +- targetBlock = statement.thenStatement; +- } else if (statement is WhileStatement && statement.body is Block) { +- targetBlock = statement.body; +- } else { +- _coverageMarker(); +- return; +- } +- prefix = utils.getNodePrefix(statement); +- } +- // prepare location +- int offset; +- String statementPrefix; +- if (isExpression.notOperator == null) { +- offset = targetBlock.leftBracket.end; +- statementPrefix = indent; +- } else { +- offset = targetBlock.rightBracket.end; +- statementPrefix = ''; +- } +- // prepare excluded names +- Set excluded = new Set(); +- ScopedNameFinder scopedNameFinder = new ScopedNameFinder(offset); +- isExpression.accept(scopedNameFinder); +- excluded.addAll(scopedNameFinder.locals.keys.toSet()); +- // name(s) +- List suggestions = +- getVariableNameSuggestionsForExpression(castType, null, excluded); +- +- if (suggestions.isNotEmpty) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(offset, (DartEditBuilder builder) { +- builder.write(eol + prefix + statementPrefix); +- builder.write(castTypeCode); +- builder.write(' '); +- builder.addSimpleLinkedEdit('NAME', suggestions[0], +- kind: LinkedEditSuggestionKind.VARIABLE, +- suggestions: suggestions); +- builder.write(' = '); +- builder.write(_getNodeText(isExpression.expression)); +- builder.write(';'); +- builder.selectHere(); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE); +- } +- } +- +- Future _addProposal_invertIf() async { +- if (node is! IfStatement) { +- return; +- } +- IfStatement ifStatement = node as IfStatement; +- Expression condition = ifStatement.condition; +- // should have both "then" and "else" +- Statement thenStatement = ifStatement.thenStatement; +- Statement elseStatement = ifStatement.elseStatement; +- if (thenStatement == null || elseStatement == null) { +- return; +- } +- // prepare source +- String invertedCondition = utils.invertCondition(condition); +- String thenSource = _getNodeText(thenStatement); +- String elseSource = _getNodeText(elseStatement); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(condition), invertedCondition); +- builder.addSimpleReplacement(range.node(thenStatement), elseSource); +- builder.addSimpleReplacement(range.node(elseStatement), thenSource); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.INVERT_IF_STATEMENT); +- } +- +- Future _addProposal_joinIfStatementInner() async { +- // climb up condition to the (supposedly) "if" statement +- AstNode node = this.node; +- while (node is Expression) { +- node = node.parent; +- } +- // prepare target "if" statement +- if (node is! IfStatement) { +- _coverageMarker(); +- return; +- } +- IfStatement targetIfStatement = node as IfStatement; +- if (targetIfStatement.elseStatement != null) { +- _coverageMarker(); +- return; +- } +- // prepare inner "if" statement +- Statement targetThenStatement = targetIfStatement.thenStatement; +- Statement innerStatement = getSingleStatement(targetThenStatement); +- if (innerStatement is! IfStatement) { +- _coverageMarker(); +- return; +- } +- IfStatement innerIfStatement = innerStatement as IfStatement; +- if (innerIfStatement.elseStatement != null) { +- _coverageMarker(); +- return; +- } +- // prepare environment +- String prefix = utils.getNodePrefix(targetIfStatement); +- // merge conditions +- String condition; +- { +- Expression targetCondition = targetIfStatement.condition; +- Expression innerCondition = innerIfStatement.condition; +- String targetConditionSource = _getNodeText(targetCondition); +- String innerConditionSource = _getNodeText(innerCondition); +- if (_shouldWrapParenthesisBeforeAnd(targetCondition)) { +- targetConditionSource = '($targetConditionSource)'; +- } +- if (_shouldWrapParenthesisBeforeAnd(innerCondition)) { +- innerConditionSource = '($innerConditionSource)'; +- } +- condition = '$targetConditionSource && $innerConditionSource'; +- } +- // replace target "if" statement +- Statement innerThenStatement = innerIfStatement.thenStatement; +- List innerThenStatements = getStatements(innerThenStatement); +- SourceRange lineRanges = utils.getLinesRangeStatements(innerThenStatements); +- String oldSource = utils.getRangeText(lineRanges); +- String newSource = utils.indentSourceLeftRight(oldSource); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(targetIfStatement), +- 'if ($condition) {$eol$newSource$prefix}'); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- Future _addProposal_joinIfStatementOuter() async { +- // climb up condition to the (supposedly) "if" statement +- AstNode node = this.node; +- while (node is Expression) { +- node = node.parent; +- } +- // prepare target "if" statement +- if (node is! IfStatement) { +- _coverageMarker(); +- return; +- } +- IfStatement targetIfStatement = node as IfStatement; +- if (targetIfStatement.elseStatement != null) { +- _coverageMarker(); +- return; +- } +- // prepare outer "if" statement +- AstNode parent = targetIfStatement.parent; +- if (parent is Block) { +- if ((parent as Block).statements.length != 1) { +- _coverageMarker(); +- return; +- } +- parent = parent.parent; +- } +- if (parent is! IfStatement) { +- _coverageMarker(); +- return; +- } +- IfStatement outerIfStatement = parent as IfStatement; +- if (outerIfStatement.elseStatement != null) { +- _coverageMarker(); +- return; +- } +- // prepare environment +- String prefix = utils.getNodePrefix(outerIfStatement); +- // merge conditions +- Expression targetCondition = targetIfStatement.condition; +- Expression outerCondition = outerIfStatement.condition; +- String targetConditionSource = _getNodeText(targetCondition); +- String outerConditionSource = _getNodeText(outerCondition); +- if (_shouldWrapParenthesisBeforeAnd(targetCondition)) { +- targetConditionSource = '($targetConditionSource)'; +- } +- if (_shouldWrapParenthesisBeforeAnd(outerCondition)) { +- outerConditionSource = '($outerConditionSource)'; +- } +- String condition = '$outerConditionSource && $targetConditionSource'; +- // replace outer "if" statement +- Statement targetThenStatement = targetIfStatement.thenStatement; +- List targetThenStatements = getStatements(targetThenStatement); +- SourceRange lineRanges = +- utils.getLinesRangeStatements(targetThenStatements); +- String oldSource = utils.getRangeText(lineRanges); +- String newSource = utils.indentSourceLeftRight(oldSource); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(outerIfStatement), +- 'if ($condition) {$eol$newSource$prefix}'); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- Future _addProposal_joinVariableDeclaration_onAssignment() async { +- // check that node is LHS in assignment +- if (node is SimpleIdentifier && +- node.parent is AssignmentExpression && +- (node.parent as AssignmentExpression).leftHandSide == node && +- node.parent.parent is ExpressionStatement) {} else { +- _coverageMarker(); +- return; +- } +- AssignmentExpression assignExpression = node.parent as AssignmentExpression; +- // check that binary expression is assignment +- if (assignExpression.operator.type != TokenType.EQ) { +- _coverageMarker(); +- return; +- } +- // prepare "declaration" statement +- Element element = (node as SimpleIdentifier).staticElement; +- if (element == null) { +- _coverageMarker(); +- return; +- } +- int declOffset = element.nameOffset; +- AstNode declNode = new NodeLocator(declOffset).searchWithin(unit); +- if (declNode != null && +- declNode.parent is VariableDeclaration && +- (declNode.parent as VariableDeclaration).name == declNode && +- declNode.parent.parent is VariableDeclarationList && +- declNode.parent.parent.parent is VariableDeclarationStatement) {} else { +- _coverageMarker(); +- return; +- } +- VariableDeclaration decl = declNode.parent as VariableDeclaration; +- VariableDeclarationStatement declStatement = +- decl.parent.parent as VariableDeclarationStatement; +- // may be has initializer +- if (decl.initializer != null) { +- _coverageMarker(); +- return; +- } +- // check that "declaration" statement declared only one variable +- if (declStatement.variables.variables.length != 1) { +- _coverageMarker(); +- return; +- } +- // check that the "declaration" and "assignment" statements are +- // parts of the same Block +- ExpressionStatement assignStatement = +- node.parent.parent as ExpressionStatement; +- if (assignStatement.parent is Block && +- assignStatement.parent == declStatement.parent) {} else { +- _coverageMarker(); +- return; +- } +- Block block = assignStatement.parent as Block; +- // check that "declaration" and "assignment" statements are adjacent +- List statements = block.statements; +- if (statements.indexOf(assignStatement) == +- statements.indexOf(declStatement) + 1) {} else { +- _coverageMarker(); +- return; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.endStart(declNode, assignExpression.operator), ' '); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- Future _addProposal_joinVariableDeclaration_onDeclaration() async { +- // prepare enclosing VariableDeclarationList +- VariableDeclarationList declList = +- node.getAncestor((node) => node is VariableDeclarationList); +- if (declList != null && declList.variables.length == 1) {} else { +- _coverageMarker(); +- return; +- } +- VariableDeclaration decl = declList.variables[0]; +- // already initialized +- if (decl.initializer != null) { +- _coverageMarker(); +- return; +- } +- // prepare VariableDeclarationStatement in Block +- if (declList.parent is VariableDeclarationStatement && +- declList.parent.parent is Block) {} else { +- _coverageMarker(); +- return; +- } +- VariableDeclarationStatement declStatement = +- declList.parent as VariableDeclarationStatement; +- Block block = declStatement.parent as Block; +- List statements = block.statements; +- // prepare assignment +- AssignmentExpression assignExpression; +- { +- // declaration should not be last Statement +- int declIndex = statements.indexOf(declStatement); +- if (declIndex < statements.length - 1) {} else { +- _coverageMarker(); +- return; +- } +- // next Statement should be assignment +- Statement assignStatement = statements[declIndex + 1]; +- if (assignStatement is ExpressionStatement) {} else { +- _coverageMarker(); +- return; +- } +- ExpressionStatement expressionStatement = +- assignStatement as ExpressionStatement; +- // expression should be assignment +- if (expressionStatement.expression is AssignmentExpression) {} else { +- _coverageMarker(); +- return; +- } +- assignExpression = expressionStatement.expression as AssignmentExpression; +- } +- // check that pure assignment +- if (assignExpression.operator.type != TokenType.EQ) { +- _coverageMarker(); +- return; +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.endStart(decl.name, assignExpression.operator), ' '); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- Future _addProposal_moveFlutterWidgetDown() async { +- InstanceCreationExpression exprGoingDown = +- flutter.identifyNewExpression(node); +- if (exprGoingDown == null || !flutter.isWidgetCreation(exprGoingDown)) { +- _coverageMarker(); +- return; +- } +- InstanceCreationExpression exprGoingUp = +- flutter.findChildWidget(exprGoingDown); +- if (exprGoingUp == null) { +- _coverageMarker(); +- return; +- } +- NamedExpression stableChild = flutter.findChildArgument(exprGoingUp); +- if (stableChild == null || stableChild.expression == null) { +- _coverageMarker(); +- return; +- } +- String exprGoingDownSrc = utils.getNodeText(exprGoingDown); +- int dnNewlineIdx = exprGoingDownSrc.lastIndexOf(eol); +- if (dnNewlineIdx < 0 || dnNewlineIdx == exprGoingDownSrc.length - 1) { +- _coverageMarker(); +- return; // Outer new-expr needs to be in multi-line format already. +- } +- String exprGoingUpSrc = utils.getNodeText(exprGoingUp); +- int upNewlineIdx = exprGoingUpSrc.lastIndexOf(eol); +- if (upNewlineIdx < 0 || upNewlineIdx == exprGoingUpSrc.length - 1) { +- _coverageMarker(); +- return; // Inner new-expr needs to be in multi-line format already. +- } +- await _swapFlutterWidgets(exprGoingDown, exprGoingUp, stableChild, +- DartAssistKind.MOVE_FLUTTER_WIDGET_DOWN); +- } +- +- Future _addProposal_moveFlutterWidgetUp() async { +- InstanceCreationExpression exprGoingUp = +- flutter.identifyNewExpression(node); +- if (exprGoingUp == null || !flutter.isWidgetCreation(exprGoingUp)) { +- _coverageMarker(); +- return; +- } +- AstNode expr = exprGoingUp.parent?.parent?.parent; +- if (expr == null || expr is! InstanceCreationExpression) { +- _coverageMarker(); +- return; +- } +- InstanceCreationExpression exprGoingDown = expr; +- NamedExpression stableChild = flutter.findChildArgument(exprGoingUp); +- if (stableChild == null || stableChild.expression == null) { +- _coverageMarker(); +- return; +- } +- String exprGoingUpSrc = utils.getNodeText(exprGoingUp); +- int upNewlineIdx = exprGoingUpSrc.lastIndexOf(eol); +- if (upNewlineIdx < 0 || upNewlineIdx == exprGoingUpSrc.length - 1) { +- _coverageMarker(); +- return; // Inner new-expr needs to be in multi-line format already. +- } +- String exprGoingDownSrc = utils.getNodeText(exprGoingDown); +- int dnNewlineIdx = exprGoingDownSrc.lastIndexOf(eol); +- if (dnNewlineIdx < 0 || dnNewlineIdx == exprGoingDownSrc.length - 1) { +- _coverageMarker(); +- return; // Outer new-expr needs to be in multi-line format already. +- } +- await _swapFlutterWidgets(exprGoingDown, exprGoingUp, stableChild, +- DartAssistKind.MOVE_FLUTTER_WIDGET_UP); +- } +- +- Future _addProposal_removeTypeAnnotation() async { +- VariableDeclarationList declarationList = +- node.getAncestor((n) => n is VariableDeclarationList); +- if (declarationList == null) { +- _coverageMarker(); +- return; +- } +- // we need a type +- TypeAnnotation typeNode = declarationList.type; +- if (typeNode == null) { +- _coverageMarker(); +- return; +- } +- // ignore if an incomplete variable declaration +- if (declarationList.variables.length == 1 && +- declarationList.variables[0].name.isSynthetic) { +- _coverageMarker(); +- return; +- } +- // must be not after the name of the variable +- VariableDeclaration firstVariable = declarationList.variables[0]; +- if (selectionOffset > firstVariable.name.end) { +- _coverageMarker(); +- return; +- } +- // The variable must have an initializer, otherwise there is no other +- // source for its type. +- if (firstVariable.initializer == null) { +- _coverageMarker(); +- return; +- } +- Token keyword = declarationList.keyword; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- SourceRange typeRange = range.startStart(typeNode, firstVariable); +- if (keyword != null && keyword.lexeme != 'var') { +- builder.addSimpleReplacement(typeRange, ''); +- } else { +- builder.addSimpleReplacement(typeRange, 'var '); +- } +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.REMOVE_TYPE_ANNOTATION); +- } +- +- Future _addProposal_reparentFlutterList() async { +- if (node is! ListLiteral) { +- return; +- } +- if ((node as ListLiteral).elements.any((Expression exp) => +- !(exp is InstanceCreationExpression && +- flutter.isWidgetCreation(exp)))) { +- _coverageMarker(); +- return; +- } +- String literalSrc = utils.getNodeText(node); +- int newlineIdx = literalSrc.lastIndexOf(eol); +- if (newlineIdx < 0 || newlineIdx == literalSrc.length - 1) { +- _coverageMarker(); +- return; // Lists need to be in multi-line format already. +- } +- String indentOld = utils.getLinePrefix(node.offset + 1 + newlineIdx); +- String indentArg = '$indentOld${utils.getIndent(1)}'; +- String indentList = '$indentOld${utils.getIndent(2)}'; +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(node), (DartEditBuilder builder) { +- builder.write('['); +- builder.write(eol); +- builder.write(indentArg); +- builder.write('new '); +- builder.addSimpleLinkedEdit('WIDGET', 'widget'); +- builder.write('('); +- builder.write(eol); +- builder.write(indentList); +- // Linked editing not needed since arg is always a list. +- builder.write('children: '); +- builder.write(literalSrc.replaceAll( +- new RegExp("^$indentOld", multiLine: true), "$indentList")); +- builder.write(','); +- builder.write(eol); +- builder.write(indentArg); +- builder.write('),'); +- builder.write(eol); +- builder.write(indentOld); +- builder.write(']'); +- builder.selectHere(); +- }); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.REPARENT_FLUTTER_LIST); +- } +- +- Future _addProposal_reparentFlutterWidget() async { +- InstanceCreationExpression newExpr = flutter.identifyNewExpression(node); +- if (newExpr == null || !flutter.isWidgetCreation(newExpr)) { +- _coverageMarker(); +- return; +- } +- String newExprSrc = utils.getNodeText(newExpr); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(newExpr), (DartEditBuilder builder) { +- builder.write('new '); +- builder.addSimpleLinkedEdit('WIDGET', 'widget'); +- builder.write('('); +- if (newExprSrc.contains(eol)) { +- int newlineIdx = newExprSrc.lastIndexOf(eol); +- int eolLen = eol.length; +- if (newlineIdx == newExprSrc.length - eolLen) { +- newlineIdx -= eolLen; +- } +- String indentOld = +- utils.getLinePrefix(newExpr.offset + eolLen + newlineIdx); +- String indentNew = '$indentOld${utils.getIndent(1)}'; +- builder.write(eol); +- builder.write(indentNew); +- newExprSrc = newExprSrc.replaceAll( +- new RegExp("^$indentOld", multiLine: true), indentNew); +- newExprSrc += ",$eol$indentOld"; +- } +- builder.addSimpleLinkedEdit('CHILD', 'child'); +- builder.write(': '); +- builder.write(newExprSrc); +- builder.write(')'); +- builder.selectHere(); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.REPARENT_FLUTTER_WIDGET); +- } +- +- Future _addProposal_replaceConditionalWithIfElse() async { +- ConditionalExpression conditional = null; +- // may be on Statement with Conditional +- Statement statement = node.getAncestor((node) => node is Statement); +- if (statement == null) { +- _coverageMarker(); +- return; +- } +- // variable declaration +- bool inVariable = false; +- if (statement is VariableDeclarationStatement) { +- VariableDeclarationStatement variableStatement = statement; +- for (VariableDeclaration variable +- in variableStatement.variables.variables) { +- if (variable.initializer is ConditionalExpression) { +- conditional = variable.initializer as ConditionalExpression; +- inVariable = true; +- break; +- } +- } +- } +- // assignment +- bool inAssignment = false; +- if (statement is ExpressionStatement) { +- ExpressionStatement exprStmt = statement; +- if (exprStmt.expression is AssignmentExpression) { +- AssignmentExpression assignment = +- exprStmt.expression as AssignmentExpression; +- if (assignment.operator.type == TokenType.EQ && +- assignment.rightHandSide is ConditionalExpression) { +- conditional = assignment.rightHandSide as ConditionalExpression; +- inAssignment = true; +- } +- } +- } +- // return +- bool inReturn = false; +- if (statement is ReturnStatement) { +- ReturnStatement returnStatement = statement; +- if (returnStatement.expression is ConditionalExpression) { +- conditional = returnStatement.expression as ConditionalExpression; +- inReturn = true; +- } +- } +- // prepare environment +- String indent = utils.getIndent(1); +- String prefix = utils.getNodePrefix(statement); +- +- if (inVariable || inAssignment || inReturn) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // Type v = Conditional; +- if (inVariable) { +- VariableDeclaration variable = +- conditional.parent as VariableDeclaration; +- builder.addDeletion(range.endEnd(variable.name, conditional)); +- String conditionSrc = _getNodeText(conditional.condition); +- String thenSrc = _getNodeText(conditional.thenExpression); +- String elseSrc = _getNodeText(conditional.elseExpression); +- String name = variable.name.name; +- String src = eol; +- src += prefix + 'if ($conditionSrc) {' + eol; +- src += prefix + indent + '$name = $thenSrc;' + eol; +- src += prefix + '} else {' + eol; +- src += prefix + indent + '$name = $elseSrc;' + eol; +- src += prefix + '}'; +- builder.addSimpleReplacement(range.endLength(statement, 0), src); +- } +- // v = Conditional; +- if (inAssignment) { +- AssignmentExpression assignment = +- conditional.parent as AssignmentExpression; +- Expression leftSide = assignment.leftHandSide; +- String conditionSrc = _getNodeText(conditional.condition); +- String thenSrc = _getNodeText(conditional.thenExpression); +- String elseSrc = _getNodeText(conditional.elseExpression); +- String name = _getNodeText(leftSide); +- String src = ''; +- src += 'if ($conditionSrc) {' + eol; +- src += prefix + indent + '$name = $thenSrc;' + eol; +- src += prefix + '} else {' + eol; +- src += prefix + indent + '$name = $elseSrc;' + eol; +- src += prefix + '}'; +- builder.addSimpleReplacement(range.node(statement), src); +- } +- // return Conditional; +- if (inReturn) { +- String conditionSrc = _getNodeText(conditional.condition); +- String thenSrc = _getNodeText(conditional.thenExpression); +- String elseSrc = _getNodeText(conditional.elseExpression); +- String src = ''; +- src += 'if ($conditionSrc) {' + eol; +- src += prefix + indent + 'return $thenSrc;' + eol; +- src += prefix + '} else {' + eol; +- src += prefix + indent + 'return $elseSrc;' + eol; +- src += prefix + '}'; +- builder.addSimpleReplacement(range.node(statement), src); +- } +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE); +- } +- } +- +- Future _addProposal_replaceIfElseWithConditional() async { +- // should be "if" +- if (node is! IfStatement) { +- _coverageMarker(); +- return; +- } +- IfStatement ifStatement = node as IfStatement; +- // single then/else statements +- Statement thenStatement = getSingleStatement(ifStatement.thenStatement); +- Statement elseStatement = getSingleStatement(ifStatement.elseStatement); +- if (thenStatement == null || elseStatement == null) { +- _coverageMarker(); +- return; +- } +- Expression thenExpression = null; +- Expression elseExpression = null; +- bool hasReturnStatements = false; +- if (thenStatement is ReturnStatement && elseStatement is ReturnStatement) { +- hasReturnStatements = true; +- thenExpression = thenStatement.expression; +- elseExpression = elseStatement.expression; +- } +- bool hasExpressionStatements = false; +- if (thenStatement is ExpressionStatement && +- elseStatement is ExpressionStatement) { +- if (thenStatement.expression is AssignmentExpression && +- elseStatement.expression is AssignmentExpression) { +- hasExpressionStatements = true; +- thenExpression = thenStatement.expression; +- elseExpression = elseStatement.expression; +- } +- } +- +- if (hasReturnStatements || hasExpressionStatements) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // returns +- if (hasReturnStatements) { +- String conditionSrc = _getNodeText(ifStatement.condition); +- String theSrc = _getNodeText(thenExpression); +- String elseSrc = _getNodeText(elseExpression); +- builder.addSimpleReplacement(range.node(ifStatement), +- 'return $conditionSrc ? $theSrc : $elseSrc;'); +- } +- // assignments -> v = Conditional; +- if (hasExpressionStatements) { +- AssignmentExpression thenAssignment = thenExpression; +- AssignmentExpression elseAssignment = elseExpression; +- String thenTarget = _getNodeText(thenAssignment.leftHandSide); +- String elseTarget = _getNodeText(elseAssignment.leftHandSide); +- if (thenAssignment.operator.type == TokenType.EQ && +- elseAssignment.operator.type == TokenType.EQ && +- thenTarget == elseTarget) { +- String conditionSrc = _getNodeText(ifStatement.condition); +- String theSrc = _getNodeText(thenAssignment.rightHandSide); +- String elseSrc = _getNodeText(elseAssignment.rightHandSide); +- builder.addSimpleReplacement(range.node(ifStatement), +- '$thenTarget = $conditionSrc ? $theSrc : $elseSrc;'); +- } +- } +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL); +- } +- } +- +- Future _addProposal_splitAndCondition() async { +- // check that user invokes quick assist on binary expression +- if (node is! BinaryExpression) { +- _coverageMarker(); +- return; +- } +- BinaryExpression binaryExpression = node as BinaryExpression; +- // prepare operator position +- if (!_isOperatorSelected( +- binaryExpression, selectionOffset, selectionLength)) { +- _coverageMarker(); +- return; +- } +- // should be && +- if (binaryExpression.operator.type != TokenType.AMPERSAND_AMPERSAND) { +- _coverageMarker(); +- return; +- } +- // prepare "if" +- Statement statement = node.getAncestor((node) => node is Statement); +- if (statement is! IfStatement) { +- _coverageMarker(); +- return; +- } +- IfStatement ifStatement = statement as IfStatement; +- // no support "else" +- if (ifStatement.elseStatement != null) { +- _coverageMarker(); +- return; +- } +- // check that binary expression is part of first level && condition of "if" +- BinaryExpression condition = binaryExpression; +- while (condition.parent is BinaryExpression && +- (condition.parent as BinaryExpression).operator.type == +- TokenType.AMPERSAND_AMPERSAND) { +- condition = condition.parent as BinaryExpression; +- } +- if (ifStatement.condition != condition) { +- _coverageMarker(); +- return; +- } +- // prepare environment +- String prefix = utils.getNodePrefix(ifStatement); +- String indent = utils.getIndent(1); +- // prepare "rightCondition" +- String rightConditionSource; +- { +- SourceRange rightConditionRange = +- range.startEnd(binaryExpression.rightOperand, condition); +- rightConditionSource = _getRangeText(rightConditionRange); +- } +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // remove "&& rightCondition" +- builder +- .addDeletion(range.endEnd(binaryExpression.leftOperand, condition)); +- // update "then" statement +- Statement thenStatement = ifStatement.thenStatement; +- if (thenStatement is Block) { +- Block thenBlock = thenStatement; +- SourceRange thenBlockRange = range.node(thenBlock); +- // insert inner "if" with right part of "condition" +- int thenBlockInsideOffset = thenBlockRange.offset + 1; +- builder.addSimpleInsertion(thenBlockInsideOffset, +- '$eol$prefix${indent}if ($rightConditionSource) {'); +- // insert closing "}" for inner "if" +- int thenBlockEnd = thenBlockRange.end; +- // insert before outer "then" block "}" +- builder.addSimpleInsertion(thenBlockEnd - 1, '$indent}$eol$prefix'); +- } else { +- // insert inner "if" with right part of "condition" +- String source = '$eol$prefix${indent}if ($rightConditionSource)'; +- builder.addSimpleInsertion( +- ifStatement.rightParenthesis.offset + 1, source); +- } +- // indent "then" statements to correspond inner "if" +- { +- List thenStatements = getStatements(thenStatement); +- SourceRange linesRange = utils.getLinesRangeStatements(thenStatements); +- String thenIndentOld = '$prefix$indent'; +- String thenIndentNew = '$thenIndentOld$indent'; +- builder.addSimpleReplacement( +- linesRange, +- utils.replaceSourceRangeIndent( +- linesRange, thenIndentOld, thenIndentNew)); +- } +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.SPLIT_AND_CONDITION); +- } +- +- Future _addProposal_splitVariableDeclaration() async { +- // prepare DartVariableStatement, should be part of Block +- VariableDeclarationStatement statement = +- node.getAncestor((node) => node is VariableDeclarationStatement); +- if (statement != null && statement.parent is Block) {} else { +- _coverageMarker(); +- return; +- } +- // check that statement declares single variable +- List variables = statement.variables.variables; +- if (variables.length != 1) { +- _coverageMarker(); +- return; +- } +- VariableDeclaration variable = variables[0]; +- // prepare initializer +- Expression initializer = variable.initializer; +- if (initializer == null) { +- _coverageMarker(); +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // remove initializer value +- builder.addDeletion(range.endStart(variable.name, statement.semicolon)); +- // add assignment statement +- String indent = utils.getNodePrefix(statement); +- String name = variable.name.name; +- String initSrc = _getNodeText(initializer); +- SourceRange assignRange = range.endLength(statement, 0); +- builder.addSimpleReplacement( +- assignRange, eol + indent + name + ' = ' + initSrc + ';'); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.SPLIT_VARIABLE_DECLARATION); +- } +- +- Future _addProposal_surroundWith() async { +- // prepare selected statements +- List selectedStatements; +- { +- StatementAnalyzer selectionAnalyzer = new StatementAnalyzer( +- unit, new SourceRange(selectionOffset, selectionLength)); +- unit.accept(selectionAnalyzer); +- List selectedNodes = selectionAnalyzer.selectedNodes; +- // convert nodes to statements +- selectedStatements = []; +- for (AstNode selectedNode in selectedNodes) { +- if (selectedNode is Statement) { +- selectedStatements.add(selectedNode); +- } +- } +- // we want only statements +- if (selectedStatements.isEmpty || +- selectedStatements.length != selectedNodes.length) { +- return; +- } +- } +- // prepare statement information +- Statement firstStatement = selectedStatements[0]; +- Statement lastStatement = selectedStatements[selectedStatements.length - 1]; +- SourceRange statementsRange = +- utils.getLinesRangeStatements(selectedStatements); +- // prepare environment +- String indentOld = utils.getNodePrefix(firstStatement); +- String indentNew = '$indentOld${utils.getIndent(1)}'; +- String indentedCode = +- utils.replaceSourceRangeIndent(statementsRange, indentOld, indentNew); +- // "block" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(statementsRange.offset, '$indentOld{$eol'); +- builder.addSimpleReplacement( +- statementsRange, +- utils.replaceSourceRangeIndent( +- statementsRange, indentOld, indentNew)); +- builder.addSimpleInsertion(statementsRange.end, '$indentOld}$eol'); +- exitPosition = _newPosition(lastStatement.end); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.SURROUND_WITH_BLOCK); +- } +- // "if" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('if ('); +- builder.addSimpleLinkedEdit('CONDITION', 'condition'); +- builder.write(') {'); +- builder.write(eol); +- builder.write(indentedCode); +- builder.write(indentOld); +- builder.write('}'); +- builder.selectHere(); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.SURROUND_WITH_IF); +- } +- // "while" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('while ('); +- builder.addSimpleLinkedEdit('CONDITION', 'condition'); +- builder.write(') {'); +- builder.write(eol); +- builder.write(indentedCode); +- builder.write(indentOld); +- builder.write('}'); +- builder.selectHere(); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.SURROUND_WITH_WHILE); +- } +- // "for-in" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('for (var '); +- builder.addSimpleLinkedEdit('NAME', 'item'); +- builder.write(' in '); +- builder.addSimpleLinkedEdit('ITERABLE', 'iterable'); +- builder.write(') {'); +- builder.write(eol); +- builder.write(indentedCode); +- builder.write(indentOld); +- builder.write('}'); +- builder.selectHere(); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.SURROUND_WITH_FOR_IN); +- } +- // "for" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('for (var '); +- builder.addSimpleLinkedEdit('VAR', 'v'); +- builder.write(' = '); +- builder.addSimpleLinkedEdit('INIT', 'init'); +- builder.write('; '); +- builder.addSimpleLinkedEdit('CONDITION', 'condition'); +- builder.write('; '); +- builder.addSimpleLinkedEdit('INCREMENT', 'increment'); +- builder.write(') {'); +- builder.write(eol); +- builder.write(indentedCode); +- builder.write(indentOld); +- builder.write('}'); +- builder.selectHere(); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder(changeBuilder, DartAssistKind.SURROUND_WITH_FOR); +- } +- // "do-while" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('do {'); +- builder.write(eol); +- builder.write(indentedCode); +- builder.write(indentOld); +- builder.write('} while ('); +- builder.addSimpleLinkedEdit('CONDITION', 'condition'); +- builder.write(');'); +- builder.selectHere(); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.SURROUND_WITH_DO_WHILE); +- } +- // "try-catch" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('try {'); +- builder.write(eol); +- builder.write(indentedCode); +- builder.write(indentOld); +- builder.write('} on '); +- builder.addSimpleLinkedEdit('EXCEPTION_TYPE', 'Exception'); +- builder.write(' catch ('); +- builder.addSimpleLinkedEdit('EXCEPTION_VAR', 'e'); +- builder.write(') {'); +- builder.write(eol); +- // +- builder.write(indentNew); +- builder.addSimpleLinkedEdit('CATCH', '// TODO'); +- builder.selectHere(); +- builder.write(eol); +- // +- builder.write(indentOld); +- builder.write('}'); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.SURROUND_WITH_TRY_CATCH); +- } +- // "try-finally" +- { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(statementsRange, (DartEditBuilder builder) { +- builder.write(indentOld); +- builder.write('try {'); +- builder.write(eol); +- // +- builder.write(indentedCode); +- // +- builder.write(indentOld); +- builder.write('} finally {'); +- builder.write(eol); +- // +- builder.write(indentNew); +- builder.addSimpleLinkedEdit('FINALLY', '// TODO'); +- builder.selectHere(); +- builder.write(eol); +- // +- builder.write(indentOld); +- builder.write('}'); +- builder.write(eol); +- }); +- }); +- _addAssistFromBuilder( +- changeBuilder, DartAssistKind.SURROUND_WITH_TRY_FINALLY); +- } +- } +- +- /** +- * Configures [utils] using given [target]. +- */ +- void _configureTargetLocation(Object target) { +- utils.targetClassElement = null; +- if (target is AstNode) { +- ClassDeclaration targetClassDeclaration = +- target.getAncestor((node) => node is ClassDeclaration); +- if (targetClassDeclaration != null) { +- utils.targetClassElement = targetClassDeclaration.element; +- } +- } +- } +- +- void _convertFlutterChildToChildren( +- InstanceCreationExpression childArg, +- NamedExpression namedExp, +- String eol, +- Function getNodeText, +- Function getLinePrefix, +- Function getIndent, +- Function getText, +- DartFileEditBuilder builder) { +- int childLoc = namedExp.offset + 'child'.length; +- builder.addSimpleInsertion(childLoc, 'ren'); +- int listLoc = childArg.offset; +- String childArgSrc = getNodeText(childArg); +- if (!childArgSrc.contains(eol)) { +- builder.addSimpleInsertion(listLoc, '['); +- builder.addSimpleInsertion(listLoc + childArg.length, ']'); +- } else { +- int newlineLoc = childArgSrc.lastIndexOf(eol); +- if (newlineLoc == childArgSrc.length) { +- newlineLoc -= 1; +- } +- String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc); +- String indentNew = '$indentOld${getIndent(1)}'; +- // The separator includes 'child:' but that has no newlines. +- String separator = +- getText(namedExp.offset, childArg.offset - namedExp.offset); +- String prefix = separator.contains(eol) ? "" : "$eol$indentNew"; +- if (prefix.isEmpty) { +- builder.addSimpleInsertion( +- namedExp.offset + 'child:'.length, ' ['); +- int argOffset = childArg.offset; +- builder +- .addDeletion(range.startOffsetEndOffset(argOffset - 2, argOffset)); +- } else { +- builder.addSimpleInsertion(listLoc, '['); +- } +- String newChildArgSrc = childArgSrc.replaceAll( +- new RegExp("^$indentOld", multiLine: true), "$indentNew"); +- newChildArgSrc = "$prefix$newChildArgSrc,$eol$indentOld]"; +- builder.addSimpleReplacement(range.node(childArg), newChildArgSrc); +- } +- } +- +- /** +- * Returns the text of the given node in the unit. +- */ +- String _getNodeText(AstNode node) { +- return utils.getNodeText(node); +- } +- +- /** +- * Returns the text of the given range in the unit. +- */ +- String _getRangeText(SourceRange range) { +- return utils.getRangeText(range); +- } +- +- Position _newPosition(int offset) { +- return new Position(file, offset); +- } +- +- Future _swapFlutterWidgets( +- InstanceCreationExpression exprGoingDown, +- InstanceCreationExpression exprGoingUp, +- NamedExpression stableChild, +- AssistKind assistKind) async { +- String currentSource = unitElement.context.getContents(source).data; +- // TODO(messick) Find a better way to get LineInfo for the source. +- LineInfo lineInfo = new LineInfo.fromContent(currentSource); +- int currLn = lineInfo.getLocation(exprGoingUp.offset).lineNumber; +- int lnOffset = lineInfo.getOffsetOfLine(currLn); +- +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(exprGoingDown), +- (DartEditBuilder builder) { +- String argSrc = +- utils.getText(exprGoingUp.offset, lnOffset - exprGoingUp.offset); +- builder.write(argSrc); // Append child new-expr plus rest of line. +- +- String getSrc(Expression expr) { +- int startLn = lineInfo.getLocation(expr.offset).lineNumber; +- int startOffset = lineInfo.getOffsetOfLine(startLn - 1); +- int endLn = +- lineInfo.getLocation(expr.offset + expr.length).lineNumber + 1; +- int curOffset = lineInfo.getOffsetOfLine(endLn - 1); +- return utils.getText(startOffset, curOffset - startOffset); +- } +- +- String outerIndent = utils.getNodePrefix(exprGoingDown.parent); +- String innerIndent = utils.getNodePrefix(exprGoingUp.parent); +- exprGoingUp.argumentList.arguments.forEach((arg) { +- if (arg is NamedExpression && arg.name.label.name == 'child') { +- if (stableChild != arg) { +- _coverageMarker(); +- return; +- } +- // Insert exprGoingDown here. +- // Copy from start of line to offset of exprGoingDown. +- currLn = lineInfo.getLocation(stableChild.offset).lineNumber; +- lnOffset = lineInfo.getOffsetOfLine(currLn - 1); +- argSrc = utils.getText( +- lnOffset, stableChild.expression.offset - lnOffset); +- argSrc = argSrc.replaceAll( +- new RegExp("^$innerIndent", multiLine: true), "$outerIndent"); +- builder.write(argSrc); +- int nextLn = lineInfo.getLocation(exprGoingDown.offset).lineNumber; +- lnOffset = lineInfo.getOffsetOfLine(nextLn); +- argSrc = utils.getText( +- exprGoingDown.offset, lnOffset - exprGoingDown.offset); +- builder.write(argSrc); +- +- exprGoingDown.argumentList.arguments.forEach((val) { +- if (val is NamedExpression && val.name.label.name == 'child') { +- // Insert stableChild here at same indent level. +- builder.write(utils.getNodePrefix(arg.name)); +- argSrc = utils.getNodeText(stableChild); +- builder.write(argSrc); +- if (assistKind == DartAssistKind.MOVE_FLUTTER_WIDGET_UP) { +- builder.write(',$eol'); +- } +- } else { +- argSrc = getSrc(val); +- argSrc = argSrc.replaceAll( +- new RegExp("^$outerIndent", multiLine: true), +- "$innerIndent"); +- builder.write(argSrc); +- } +- }); +- if (assistKind == DartAssistKind.MOVE_FLUTTER_WIDGET_DOWN) { +- builder.write(',$eol'); +- } +- builder.write(innerIndent); +- builder.write('),$eol'); +- } else { +- argSrc = getSrc(arg); +- argSrc = argSrc.replaceAll( +- new RegExp("^$innerIndent", multiLine: true), "$outerIndent"); +- builder.write(argSrc); +- } +- }); +- builder.write(outerIndent); +- builder.write(')'); +- builder.selectHere(); +- }); +- }); +- _addAssistFromBuilder(changeBuilder, assistKind); +- } +- +- /** +- * This method does nothing, but we invoke it in places where Dart VM +- * coverage agent fails to provide coverage information - such as almost +- * all "return" statements. +- * +- * https://code.google.com/p/dart/issues/detail?id=19912 +- */ +- static void _coverageMarker() {} +- +- /** +- * Returns `true` if the selection covers an operator of the given +- * [BinaryExpression]. +- */ +- static bool _isOperatorSelected( +- BinaryExpression binaryExpression, int offset, int length) { +- AstNode left = binaryExpression.leftOperand; +- AstNode right = binaryExpression.rightOperand; +- // between the nodes +- if (offset >= left.endToken.end && offset + length <= right.offset) { +- _coverageMarker(); +- return true; +- } +- // or exactly select the node (but not with infix expressions) +- if (offset == left.offset && offset + length == right.endToken.end) { +- if (left is BinaryExpression || right is BinaryExpression) { +- _coverageMarker(); +- return false; +- } +- _coverageMarker(); +- return true; +- } +- // invalid selection (part of node, etc) +- _coverageMarker(); +- return false; +- } +- +- /** +- * Checks if the given [Expression] should be wrapped with parenthesis when we +- * want to use it as operand of a logical `and` expression. +- */ +- static bool _shouldWrapParenthesisBeforeAnd(Expression expr) { +- if (expr is BinaryExpression) { +- BinaryExpression binary = expr; +- int precedence = binary.operator.type.precedence; +- return precedence < TokenClass.LOGICAL_AND_OPERATOR.precedence; +- } +- return false; +- } +-} +- +-/** +- * An [AssistContributor] that provides the default set of assists. +- */ +-class DefaultAssistContributor extends DartAssistContributor { +- @override +- Future> internalComputeAssists(DartAssistContext context) async { +- try { +- AssistProcessor processor = new AssistProcessor(context); +- return processor.compute(); +- } on CancelCorrectionException { +- return Assist.EMPTY_LIST; +- } +- } +-} +- +-class _SimpleIdentifierRecursiveAstVisitor extends RecursiveAstVisitor { +- final _SimpleIdentifierVisitor visitor; +- +- _SimpleIdentifierRecursiveAstVisitor(this.visitor); +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- visitor(node); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart +deleted file mode 100644 +index bfcd0dc5551..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/fix.dart ++++ /dev/null +@@ -1,260 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +-import 'package:analysis_server/src/services/correction/fix_internal.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/error/codes.dart'; +-import 'package:analyzer/src/generated/parser.dart'; +-import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +- +-/** +- * Return true if this [errorCode] is likely to have a fix associated with it. +- */ +-bool hasFix(ErrorCode errorCode) => +- errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN || +- errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER || +- errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS || +- errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED || +- errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR || +- errorCode == +- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE || +- errorCode == +- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO || +- errorCode == +- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE || +- errorCode == +- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR || +- errorCode == +- StaticWarningCode +- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS || +- errorCode == StaticWarningCode.CAST_TO_NON_TYPE || +- errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME || +- errorCode == StaticWarningCode.UNDEFINED_CLASS || +- errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED || +- errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 || +- errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 || +- errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS || +- errorCode == StaticWarningCode.FUNCTION_WITHOUT_CALL || +- errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER || +- errorCode == +- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE || +- errorCode == CompileTimeErrorCode.INVALID_ANNOTATION || +- errorCode == CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT || +- errorCode == CompileTimeErrorCode.PART_OF_NON_PART || +- errorCode == +- CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT || +- errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST || +- errorCode == CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED || +- errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE || +- errorCode == HintCode.DEAD_CODE || +- errorCode == HintCode.DIVISION_OPTIMIZATION || +- errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL || +- errorCode == HintCode.TYPE_CHECK_IS_NULL || +- errorCode == HintCode.UNDEFINED_GETTER || +- errorCode == HintCode.UNDEFINED_SETTER || +- errorCode == HintCode.UNNECESSARY_CAST || +- errorCode == HintCode.UNUSED_CATCH_CLAUSE || +- errorCode == HintCode.UNUSED_CATCH_STACK || +- errorCode == HintCode.UNUSED_IMPORT || +- errorCode == HintCode.UNDEFINED_METHOD || +- errorCode == ParserErrorCode.EXPECTED_TOKEN || +- errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS || +- errorCode == ParserErrorCode.VAR_AS_TYPE_NAME || +- errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE || +- errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER || +- errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION || +- errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT || +- errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION || +- errorCode == StaticTypeWarningCode.UNDEFINED_GETTER || +- errorCode == StaticTypeWarningCode.UNDEFINED_METHOD || +- errorCode == StaticTypeWarningCode.UNDEFINED_SETTER || +- errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER || +- (errorCode is LintCode && +- (errorCode.name == LintNames.annotate_overrides || +- errorCode.name == LintNames.avoid_init_to_null || +- errorCode.name == LintNames.prefer_collection_literals || +- errorCode.name == LintNames.prefer_conditional_assignment || +- errorCode.name == LintNames.unnecessary_brace_in_string_interp || +- errorCode.name == LintNames.unnecessary_lambdas || +- errorCode.name == LintNames.unnecessary_this)); +- +-/** +- * An enumeration of possible quick fix kinds. +- */ +-class DartFixKind { +- static const ADD_ASYNC = +- const FixKind('ADD_ASYNC', 50, "Add 'async' modifier"); +- static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind( +- 'ADD_FIELD_FORMAL_PARAMETERS', 30, "Add final field formal parameters"); +- static const ADD_MISSING_PARAMETER_POSITIONAL = const FixKind( +- 'ADD_MISSING_PARAMETER_POSITIONAL', +- 31, +- "Add optional positional parameter"); +- static const ADD_MISSING_PARAMETER_REQUIRED = const FixKind( +- 'ADD_MISSING_PARAMETER_REQUIRED', 30, "Add required parameter"); +- static const ADD_MISSING_REQUIRED_ARGUMENT = const FixKind( +- 'ADD_MISSING_REQUIRED_ARGUMENT', 30, "Add required argument '{0}'"); +- static const ADD_NE_NULL = const FixKind('ADD_NE_NULL', 50, "Add != null"); +- static const ADD_PACKAGE_DEPENDENCY = const FixKind( +- 'ADD_PACKAGE_DEPENDENCY', 50, "Add dependency on package '{0}'"); +- static const ADD_SUPER_CONSTRUCTOR_INVOCATION = const FixKind( +- 'ADD_SUPER_CONSTRUCTOR_INVOCATION', +- 50, +- "Add super constructor {0} invocation"); +- static const CHANGE_TO = const FixKind('CHANGE_TO', 49, "Change to '{0}'"); +- static const CHANGE_TO_STATIC_ACCESS = const FixKind( +- 'CHANGE_TO_STATIC_ACCESS', 50, "Change access to static using '{0}'"); +- static const CHANGE_TYPE_ANNOTATION = const FixKind( +- 'CHANGE_TYPE_ANNOTATION', 50, "Change '{0}' to '{1}' type annotation"); +- static const CONVERT_FLUTTER_CHILD = +- const FixKind('CONVERT_FLUTTER_CHILD', 50, "Convert to children:"); +- static const CREATE_CLASS = +- const FixKind('CREATE_CLASS', 50, "Create class '{0}'"); +- static const CREATE_CONSTRUCTOR = +- const FixKind('CREATE_CONSTRUCTOR', 50, "Create constructor '{0}'"); +- static const CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS = const FixKind( +- 'CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS', +- 50, +- "Create constructor for final fields"); +- static const CREATE_CONSTRUCTOR_SUPER = const FixKind( +- 'CREATE_CONSTRUCTOR_SUPER', 50, "Create constructor to call {0}"); +- static const CREATE_FIELD = +- const FixKind('CREATE_FIELD', 51, "Create field '{0}'"); +- static const CREATE_FILE = +- const FixKind('CREATE_FILE', 50, "Create file '{0}'"); +- static const CREATE_FUNCTION = +- const FixKind('CREATE_FUNCTION', 51, "Create function '{0}'"); +- static const CREATE_GETTER = +- const FixKind('CREATE_GETTER', 50, "Create getter '{0}'"); +- static const CREATE_LOCAL_VARIABLE = +- const FixKind('CREATE_LOCAL_VARIABLE', 50, "Create local variable '{0}'"); +- static const CREATE_METHOD = +- const FixKind('CREATE_METHOD', 50, "Create method '{0}'"); +- static const CREATE_MISSING_METHOD_CALL = +- const FixKind('CREATE_MISSING_METHOD_CALL', 49, "Create method 'call'."); +- static const CREATE_MISSING_OVERRIDES = const FixKind( +- 'CREATE_MISSING_OVERRIDES', 49, "Create {0} missing override(s)"); +- static const CREATE_NO_SUCH_METHOD = const FixKind( +- 'CREATE_NO_SUCH_METHOD', 51, "Create 'noSuchMethod' method"); +- static const IMPORT_LIBRARY_PREFIX = const FixKind('IMPORT_LIBRARY_PREFIX', +- 51, "Use imported library '{0}' with prefix '{1}'"); +- static const IMPORT_LIBRARY_PROJECT1 = +- const FixKind('IMPORT_LIBRARY_PROJECT1', 47, "Import library '{0}'"); +- static const IMPORT_LIBRARY_PROJECT2 = +- const FixKind('IMPORT_LIBRARY_PROJECT2', 48, "Import library '{0}'"); +- static const IMPORT_LIBRARY_PROJECT3 = +- const FixKind('IMPORT_LIBRARY_PROJECT3', 49, "Import library '{0}'"); +- static const IMPORT_LIBRARY_SDK = +- const FixKind('IMPORT_LIBRARY_SDK', 46, "Import library '{0}'"); +- static const IMPORT_LIBRARY_SHOW = +- const FixKind('IMPORT_LIBRARY_SHOW', 45, "Update library '{0}' import"); +- static const INSERT_SEMICOLON = +- const FixKind('INSERT_SEMICOLON', 50, "Insert ';'"); +- static const INVOKE_CONSTRUCTOR_USING_NEW = const FixKind( +- 'INVOKE_CONSTRUCTOR_USING_NEW', 50, "Invoke constructor using 'new'"); +- static const LINT_ADD_OVERRIDE = +- const FixKind('LINT_ADD_OVERRIDE', 50, "Add '@override' annotation"); +- static const LINT_ADD_REQUIRED = +- const FixKind('LINT_ADD_REQUIRED', 50, "Add '@required' annotation"); +- static const LINT_REMOVE_INTERPOLATION_BRACES = const FixKind( +- 'LINT_REMOVE_INTERPOLATION_BRACES', +- 50, +- 'Remove unnecessary interpolation braces'); +- static const MAKE_CLASS_ABSTRACT = +- const FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract"); +- static const REMOVE_DEAD_CODE = +- const FixKind('REMOVE_DEAD_CODE', 50, "Remove dead code"); +- static const MAKE_FIELD_NOT_FINAL = +- const FixKind('MAKE_FIELD_NOT_FINAL', 50, "Make field '{0}' not final"); +- static const REMOVE_AWAIT = const FixKind('REMOVE_AWAIT', 50, "Remove await"); +- static const REMOVE_EMPTY_CATCH = +- const FixKind('REMOVE_EMPTY_CATCH', 50, "Remove empty catch clause"); +- static const REMOVE_EMPTY_CONSTRUCTOR_BODY = const FixKind( +- 'REMOVE_EMPTY_CONSTRUCTOR_BODY', 50, "Remove empty constructor body"); +- static const REMOVE_EMPTY_ELSE = +- const FixKind('REMOVE_EMPTY_ELSE', 50, "Remove empty else clause"); +- static const REMOVE_EMPTY_STATEMENT = +- const FixKind('REMOVE_EMPTY_STATEMENT', 50, "Remove empty statement"); +- static const REMOVE_INITIALIZER = +- const FixKind('REMOVE_INITIALIZER', 50, "Remove initializer"); +- static const REMOVE_METHOD_DECLARATION = const FixKind( +- 'REMOVE_METHOD_DECLARATION', 50, 'Remove method declaration'); +- static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = const FixKind( +- 'REMOVE_PARAMETERS_IN_GETTER_DECLARATION', +- 50, +- "Remove parameters in getter declaration"); +- static const REMOVE_PARENTHESIS_IN_GETTER_INVOCATION = const FixKind( +- 'REMOVE_PARENTHESIS_IN_GETTER_INVOCATION', +- 50, +- "Remove parentheses in getter invocation"); +- static const REMOVE_THIS_EXPRESSION = +- const FixKind('REMOVE_THIS_EXPRESSION', 50, "Remove this expression"); +- static const REMOVE_TYPE_NAME = +- const FixKind('REMOVE_TYPE_NAME', 50, "Remove type name"); +- static const REMOVE_UNNECESSARY_CAST = +- const FixKind('REMOVE_UNNECESSARY_CAST', 50, "Remove unnecessary cast"); +- static const REMOVE_UNUSED_CATCH_CLAUSE = +- const FixKind('REMOVE_UNUSED_CATCH', 50, "Remove unused 'catch' clause"); +- static const REMOVE_UNUSED_CATCH_STACK = const FixKind( +- 'REMOVE_UNUSED_CATCH_STACK', 50, "Remove unused stack trace variable"); +- static const REMOVE_UNUSED_IMPORT = +- const FixKind('REMOVE_UNUSED_IMPORT', 50, "Remove unused import"); +- static const REPLACE_BOOLEAN_WITH_BOOL = const FixKind( +- 'REPLACE_BOOLEAN_WITH_BOOL', 50, "Replace 'boolean' with 'bool'"); +- static const REPLACE_VAR_WITH_DYNAMIC = const FixKind( +- 'REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'"); +- static const REPLACE_RETURN_TYPE_FUTURE = const FixKind( +- 'REPLACE_RETURN_TYPE_FUTURE', +- 50, +- "Return 'Future' from 'async' function"); +- static const REPLACE_WITH_BRACKETS = +- const FixKind('REPLACE_WITH_BRACKETS', 50, "Replace with { }"); +- static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = const FixKind( +- 'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, 'Replace with ??='); +- static const REPLACE_WITH_IDENTIFIER = +- const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier"); +- static const REPLACE_WITH_LITERAL = +- const FixKind('REPLACE_WITH_LITERAL', 50, 'Replace with literal'); +- static const REPLACE_WITH_NULL_AWARE = const FixKind( +- 'REPLACE_WITH_NULL_AWARE', +- 50, +- "Replace the '.' with a '?.' in the invocation"); +- static const REPLACE_WITH_TEAR_OFF = const FixKind( +- 'REPLACE_WITH_TEAR_OFF', 50, "Replace function literal with tear-off"); +- static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant"); +- static const USE_EFFECTIVE_INTEGER_DIVISION = const FixKind( +- 'USE_EFFECTIVE_INTEGER_DIVISION', +- 50, +- "Use effective integer division ~/"); +- static const USE_EQ_EQ_NULL = +- const FixKind('USE_EQ_EQ_NULL', 50, "Use == null instead of 'is Null'"); +- static const USE_IS_NOT_EMPTY = const FixKind( +- 'USE_NOT_EMPTY', 50, "Use x.isNotEmpty instead of '!x.isEmpty'"); +- static const USE_NOT_EQ_NULL = +- const FixKind('USE_NOT_EQ_NULL', 50, "Use != null instead of 'is! Null'"); +-} +- +-/** +- * The implementation of [FixContext]. +- */ +-class FixContextImpl implements FixContext { +- @override +- final ResourceProvider resourceProvider; +- +- @override +- final AnalysisDriver analysisDriver; +- +- @override +- final AnalysisError error; +- +- FixContextImpl(this.resourceProvider, this.analysisDriver, this.error); +- +- FixContextImpl.from(FixContext other) +- : resourceProvider = other.resourceProvider, +- analysisDriver = other.analysisDriver, +- error = other.error; +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart +deleted file mode 100644 +index 48771205d9e..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart ++++ /dev/null +@@ -1,3284 +0,0 @@ +-// Copyright (c) 2014, 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 'dart:core'; +- +-import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +-import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/utilities.dart'; +-import 'package:analysis_server/src/services/correction/fix.dart'; +-import 'package:analysis_server/src/services/correction/levenshtein.dart'; +-import 'package:analysis_server/src/services/correction/namespace.dart'; +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/utilities/flutter.dart' as flutter; +-import 'package:analyzer/dart/analysis/session.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/top_level_declaration.dart'; +-import 'package:analyzer/src/dart/ast/token.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/member.dart'; +-import 'package:analyzer/src/dart/element/type.dart'; +-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; +-import 'package:analyzer/src/error/codes.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/error_verifier.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/parser.dart'; +-import 'package:analyzer/src/generated/resolver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/utilities_dart.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- hide AnalysisError, Element, ElementKind; +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; +-import 'package:analyzer_plugin/utilities/fixes/fixes.dart' hide FixContributor; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +-import 'package:path/path.dart'; +- +-/** +- * A predicate is a one-argument function that returns a boolean value. +- */ +-typedef bool ElementPredicate(Element argument); +- +-/** +- * The implementation of [DartFixContext]. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-class DartFixContextImpl extends FixContextImpl implements DartFixContext { +- @override +- final AstProvider astProvider; +- +- @override +- final CompilationUnit unit; +- +- DartFixContextImpl(FixContext fixContext, this.astProvider, this.unit) +- : super.from(fixContext); +- +- GetTopLevelDeclarations get getTopLevelDeclarations => +- analysisDriver.getTopLevelNameDeclarations; +-} +- +-/** +- * A [FixContributor] that provides the default set of fixes. +- */ +-class DefaultFixContributor extends DartFixContributor { +- @override +- Future> internalComputeFixes(DartFixContext context) async { +- try { +- FixProcessor processor = new FixProcessor(context); +- List fixes = await processor.compute(); +- return fixes; +- } on CancelCorrectionException { +- return Fix.EMPTY_LIST; +- } +- } +-} +- +-/** +- * The computer for Dart fixes. +- */ +-class FixProcessor { +- static const int MAX_LEVENSHTEIN_DISTANCE = 3; +- +- ResourceProvider resourceProvider; +- AstProvider astProvider; +- GetTopLevelDeclarations getTopLevelDeclarations; +- CompilationUnit unit; +- AnalysisError error; +- +- /** +- * The analysis driver being used to perform analysis. +- */ +- AnalysisDriver driver; +- +- String file; +- CompilationUnitElement unitElement; +- Source unitSource; +- LibraryElement unitLibraryElement; +- File unitLibraryFile; +- Folder unitLibraryFolder; +- +- final List fixes = []; +- +- CorrectionUtils utils; +- int errorOffset; +- int errorLength; +- int errorEnd; +- SourceRange errorRange; +- AstNode node; +- AstNode coveredNode; +- +- TypeProvider _typeProvider; +- TypeSystem _typeSystem; +- +- FixProcessor(DartFixContext dartContext) { +- resourceProvider = dartContext.resourceProvider; +- astProvider = dartContext.astProvider; +- getTopLevelDeclarations = dartContext.getTopLevelDeclarations; +- driver = dartContext.analysisDriver; +- // unit +- unit = dartContext.unit; +- unitElement = unit.element; +- unitSource = unitElement.source; +- // file +- file = unitSource.fullName; +- // library +- unitLibraryElement = unitElement.library; +- String unitLibraryPath = unitLibraryElement.source.fullName; +- unitLibraryFile = resourceProvider.getFile(unitLibraryPath); +- unitLibraryFolder = unitLibraryFile.parent; +- // error +- error = dartContext.error; +- } +- +- DartType get coreTypeBool => _getCoreType('bool'); +- +- /** +- * Returns the EOL to use for this [CompilationUnit]. +- */ +- String get eol => utils.endOfLine; +- +- /** +- * Return the analysis session to be used to create the change builder. +- */ +- AnalysisSession get session => driver.currentSession; +- +- TypeProvider get typeProvider { +- if (_typeProvider == null) { +- _typeProvider = unitElement.context.typeProvider; +- } +- return _typeProvider; +- } +- +- TypeSystem get typeSystem { +- if (_typeSystem == null) { +- if (driver.analysisOptions.strongMode) { +- _typeSystem = new StrongTypeSystemImpl(typeProvider); +- } else { +- _typeSystem = new TypeSystemImpl(typeProvider); +- } +- } +- return _typeSystem; +- } +- +- Future> compute() async { +- try { +- utils = new CorrectionUtils(unit); +- } catch (e) { +- throw new CancelCorrectionException(exception: e); +- } +- +- errorOffset = error.offset; +- errorLength = error.length; +- errorEnd = errorOffset + errorLength; +- errorRange = new SourceRange(errorOffset, errorLength); +- node = new NodeLocator2(errorOffset).searchWithin(unit); +- coveredNode = +- new NodeLocator2(errorOffset, errorEnd - 1).searchWithin(unit); +- // analyze ErrorCode +- ErrorCode errorCode = error.errorCode; +- if (errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN) { +- await _addFix_boolInsteadOfBoolean(); +- } +- if (errorCode == +- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) { +- await _addFix_replaceWithConstInstanceCreation(); +- } +- if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT || +- errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) { +- await _addFix_addAsync(); +- } +- if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION) { +- if (node is Annotation) { +- Annotation annotation = node; +- Identifier name = annotation.name; +- if (name != null && name.staticElement == null) { +- node = name; +- if (annotation.arguments == null) { +- await _addFix_importLibrary_withTopLevelVariable(); +- } else { +- await _addFix_importLibrary_withType(); +- await _addFix_createClass(); +- await _addFix_undefinedClass_useSimilar(); +- } +- } +- } +- } +- if (errorCode == +- CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT) { +- await _addFix_createConstructorSuperExplicit(); +- } +- if (errorCode == +- CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT) { +- await _addFix_createConstructorSuperImplicit(); +- } +- if (errorCode == +- CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT) { +- await _addFix_createConstructorSuperExplicit(); +- } +- if (errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST) { +- await _addFix_createImportUri(); +- await _addFix_createPartUri(); +- } +- if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) { +- await _addFix_canBeNullAfterNullAware(); +- } +- if (errorCode == HintCode.DEAD_CODE) { +- await _addFix_removeDeadCode(); +- } +- if (errorCode == HintCode.DIVISION_OPTIMIZATION) { +- await _addFix_useEffectiveIntegerDivision(); +- } +- if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) { +- await _addFix_isNotNull(); +- } +- if (errorCode == HintCode.TYPE_CHECK_IS_NULL) { +- await _addFix_isNull(); +- } +- if (errorCode == HintCode.UNDEFINED_GETTER) { +- await _addFix_undefinedClassAccessor_useSimilar(); +- await _addFix_createField(); +- await _addFix_createGetter(); +- } +- if (errorCode == HintCode.UNDEFINED_SETTER) { +- await _addFix_undefinedClassAccessor_useSimilar(); +- await _addFix_createField(); +- } +- if (errorCode == HintCode.UNNECESSARY_CAST) { +- await _addFix_removeUnnecessaryCast(); +- } +- if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) { +- await _addFix_removeUnusedCatchClause(); +- } +- if (errorCode == HintCode.UNUSED_CATCH_STACK) { +- await _addFix_removeUnusedCatchStack(); +- } +- if (errorCode == HintCode.UNUSED_IMPORT) { +- await _addFix_removeUnusedImport(); +- } +- if (errorCode == ParserErrorCode.EXPECTED_TOKEN) { +- await _addFix_insertSemicolon(); +- } +- if (errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS) { +- await _addFix_removeParameters_inGetterDeclaration(); +- } +- if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) { +- await _addFix_replaceVarWithDynamic(); +- } +- if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) { +- await _addFix_makeFieldNotFinal(); +- } +- if (errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER) { +- await _addFix_makeEnclosingClassAbstract(); +- } +- if (errorCode == StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS || +- errorCode == +- StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED) { +- await _addFix_createConstructor_insteadOfSyntheticDefault(); +- await _addFix_addMissingParameter(); +- } +- if (errorCode == HintCode.MISSING_REQUIRED_PARAM || +- errorCode == HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS) { +- await _addFix_addMissingRequiredArgument(); +- } +- if (errorCode == StaticWarningCode.FUNCTION_WITHOUT_CALL) { +- await _addFix_addMissingMethodCall(); +- } +- if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) { +- await _addFix_createConstructor_named(); +- } +- if (errorCode == +- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE || +- errorCode == +- StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO || +- errorCode == +- StaticWarningCode +- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE || +- errorCode == +- StaticWarningCode +- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR || +- errorCode == +- StaticWarningCode +- .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) { +- // make class abstract +- await _addFix_makeEnclosingClassAbstract(); +- await _addFix_createNoSuchMethod(); +- // implement methods +- await _addFix_createMissingOverrides(); +- } +- if (errorCode == CompileTimeErrorCode.UNDEFINED_CLASS || +- errorCode == StaticWarningCode.CAST_TO_NON_TYPE || +- errorCode == StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME || +- errorCode == StaticWarningCode.UNDEFINED_CLASS) { +- await _addFix_importLibrary_withType(); +- await _addFix_createClass(); +- await _addFix_undefinedClass_useSimilar(); +- } +- if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) { +- await _addFix_createConstructor_forUninitializedFinalFields(); +- } +- if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 || +- errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 || +- errorCode == +- StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) { +- await _addFix_updateConstructor_forUninitializedFinalFields(); +- } +- if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) { +- await _addFix_undefinedClassAccessor_useSimilar(); +- await _addFix_createClass(); +- await _addFix_createField(); +- await _addFix_createGetter(); +- await _addFix_createFunction_forFunctionType(); +- await _addFix_importLibrary_withType(); +- await _addFix_importLibrary_withTopLevelVariable(); +- await _addFix_createLocalVariable(); +- } +- if (errorCode == StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR) { +- await _addFix_undefinedMethodWithContructor(); +- } +- if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) { +- await _addFix_illegalAsyncReturnType(); +- } +- if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) { +- await _addFix_useStaticAccess_method(); +- await _addFix_useStaticAccess_property(); +- } +- if (errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT) { +- await _addFix_changeTypeAnnotation(); +- } +- if (errorCode == StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) { +- await _addFix_removeParentheses_inGetterInvocation(); +- } +- if (errorCode == StaticTypeWarningCode.NON_BOOL_CONDITION) { +- await _addFix_nonBoolCondition_addNotNull(); +- } +- if (errorCode == StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT) { +- await _addFix_importLibrary_withType(); +- await _addFix_createClass(); +- } +- if (errorCode == StaticTypeWarningCode.UNDEFINED_FUNCTION) { +- await _addFix_importLibrary_withFunction(); +- await _addFix_undefinedFunction_useSimilar(); +- await _addFix_undefinedFunction_create(); +- } +- if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) { +- await _addFix_undefinedClassAccessor_useSimilar(); +- await _addFix_createField(); +- await _addFix_createGetter(); +- await _addFix_createFunction_forFunctionType(); +- } +- if (errorCode == HintCode.UNDEFINED_METHOD || +- errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) { +- await _addFix_importLibrary_withFunction(); +- await _addFix_undefinedMethod_useSimilar(); +- await _addFix_undefinedMethod_create(); +- await _addFix_undefinedFunction_create(); +- } +- if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) { +- await _addFix_undefinedClassAccessor_useSimilar(); +- await _addFix_createField(); +- } +- if (errorCode == CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER || +- errorCode == StaticWarningCode.UNDEFINED_NAMED_PARAMETER) { +- await _addFix_convertFlutterChild(); +- await _addFix_convertFlutterChildren(); +- } +- if (errorCode == +- CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD) { +- await _addFix_createField_initializingFormal(); +- } +- // lints +- if (errorCode is LintCode) { +- String name = errorCode.name; +- if (name == LintNames.always_require_non_null_named_parameters) { +- await _addFix_addRequiredAnnotation(); +- } +- if (name == LintNames.annotate_overrides) { +- await _addFix_addOverrideAnnotation(); +- } +- if (name == LintNames.avoid_annotating_with_dynamic) { +- await _addFix_removeTypeAnnotation(); +- } +- if (name == LintNames.avoid_empty_else) { +- await _addFix_removeEmptyElse(); +- } +- if (name == LintNames.avoid_init_to_null) { +- await _addFix_removeInitializer(); +- } +- if (name == LintNames.avoid_return_types_on_setters) { +- await _addFix_removeTypeAnnotation(); +- } +- if (name == LintNames.avoid_types_on_closure_parameters) { +- await _addFix_replaceWithIdentifier(); +- } +- if (name == LintNames.await_only_futures) { +- await _addFix_removeAwait(); +- } +- if (name == LintNames.empty_catches) { +- await _addFix_removeEmptyCatch(); +- } +- if (name == LintNames.empty_constructor_bodies) { +- await _addFix_removeEmptyConstructorBody(); +- } +- if (name == LintNames.empty_statements) { +- await _addFix_removeEmptyStatement(); +- } +- if (name == LintNames.prefer_collection_literals) { +- await _addFix_replaceWithLiteral(); +- } +- if (name == LintNames.prefer_conditional_assignment) { +- await _addFix_replaceWithConditionalAssignment(); +- } +- if (name == LintNames.prefer_is_not_empty) { +- await _addFix_isNotEmpty(); +- } +- if (name == LintNames.type_init_formals) { +- await _addFix_removeTypeAnnotation(); +- } +- if (name == LintNames.unnecessary_brace_in_string_interp) { +- await _addFix_removeInterpolationBraces(); +- } +- if (name == LintNames.unnecessary_lambdas) { +- await _addFix_replaceWithTearOff(); +- } +- if (name == LintNames.unnecessary_override) { +- await _addFix_removeMethodDeclaration(); +- } +- if (name == LintNames.unnecessary_this) { +- await _addFix_removeThisExpression(); +- } +- } +- // done +- return fixes; +- } +- +- /** +- * Returns `true` if the `async` proposal was added. +- */ +- Future _addFix_addAsync() async { +- FunctionBody body = node.getAncestor((n) => n is FunctionBody); +- if (body != null && body.keyword == null) { +- TypeProvider typeProvider = await this.typeProvider; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.convertFunctionFromSyncToAsync(body, typeProvider); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_ASYNC); +- } +- } +- +- Future _addFix_addMissingMethodCall() async { +- ClassDeclaration targetClass = node.parent as ClassDeclaration; +- int insertOffset = targetClass.end - 1; +- // prepare environment +- String prefix = utils.getIndent(1); +- String prefix2 = utils.getIndent(2); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(insertOffset, (DartEditBuilder builder) { +- builder.selectHere(); +- builder.write(prefix); +- builder.write('call() {'); +- // TO-DO +- builder.write(eol); +- builder.write(prefix2); +- builder.write('// TODO: implement call'); +- builder.write(eol); +- // close method +- builder.write(prefix); +- builder.write('}'); +- builder.write(eol); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MISSING_METHOD_CALL); +- } +- +- Future _addFix_addMissingParameter() async { +- if (node is ArgumentList && node.parent is MethodInvocation) { +- ArgumentList argumentList = node; +- MethodInvocation invocation = node.parent; +- SimpleIdentifier methodName = invocation.methodName; +- Element targetElement = methodName.bestElement; +- List arguments = argumentList.arguments; +- if (targetElement is ExecutableElement) { +- List parameters = targetElement.parameters; +- int numParameters = parameters.length; +- Iterable requiredParameters = parameters +- .takeWhile((p) => p.parameterKind == ParameterKind.REQUIRED); +- Iterable optionalParameters = parameters +- .skipWhile((p) => p.parameterKind == ParameterKind.REQUIRED); +- // prepare the argument to add a new parameter for +- int numRequired = requiredParameters.length; +- if (numRequired >= arguments.length) { +- return; +- } +- Expression argument = arguments[numRequired]; +- // prepare target +- int targetOffset; +- if (numRequired != 0) { +- SimpleIdentifier lastName = await astProvider +- .getParsedNameForElement(requiredParameters.last); +- if (lastName != null) { +- targetOffset = lastName.end; +- } else { +- return; +- } +- } else { +- SimpleIdentifier targetName = +- await astProvider.getParsedNameForElement(targetElement); +- AstNode targetDeclaration = targetName?.parent; +- if (targetDeclaration is FunctionDeclaration) { +- FunctionExpression function = targetDeclaration.functionExpression; +- Token paren = function.parameters?.leftParenthesis; +- if (paren == null) { +- return; +- } +- targetOffset = paren.end; +- } else if (targetDeclaration is MethodDeclaration) { +- Token paren = targetDeclaration.parameters?.leftParenthesis; +- if (paren == null) { +- return; +- } +- targetOffset = paren.end; +- } else { +- return; +- } +- } +- Source targetSource = targetElement.source; +- String targetFile = targetSource.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, +- (DartFileEditBuilder builder) { +- builder.addInsertion(targetOffset, (DartEditBuilder builder) { +- if (numRequired != 0) { +- builder.write(', '); +- } +- builder.writeParameterMatchingArgument( +- argument, numRequired, new Set()); +- if (numRequired != numParameters) { +- builder.write(', '); +- } +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.ADD_MISSING_PARAMETER_REQUIRED); +- if (optionalParameters.isEmpty) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, +- (DartFileEditBuilder builder) { +- builder.addInsertion(targetOffset, (DartEditBuilder builder) { +- if (numRequired != 0) { +- builder.write(', '); +- } +- builder.write('['); +- builder.writeParameterMatchingArgument( +- argument, numRequired, new Set()); +- builder.write(']'); +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL); +- } +- } +- } +- } +- +- Future _addFix_addMissingRequiredArgument() async { +- Element targetElement; +- ArgumentList argumentList; +- +- if (node is SimpleIdentifier) { +- AstNode invocation = node.parent; +- if (invocation is MethodInvocation) { +- targetElement = invocation.methodName.bestElement; +- argumentList = invocation.argumentList; +- } else { +- AstNode ancestor = +- invocation.getAncestor((p) => p is InstanceCreationExpression); +- if (ancestor is InstanceCreationExpression) { +- targetElement = ancestor.staticElement; +- argumentList = ancestor.argumentList; +- } +- } +- } +- +- if (targetElement is ExecutableElement) { +- // Format: "Missing required argument 'foo" +- List parts = error.message.split("'"); +- if (parts.length < 2) { +- return; +- } +- +- // add proposal +- String paramName = parts[1]; +- final List args = argumentList.arguments; +- int offset = +- args.isEmpty ? argumentList.leftParenthesis.end : args.last.end; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(offset, (DartEditBuilder builder) { +- if (args.isNotEmpty) { +- builder.write(', '); +- } +- List parameters = +- (targetElement as ExecutableElement).parameters; +- ParameterElement element = parameters +- .firstWhere((p) => p.name == paramName, orElse: () => null); +- String defaultValue = getDefaultStringParameterValue(element); +- builder.write('$paramName: $defaultValue'); +- // Insert a trailing comma after Flutter instance creation params. +- InstanceCreationExpression newExpr = +- flutter.identifyNewExpression(node); +- if (newExpr != null && flutter.isWidgetCreation(newExpr)) { +- builder.write(','); +- } +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- args: [paramName]); +- } +- } +- +- Future _addFix_addOverrideAnnotation() async { +- ClassMember member = node.getAncestor((n) => n is ClassMember); +- if (member == null) { +- return; +- } +- +- //TODO(pq): migrate annotation edit building to change_builder +- +- // Handle doc comments. +- Token token = member.beginToken; +- if (token is CommentToken) { +- token = (token as CommentToken).parent; +- } +- +- Position exitPosition = new Position(file, token.offset - 1); +- String indent = utils.getIndent(1); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.startLength(token, 0), '@override$eol$indent'); +- }); +- changeBuilder.setSelection(exitPosition); +- _addFixFromBuilder(changeBuilder, DartFixKind.LINT_ADD_OVERRIDE); +- } +- +- Future _addFix_addRequiredAnnotation() async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(node.parent.offset, '@required '); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.LINT_ADD_REQUIRED); +- } +- +- Future _addFix_boolInsteadOfBoolean() async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.error(error), 'bool'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_BOOLEAN_WITH_BOOL); +- } +- +- Future _addFix_canBeNullAfterNullAware() async { +- AstNode node = coveredNode; +- if (node is Expression) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- AstNode parent = node.parent; +- while (parent != null) { +- if (parent is MethodInvocation && parent.target == node) { +- builder.addSimpleReplacement(range.token(parent.operator), '?.'); +- } else if (parent is PropertyAccess && parent.target == node) { +- builder.addSimpleReplacement(range.token(parent.operator), '?.'); +- } else { +- break; +- } +- node = parent; +- parent = node.parent; +- } +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_NULL_AWARE); +- } +- } +- +- Future _addFix_changeTypeAnnotation() async { +- AstNode declaration = coveredNode.parent; +- if (declaration is VariableDeclaration && +- declaration.initializer == coveredNode) { +- AstNode variableList = declaration.parent; +- if (variableList is VariableDeclarationList && +- variableList.variables.length == 1) { +- TypeAnnotation typeNode = variableList.type; +- if (typeNode != null) { +- Expression initializer = coveredNode; +- DartType newType = initializer.bestType; +- if (newType is InterfaceType || newType is FunctionType) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, +- (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(typeNode), +- (DartEditBuilder builder) { +- builder.writeType(newType); +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.CHANGE_TYPE_ANNOTATION, args: [ +- resolutionMap.typeForTypeName(typeNode), +- newType.displayName +- ]); +- } +- } +- } +- } +- } +- +- Future _addFix_convertFlutterChild() async { +- NamedExpression namedExp = flutter.findNamedExpression(node, 'child'); +- if (namedExp == null) { +- return; +- } +- InstanceCreationExpression childArg = +- flutter.getChildWidget(namedExp, false); +- if (childArg != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- flutter.convertChildToChildren2( +- builder, +- childArg, +- namedExp, +- eol, +- utils.getNodeText, +- utils.getLinePrefix, +- utils.getIndent, +- utils.getText, +- range.node); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD); +- return; +- } +- ListLiteral listArg = flutter.getChildList(namedExp); +- if (listArg != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(namedExp.offset + 'child'.length, 'ren'); +- if (listArg.typeArguments == null) { +- builder.addSimpleInsertion(listArg.offset, ''); +- } +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_FLUTTER_CHILD); +- } +- } +- +- Future _addFix_convertFlutterChildren() async { +- // TODO(messick) Implement _addFix_convertFlutterChildren() +- } +- +- Future _addFix_createClass() async { +- Element prefixElement = null; +- String name = null; +- SimpleIdentifier nameNode; +- if (node is SimpleIdentifier) { +- AstNode parent = node.parent; +- if (parent is PrefixedIdentifier) { +- PrefixedIdentifier prefixedIdentifier = parent; +- prefixElement = prefixedIdentifier.prefix.staticElement; +- if (prefixElement == null) { +- return; +- } +- parent = prefixedIdentifier.parent; +- nameNode = prefixedIdentifier.identifier; +- name = prefixedIdentifier.identifier.name; +- } else { +- nameNode = node; +- name = nameNode.name; +- } +- if (!_mayBeTypeIdentifier(nameNode)) { +- return; +- } +- } else { +- return; +- } +- // prepare environment +- Element targetUnit; +- String prefix = ''; +- String suffix = ''; +- int offset = -1; +- String filePath; +- if (prefixElement == null) { +- targetUnit = unitElement; +- CompilationUnitMember enclosingMember = +- node.getAncestor((node) => node.parent is CompilationUnit); +- if (enclosingMember == null) { +- return; +- } +- offset = enclosingMember.end; +- filePath = file; +- prefix = '$eol$eol'; +- } else { +- for (ImportElement import in unitLibraryElement.imports) { +- if (prefixElement is PrefixElement && import.prefix == prefixElement) { +- LibraryElement library = import.importedLibrary; +- if (library != null) { +- targetUnit = library.definingCompilationUnit; +- Source targetSource = targetUnit.source; +- try { +- offset = targetSource.contents.data.length; +- filePath = targetSource.fullName; +- prefix = '$eol'; +- suffix = '$eol'; +- } on FileSystemException { +- // If we can't read the file to get the offset, then we can't +- // create a fix. +- } +- break; +- } +- } +- } +- } +- if (offset < 0) { +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(filePath, (DartFileEditBuilder builder) { +- builder.addInsertion(offset, (DartEditBuilder builder) { +- builder.write(prefix); +- builder.writeClassDeclaration(name, nameGroupName: 'NAME'); +- builder.write(suffix); +- }); +- if (prefixElement == null) { +- builder.addLinkedPosition(range.node(node), 'NAME'); +- } +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CLASS, args: [name]); +- } +- +- /** +- * Here we handle cases when there are no constructors in a class, and the +- * class has uninitialized final fields. +- */ +- Future _addFix_createConstructor_forUninitializedFinalFields() async { +- if (node is! SimpleIdentifier || node.parent is! VariableDeclaration) { +- return; +- } +- ClassDeclaration classDeclaration = +- node.getAncestor((node) => node is ClassDeclaration); +- if (classDeclaration == null) { +- return; +- } +- // prepare names of uninitialized final fields +- List fieldNames = []; +- for (ClassMember member in classDeclaration.members) { +- if (member is FieldDeclaration) { +- VariableDeclarationList variableList = member.fields; +- if (variableList.isFinal) { +- fieldNames.addAll(variableList.variables +- .where((v) => v.initializer == null) +- .map((v) => v.name.name)); +- } +- } +- } +- // prepare location for a new constructor +- ClassMemberLocation targetLocation = +- utils.prepareNewConstructorLocation(classDeclaration); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- builder.write(targetLocation.prefix); +- builder.writeConstructorDeclaration(classDeclaration.name.name, +- fieldNames: fieldNames); +- builder.write(targetLocation.suffix); +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS); +- } +- +- Future _addFix_createConstructor_insteadOfSyntheticDefault() async { +- if (node is! ArgumentList) { +- return; +- } +- if (node.parent is! InstanceCreationExpression) { +- return; +- } +- InstanceCreationExpression instanceCreation = node.parent; +- ConstructorName constructorName = instanceCreation.constructorName; +- // should be synthetic default constructor +- ConstructorElement constructorElement = constructorName.staticElement; +- if (constructorElement == null || +- !constructorElement.isDefaultConstructor || +- !constructorElement.isSynthetic) { +- return; +- } +- // prepare target +- if (constructorElement.enclosingElement is! ClassElement) { +- return; +- } +- ClassElement targetElement = constructorElement.enclosingElement; +- // prepare location for a new constructor +- AstNode targetTypeNode = getParsedClassElementNode(targetElement); +- if (targetTypeNode is! ClassDeclaration) { +- return; +- } +- ClassMemberLocation targetLocation = +- utils.prepareNewConstructorLocation(targetTypeNode); +- Source targetSource = targetElement.source; +- String targetFile = targetSource.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) { +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- builder.write(targetLocation.prefix); +- builder.writeConstructorDeclaration(targetElement.name, +- argumentList: instanceCreation.argumentList); +- builder.write(targetLocation.suffix); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CONSTRUCTOR, +- args: [constructorName]); +- } +- +- Future _addFix_createConstructor_named() async { +- SimpleIdentifier name = null; +- ConstructorName constructorName = null; +- InstanceCreationExpression instanceCreation = null; +- if (node is SimpleIdentifier) { +- // name +- name = node as SimpleIdentifier; +- if (name.parent is ConstructorName) { +- constructorName = name.parent as ConstructorName; +- if (constructorName.name == name) { +- // Type.name +- if (constructorName.parent is InstanceCreationExpression) { +- instanceCreation = +- constructorName.parent as InstanceCreationExpression; +- // new Type.name() +- if (instanceCreation.constructorName != constructorName) { +- return; +- } +- } +- } +- } +- } +- // do we have enough information? +- if (instanceCreation == null) { +- return; +- } +- // prepare target interface type +- DartType targetType = constructorName.type.type; +- if (targetType is! InterfaceType) { +- return; +- } +- // prepare location for a new constructor +- ClassElement targetElement = targetType.element as ClassElement; +- AstNode targetTypeNode = getParsedClassElementNode(targetElement); +- if (targetTypeNode is! ClassDeclaration) { +- return; +- } +- ClassMemberLocation targetLocation = +- utils.prepareNewConstructorLocation(targetTypeNode); +- String targetFile = targetElement.source.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- builder.write(targetLocation.prefix); +- builder.writeConstructorDeclaration(targetElement.name, +- argumentList: instanceCreation.argumentList, +- constructorName: name, +- constructorNameGroupName: 'NAME'); +- builder.write(targetLocation.suffix); +- }); +- if (targetFile == file) { +- builder.addLinkedPosition(range.node(name), 'NAME'); +- } +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CONSTRUCTOR, +- args: [constructorName]); +- } +- +- Future _addFix_createConstructorSuperExplicit() async { +- if (node.parent is! ConstructorDeclaration || +- node.parent.parent is! ClassDeclaration) { +- return; +- } +- ConstructorDeclaration targetConstructor = +- node.parent as ConstructorDeclaration; +- ClassDeclaration targetClassNode = +- targetConstructor.parent as ClassDeclaration; +- ClassElement targetClassElement = targetClassNode.element; +- InterfaceType superType = targetClassElement.supertype; +- // add proposals for all super constructors +- for (ConstructorElement superConstructor in superType.constructors) { +- String constructorName = superConstructor.name; +- // skip private +- if (Identifier.isPrivateName(constructorName)) { +- continue; +- } +- List initializers = +- targetConstructor.initializers; +- int insertOffset; +- String prefix; +- if (initializers.isEmpty) { +- insertOffset = targetConstructor.parameters.end; +- prefix = ' : '; +- } else { +- ConstructorInitializer lastInitializer = +- initializers[initializers.length - 1]; +- insertOffset = lastInitializer.end; +- prefix = ', '; +- } +- String proposalName = _getConstructorProposalName(superConstructor); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(insertOffset, (DartEditBuilder builder) { +- builder.write(prefix); +- // add super constructor name +- builder.write('super'); +- if (!isEmpty(constructorName)) { +- builder.write('.'); +- builder.addSimpleLinkedEdit('NAME', constructorName); +- } +- // add arguments +- builder.write('('); +- bool firstParameter = true; +- for (ParameterElement parameter in superConstructor.parameters) { +- // skip non-required parameters +- if (parameter.parameterKind != ParameterKind.REQUIRED) { +- break; +- } +- // comma +- if (firstParameter) { +- firstParameter = false; +- } else { +- builder.write(', '); +- } +- // default value +- builder.addSimpleLinkedEdit( +- parameter.name, getDefaultValueCode(parameter.type)); +- } +- builder.write(')'); +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, +- args: [proposalName]); +- } +- } +- +- Future _addFix_createConstructorSuperImplicit() async { +- ClassDeclaration targetClassNode = node.parent as ClassDeclaration; +- ClassElement targetClassElement = targetClassNode.element; +- InterfaceType superType = targetClassElement.supertype; +- String targetClassName = targetClassElement.name; +- // add proposals for all super constructors +- for (ConstructorElement superConstructor in superType.constructors) { +- superConstructor = ConstructorMember.from(superConstructor, superType); +- String constructorName = superConstructor.name; +- // skip private +- if (Identifier.isPrivateName(constructorName)) { +- continue; +- } +- // prepare parameters and arguments +- Iterable requiredParameters = +- superConstructor.parameters.where( +- (parameter) => parameter.parameterKind == ParameterKind.REQUIRED); +- // add proposal +- ClassMemberLocation targetLocation = +- utils.prepareNewConstructorLocation(targetClassNode); +- String proposalName = _getConstructorProposalName(superConstructor); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- void writeParameters(bool includeType) { +- bool firstParameter = true; +- for (ParameterElement parameter in requiredParameters) { +- if (firstParameter) { +- firstParameter = false; +- } else { +- builder.write(', '); +- } +- String parameterName = parameter.displayName; +- if (parameterName.length > 1 && parameterName.startsWith('_')) { +- parameterName = parameterName.substring(1); +- } +- if (includeType && builder.writeType(parameter.type)) { +- builder.write(' '); +- } +- builder.write(parameterName); +- } +- } +- +- builder.write(targetLocation.prefix); +- builder.write(targetClassName); +- if (!constructorName.isEmpty) { +- builder.write('.'); +- builder.addSimpleLinkedEdit('NAME', constructorName); +- } +- builder.write('('); +- writeParameters(true); +- builder.write(') : super'); +- if (!constructorName.isEmpty) { +- builder.write('.'); +- builder.addSimpleLinkedEdit('NAME', constructorName); +- } +- builder.write('('); +- writeParameters(false); +- builder.write(');'); +- builder.write(targetLocation.suffix); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_SUPER, +- args: [proposalName]); +- } +- } +- +- Future _addFix_createField() async { +- if (node is! SimpleIdentifier) { +- return; +- } +- SimpleIdentifier nameNode = node; +- String name = nameNode.name; +- // prepare target Expression +- Expression target; +- { +- AstNode nameParent = nameNode.parent; +- if (nameParent is PrefixedIdentifier) { +- target = nameParent.prefix; +- } else if (nameParent is PropertyAccess) { +- target = nameParent.realTarget; +- } +- } +- // prepare target ClassElement +- bool staticModifier = false; +- ClassElement targetClassElement; +- if (target != null) { +- // prepare target interface type +- DartType targetType = target.bestType; +- if (targetType is! InterfaceType) { +- return; +- } +- targetClassElement = targetType.element; +- // maybe static +- if (target is Identifier) { +- Identifier targetIdentifier = target; +- Element targetElement = targetIdentifier.bestElement; +- if (targetElement == null) { +- return; +- } +- staticModifier = targetElement.kind == ElementKind.CLASS; +- } +- } else { +- targetClassElement = getEnclosingClassElement(node); +- if (targetClassElement == null) { +- return; +- } +- staticModifier = _inStaticContext(); +- } +- if (targetClassElement.librarySource.isInSystemLibrary) { +- return; +- } +- utils.targetClassElement = targetClassElement; +- // prepare target ClassDeclaration +- AstNode targetTypeNode = getParsedClassElementNode(targetClassElement); +- if (targetTypeNode is! ClassDeclaration) { +- return; +- } +- ClassDeclaration targetClassNode = targetTypeNode; +- // prepare location +- ClassMemberLocation targetLocation = +- _getUtilsFor(targetClassNode).prepareNewFieldLocation(targetClassNode); +- // build field source +- Source targetSource = targetClassElement.source; +- String targetFile = targetSource.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) { +- Expression fieldTypeNode = climbPropertyAccess(nameNode); +- DartType fieldType = _inferUndefinedExpressionType(fieldTypeNode); +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- builder.write(targetLocation.prefix); +- builder.writeFieldDeclaration(name, +- isStatic: staticModifier, +- nameGroupName: 'NAME', +- type: fieldType, +- typeGroupName: 'TYPE'); +- builder.write(targetLocation.suffix); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FIELD, args: [name]); +- } +- +- Future _addFix_createField_initializingFormal() async { +- // +- // Ensure that we are in an initializing formal parameter. +- // +- FieldFormalParameter parameter = +- node.getAncestor((node) => node is FieldFormalParameter); +- if (parameter == null) { +- return; +- } +- ClassDeclaration targetClassNode = +- parameter.getAncestor((node) => node is ClassDeclaration); +- if (targetClassNode == null) { +- return; +- } +- SimpleIdentifier nameNode = parameter.identifier; +- String name = nameNode.name; +- ClassMemberLocation targetLocation = +- utils.prepareNewFieldLocation(targetClassNode); +- // +- // Add proposal. +- // +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- DartType fieldType = parameter.type?.type; +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- builder.write(targetLocation.prefix); +- builder.writeFieldDeclaration(name, +- nameGroupName: 'NAME', type: fieldType, typeGroupName: 'TYPE'); +- builder.write(targetLocation.suffix); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FIELD, args: [name]); +- } +- +- Future _addFix_createFunction_forFunctionType() async { +- if (node is SimpleIdentifier) { +- SimpleIdentifier nameNode = node as SimpleIdentifier; +- // prepare argument expression (to get parameter) +- ClassElement targetElement; +- Expression argument; +- { +- Expression target = getQualifiedPropertyTarget(node); +- if (target != null) { +- DartType targetType = target.bestType; +- if (targetType != null && targetType.element is ClassElement) { +- targetElement = targetType.element as ClassElement; +- argument = target.parent as Expression; +- } else { +- return; +- } +- } else { +- ClassDeclaration enclosingClass = +- node.getAncestor((node) => node is ClassDeclaration); +- targetElement = enclosingClass?.element; +- argument = nameNode; +- } +- } +- argument = stepUpNamedExpression(argument); +- // should be argument of some invocation +- ParameterElement parameterElement = argument.bestParameterElement; +- if (parameterElement == null) { +- return; +- } +- // should be parameter of function type +- DartType parameterType = parameterElement.type; +- if (parameterType is InterfaceType && parameterType.isDartCoreFunction) { +- ExecutableElement element = new MethodElementImpl('', -1); +- parameterType = new FunctionTypeImpl(element); +- } +- if (parameterType is! FunctionType) { +- return; +- } +- FunctionType functionType = parameterType as FunctionType; +- // add proposal +- if (targetElement != null) { +- await _addProposal_createFunction_method(targetElement, functionType); +- } else { +- await _addProposal_createFunction_function(functionType); +- } +- } +- } +- +- Future _addFix_createGetter() async { +- if (node is! SimpleIdentifier) { +- return; +- } +- SimpleIdentifier nameNode = node; +- String name = nameNode.name; +- if (!nameNode.inGetterContext()) { +- return; +- } +- // prepare target Expression +- Expression target; +- { +- AstNode nameParent = nameNode.parent; +- if (nameParent is PrefixedIdentifier) { +- target = nameParent.prefix; +- } else if (nameParent is PropertyAccess) { +- target = nameParent.realTarget; +- } +- } +- // prepare target ClassElement +- bool staticModifier = false; +- ClassElement targetClassElement; +- if (target != null) { +- // prepare target interface type +- DartType targetType = target.bestType; +- if (targetType is! InterfaceType) { +- return; +- } +- targetClassElement = targetType.element; +- // maybe static +- if (target is Identifier) { +- Identifier targetIdentifier = target; +- Element targetElement = targetIdentifier.bestElement; +- staticModifier = targetElement.kind == ElementKind.CLASS; +- } +- } else { +- targetClassElement = getEnclosingClassElement(node); +- if (targetClassElement == null) { +- return; +- } +- staticModifier = _inStaticContext(); +- } +- if (targetClassElement.librarySource.isInSystemLibrary) { +- return; +- } +- utils.targetClassElement = targetClassElement; +- // prepare target ClassDeclaration +- AstNode targetTypeNode = getParsedClassElementNode(targetClassElement); +- if (targetTypeNode is! ClassDeclaration) { +- return; +- } +- ClassDeclaration targetClassNode = targetTypeNode; +- // prepare location +- ClassMemberLocation targetLocation = +- _getUtilsFor(targetClassNode).prepareNewGetterLocation(targetClassNode); +- // build method source +- Source targetSource = targetClassElement.source; +- String targetFile = targetSource.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) { +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- Expression fieldTypeNode = climbPropertyAccess(nameNode); +- DartType fieldType = _inferUndefinedExpressionType(fieldTypeNode); +- builder.write(targetLocation.prefix); +- builder.writeGetterDeclaration(name, +- isStatic: staticModifier, +- nameGroupName: 'NAME', +- returnType: fieldType, +- returnTypeGroupName: 'TYPE'); +- builder.write(targetLocation.suffix); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_GETTER, args: [name]); +- } +- +- Future _addFix_createImportUri() async { +- // TODO(brianwilkerson) Generalize this to allow other valid string literals. +- // TODO(brianwilkerson) Support the case where the node's parent is a Configuration. +- if (node is SimpleStringLiteral && node.parent is ImportDirective) { +- ImportDirective importDirective = node.parent; +- Source source = importDirective.uriSource; +- if (source != null) { +- String file = source.fullName; +- if (isAbsolute(file) && AnalysisEngine.isDartFileName(file)) { +- String libName = _computeLibraryName(file); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(source.fullName, +- (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(0, 'library $libName;$eol$eol'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE, +- args: [source.shortName]); +- } +- } +- } +- } +- +- Future _addFix_createLocalVariable() async { +- if (node is! SimpleIdentifier) { +- return; +- } +- SimpleIdentifier nameNode = node; +- String name = nameNode.name; +- // if variable is assigned, convert assignment into declaration +- if (node.parent is AssignmentExpression) { +- AssignmentExpression assignment = node.parent; +- if (assignment.leftHandSide == node && +- assignment.operator.type == TokenType.EQ && +- assignment.parent is ExpressionStatement) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(node.offset, 'var '); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_LOCAL_VARIABLE, +- args: [name]); +- return; +- } +- } +- // prepare target Statement +- Statement target = node.getAncestor((x) => x is Statement); +- if (target == null) { +- return; +- } +- String prefix = utils.getNodePrefix(target); +- // compute type +- DartType type = _inferUndefinedExpressionType(node); +- if (!(type == null || +- type is InterfaceType || +- type is FunctionType && +- type.element != null && +- !type.element.isSynthetic)) { +- return; +- } +- // build variable declaration source +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(target.offset, (DartEditBuilder builder) { +- builder.writeLocalVariableDeclaration(name, +- nameGroupName: 'NAME', type: type, typeGroupName: 'TYPE'); +- builder.write(eol); +- builder.write(prefix); +- }); +- builder.addLinkedPosition(range.node(node), 'NAME'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_LOCAL_VARIABLE, +- args: [name]); +- } +- +- Future _addFix_createMissingOverrides() async { +- // prepare target +- ClassDeclaration targetClass = node.parent as ClassDeclaration; +- ClassElement targetClassElement = targetClass.element; +- utils.targetClassElement = targetClassElement; +- List elements = ErrorVerifier +- .computeMissingOverrides( +- driver.analysisOptions.strongMode, +- typeProvider, +- typeSystem, +- new InheritanceManager(unitLibraryElement), +- targetClassElement) +- .toList(); +- // sort by name, getters before setters +- elements.sort((Element a, Element b) { +- int names = compareStrings(a.displayName, b.displayName); +- if (names != 0) { +- return names; +- } +- if (a.kind == ElementKind.GETTER) { +- return -1; +- } +- return 1; +- }); +- int numElements = elements.length; +- +- ClassMemberLocation location = +- utils.prepareNewClassMemberLocation(targetClass, (_) => true); +- +- String prefix = utils.getIndent(1); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(location.offset, (DartEditBuilder builder) { +- // TODO(brianwilkerson) Compare with builder.writeOverrideOfInheritedMember +- // The builder method doesn't merge getter/setter pairs into fields. +- +- // Separator management. +- int numOfMembersWritten = 0; +- void addSeparatorBetweenDeclarations() { +- if (numOfMembersWritten == 0) { +- builder.write(location.prefix); +- } else { +- builder.write(eol); // after the previous member +- builder.write(eol); // empty line separator +- builder.write(prefix); +- } +- numOfMembersWritten++; +- } +- +- // merge getter/setter pairs into fields +- for (int i = 0; i < elements.length; i++) { +- ExecutableElement element = elements[i]; +- if (element.kind == ElementKind.GETTER && i + 1 < elements.length) { +- ExecutableElement nextElement = elements[i + 1]; +- if (nextElement.kind == ElementKind.SETTER) { +- // remove this and the next elements, adjust iterator +- elements.removeAt(i + 1); +- elements.removeAt(i); +- i--; +- numElements--; +- // separator +- addSeparatorBetweenDeclarations(); +- // @override +- builder.write('@override'); +- builder.write(eol); +- // add field +- builder.write(prefix); +- builder.writeType(element.type.returnType, required: true); +- builder.write(' '); +- builder.write(element.name); +- builder.write(';'); +- } +- } +- } +- // add elements +- for (ExecutableElement element in elements) { +- addSeparatorBetweenDeclarations(); +- _addFix_createMissingOverridesForBuilder( +- builder, targetClass, element); +- } +- builder.write(location.suffix); +- }); +- }); +- changeBuilder.setSelection(new Position(file, location.offset)); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MISSING_OVERRIDES, +- args: [numElements]); +- } +- +- void _addFix_createMissingOverridesForBuilder(DartEditBuilder builder, +- ClassDeclaration targetClass, ExecutableElement element) { +- utils.targetExecutableElement = element; +- // prepare environment +- String prefix = utils.getIndent(1); +- String prefix2 = utils.getIndent(2); +- // may be property +- ElementKind elementKind = element.kind; +- bool isGetter = elementKind == ElementKind.GETTER; +- bool isSetter = elementKind == ElementKind.SETTER; +- bool isMethod = elementKind == ElementKind.METHOD; +- bool isOperator = isMethod && (element as MethodElement).isOperator; +- if (isGetter) { +- builder.write('// TODO: implement ${element.displayName}'); +- builder.write(eol); +- builder.write(prefix); +- } +- // @override +- builder.write('@override'); +- builder.write(eol); +- builder.write(prefix); +- // return type +- if (!isSetter) { +- if (builder.writeType(element.type.returnType, +- methodBeingCopied: element)) { +- builder.write(' '); +- } +- } +- // keyword +- if (isGetter) { +- builder.write('get '); +- } else if (isSetter) { +- builder.write('set '); +- } else if (isOperator) { +- builder.write('operator '); +- } +- // name +- builder.write(element.displayName); +- builder.writeTypeParameters(element.typeParameters); +- // parameters + body +- if (isGetter) { +- builder.write(' => null;'); +- } else { +- List parameters = element.parameters; +- builder.writeParameters(parameters, methodBeingCopied: element); +- builder.write(' {'); +- // TO-DO +- builder.write(eol); +- builder.write(prefix2); +- builder.write('// TODO: implement ${element.displayName}'); +- builder.write(eol); +- // close method +- builder.write(prefix); +- builder.write('}'); +- } +- utils.targetExecutableElement = null; +- } +- +- Future _addFix_createNoSuchMethod() async { +- ClassDeclaration targetClass = node.parent as ClassDeclaration; +- // prepare environment +- String prefix = utils.getIndent(1); +- int insertOffset = targetClass.end - 1; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(insertOffset, (DartEditBuilder builder) { +- builder.selectHere(); +- // insert empty line before existing member +- if (!targetClass.members.isEmpty) { +- builder.write(eol); +- } +- // append method +- builder.write(prefix); +- builder.write( +- 'noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);'); +- builder.write(eol); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_NO_SUCH_METHOD); +- } +- +- Future _addFix_createPartUri() async { +- // TODO(brianwilkerson) Generalize this to allow other valid string literals. +- if (node is SimpleStringLiteral && node.parent is PartDirective) { +- PartDirective partDirective = node.parent; +- Source source = partDirective.uriSource; +- if (source != null) { +- String libName = unitLibraryElement.name; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(source.fullName, +- (DartFileEditBuilder builder) { +- // TODO(brianwilkerson) Consider using the URI rather than name +- builder.addSimpleInsertion(0, 'part of $libName;$eol$eol'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE, +- args: [source.shortName]); +- } +- } +- } +- +- Future _addFix_illegalAsyncReturnType() async { +- // prepare the existing type +- TypeAnnotation typeName = node.getAncestor((n) => n is TypeAnnotation); +- TypeProvider typeProvider = this.typeProvider; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.replaceTypeWithFuture(typeName, typeProvider); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE); +- } +- +- Future _addFix_importLibrary(FixKind kind, Source library) async { +- String libraryUri = getLibrarySourceUri(unitLibraryElement, library); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.importLibraries([library]); +- }); +- _addFixFromBuilder(changeBuilder, kind, args: [libraryUri]); +- } +- +- Future _addFix_importLibrary_withElement(String name, +- List elementKinds, TopLevelDeclarationKind kind2) async { +- // ignore if private +- if (name.startsWith('_')) { +- return; +- } +- // may be there is an existing import, +- // but it is with prefix and we don't use this prefix +- Set alreadyImportedWithPrefix = new Set(); +- for (ImportElement imp in unitLibraryElement.imports) { +- // prepare element +- LibraryElement libraryElement = imp.importedLibrary; +- Element element = getExportedElement(libraryElement, name); +- if (element == null) { +- continue; +- } +- if (element is PropertyAccessorElement) { +- element = (element as PropertyAccessorElement).variable; +- } +- if (!elementKinds.contains(element.kind)) { +- continue; +- } +- // may be apply prefix +- PrefixElement prefix = imp.prefix; +- if (prefix != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.startLength(node, 0), '${prefix.displayName}.'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.IMPORT_LIBRARY_PREFIX, +- args: [libraryElement.displayName, prefix.displayName]); +- continue; +- } +- // may be update "show" directive +- List combinators = imp.combinators; +- if (combinators.length == 1 && combinators[0] is ShowElementCombinator) { +- ShowElementCombinator showCombinator = +- combinators[0] as ShowElementCombinator; +- // prepare new set of names to show +- Set showNames = new SplayTreeSet(); +- showNames.addAll(showCombinator.shownNames); +- showNames.add(name); +- // prepare library name - unit name or 'dart:name' for SDK library +- String libraryName = libraryElement.definingCompilationUnit.displayName; +- if (libraryElement.isInSdk) { +- libraryName = libraryElement.source.shortName; +- } +- // don't add this library again +- alreadyImportedWithPrefix.add(libraryElement.source); +- // update library +- String newShowCode = 'show ${showNames.join(', ')}'; +- int offset = showCombinator.offset; +- int length = showCombinator.end - offset; +- String libraryFile = unitLibraryElement.source.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(libraryFile, +- (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- new SourceRange(offset, length), newShowCode); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.IMPORT_LIBRARY_SHOW, +- args: [libraryName]); +- } +- } +- // Find new top-level declarations. +- { +- List declarations = +- await getTopLevelDeclarations(name); +- for (TopLevelDeclarationInSource declaration in declarations) { +- // Check the kind. +- if (declaration.declaration.kind != kind2) { +- continue; +- } +- // Check the source. +- Source librarySource = declaration.source; +- if (alreadyImportedWithPrefix.contains(librarySource)) { +- continue; +- } +- if (!_isSourceVisibleToLibrary(librarySource)) { +- continue; +- } +- // Compute the fix kind. +- FixKind fixKind; +- if (librarySource.isInSystemLibrary) { +- fixKind = DartFixKind.IMPORT_LIBRARY_SDK; +- } else if (_isLibSrcPath(librarySource.fullName)) { +- // Bad: non-API. +- fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3; +- } else if (declaration.isExported) { +- // Ugly: exports. +- fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2; +- } else { +- // Good: direct declaration. +- fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1; +- } +- // Add the fix. +- await _addFix_importLibrary(fixKind, librarySource); +- } +- } +- } +- +- Future _addFix_importLibrary_withFunction() async { +- if (node is SimpleIdentifier && node.parent is MethodInvocation) { +- MethodInvocation invocation = node.parent as MethodInvocation; +- if (invocation.realTarget == null && invocation.methodName == node) { +- String name = (node as SimpleIdentifier).name; +- await _addFix_importLibrary_withElement(name, +- const [ElementKind.FUNCTION], TopLevelDeclarationKind.function); +- } +- } +- } +- +- Future _addFix_importLibrary_withTopLevelVariable() async { +- if (node is SimpleIdentifier) { +- String name = (node as SimpleIdentifier).name; +- await _addFix_importLibrary_withElement( +- name, +- const [ElementKind.TOP_LEVEL_VARIABLE], +- TopLevelDeclarationKind.variable); +- } +- } +- +- Future _addFix_importLibrary_withType() async { +- if (_mayBeTypeIdentifier(node)) { +- String typeName = (node as SimpleIdentifier).name; +- await _addFix_importLibrary_withElement( +- typeName, +- const [ElementKind.CLASS, ElementKind.FUNCTION_TYPE_ALIAS], +- TopLevelDeclarationKind.type); +- } +- } +- +- Future _addFix_insertSemicolon() async { +- if (error.message.contains("';'")) { +- if (_isAwaitNode()) { +- return; +- } +- int insertOffset = error.offset + error.length; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(insertOffset, ';'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.INSERT_SEMICOLON); +- } +- } +- +- Future _addFix_isNotEmpty() async { +- if (node is! PrefixExpression) { +- return; +- } +- PrefixExpression prefixExpression = node; +- Token negation = prefixExpression.operator; +- if (negation.type != TokenType.BANG) { +- return; +- } +- SimpleIdentifier identifier; +- Expression expression = prefixExpression.operand; +- if (expression is PrefixedIdentifier) { +- identifier = expression.identifier; +- } else if (expression is PropertyAccess) { +- identifier = expression.propertyName; +- } else { +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.token(negation)); +- builder.addSimpleReplacement(range.node(identifier), 'isNotEmpty'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.USE_IS_NOT_EMPTY); +- } +- +- Future _addFix_isNotNull() async { +- if (coveredNode is IsExpression) { +- IsExpression isExpression = coveredNode as IsExpression; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder +- .addReplacement(range.endEnd(isExpression.expression, isExpression), +- (DartEditBuilder builder) { +- builder.write(' != null'); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.USE_NOT_EQ_NULL); +- } +- } +- +- Future _addFix_isNull() async { +- if (coveredNode is IsExpression) { +- IsExpression isExpression = coveredNode as IsExpression; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder +- .addReplacement(range.endEnd(isExpression.expression, isExpression), +- (DartEditBuilder builder) { +- builder.write(' == null'); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.USE_EQ_EQ_NULL); +- } +- } +- +- Future _addFix_makeEnclosingClassAbstract() async { +- ClassDeclaration enclosingClass = +- node.getAncestor((node) => node is ClassDeclaration); +- if (enclosingClass == null) { +- return; +- } +- String className = enclosingClass.name.name; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion( +- enclosingClass.classKeyword.offset, 'abstract '); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_CLASS_ABSTRACT, +- args: [className]); +- } +- +- Future _addFix_makeFieldNotFinal() async { +- AstNode node = this.node; +- if (node is SimpleIdentifier && +- node.bestElement is PropertyAccessorElement) { +- PropertyAccessorElement getter = node.bestElement; +- if (getter.isGetter && +- getter.isSynthetic && +- !getter.variable.isSynthetic && +- getter.variable.setter == null && +- getter.enclosingElement is ClassElement) { +- AstNode name = +- await astProvider.getParsedNameForElement(getter.variable); +- AstNode variable = name?.parent; +- if (variable is VariableDeclaration && +- variable.parent is VariableDeclarationList && +- variable.parent.parent is FieldDeclaration) { +- VariableDeclarationList declarationList = variable.parent; +- Token keywordToken = declarationList.keyword; +- if (declarationList.variables.length == 1 && +- keywordToken.keyword == Keyword.FINAL) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, +- (DartFileEditBuilder builder) { +- if (declarationList.type != null) { +- builder.addReplacement( +- range.startStart(keywordToken, declarationList.type), +- (DartEditBuilder builder) {}); +- } else { +- builder.addReplacement(range.startStart(keywordToken, variable), +- (DartEditBuilder builder) { +- builder.write('var '); +- }); +- } +- }); +- String fieldName = getter.variable.displayName; +- _addFixFromBuilder(changeBuilder, DartFixKind.MAKE_FIELD_NOT_FINAL, +- args: [fieldName]); +- } +- } +- } +- } +- } +- +- Future _addFix_nonBoolCondition_addNotNull() async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(error.offset + error.length, ' != null'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL); +- } +- +- Future _addFix_removeAwait() async { +- final awaitExpression = node; +- if (awaitExpression is AwaitExpression) { +- final awaitToken = awaitExpression.awaitKeyword; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.startStart(awaitToken, awaitToken.next)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_AWAIT); +- } +- } +- +- Future _addFix_removeDeadCode() async { +- AstNode coveringNode = this.coveredNode; +- if (coveringNode is Expression) { +- AstNode parent = coveredNode.parent; +- if (parent is BinaryExpression) { +- if (parent.rightOperand == coveredNode) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.endEnd(parent.leftOperand, coveredNode)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE); +- } +- } +- } else if (coveringNode is Block) { +- Block block = coveringNode; +- List statementsToRemove = []; +- for (Statement statement in block.statements) { +- if (range.node(statement).intersects(errorRange)) { +- statementsToRemove.add(statement); +- } +- } +- if (statementsToRemove.isNotEmpty) { +- SourceRange rangeToRemove = +- utils.getLinesRangeStatements(statementsToRemove); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(rangeToRemove); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE); +- } +- } else if (coveringNode is Statement) { +- SourceRange rangeToRemove = +- utils.getLinesRangeStatements([coveringNode]); +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(rangeToRemove); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE); +- } +- } +- +- Future _addFix_removeEmptyCatch() async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(utils.getLinesRange(range.node(node.parent))); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_CATCH); +- } +- +- Future _addFix_removeEmptyConstructorBody() async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- utils.getLinesRange(range.node(node.parent)), ';'); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY); +- } +- +- Future _addFix_removeEmptyElse() async { +- IfStatement ifStatement = node.parent; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(utils.getLinesRange( +- range.startEnd(ifStatement.elseKeyword, ifStatement.elseStatement))); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_ELSE); +- } +- +- Future _addFix_removeEmptyStatement() async { +- EmptyStatement emptyStatement = node; +- if (emptyStatement.parent is Block) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(utils.getLinesRange(range.node(emptyStatement))); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_EMPTY_STATEMENT); +- } else { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.endEnd(emptyStatement.beginToken.previous, emptyStatement), +- ' {}'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_BRACKETS); +- } +- } +- +- Future _addFix_removeInitializer() async { +- // Retrieve the linted node. +- VariableDeclaration ancestor = +- node.getAncestor((a) => a is VariableDeclaration); +- if (ancestor == null) { +- return; +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.endEnd(ancestor.name, ancestor.initializer)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_INITIALIZER); +- } +- +- Future _addFix_removeInterpolationBraces() async { +- AstNode node = this.node; +- if (node is InterpolationExpression) { +- Token right = node.rightBracket; +- if (node.expression != null && right != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.startStart(node, node.expression), r'$'); +- builder.addDeletion(range.token(right)); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES); +- } else {} +- } +- } +- +- Future _addFix_removeMethodDeclaration() async { +- MethodDeclaration declaration = +- node.getAncestor((node) => node is MethodDeclaration); +- if (declaration != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(utils.getLinesRange(range.node(declaration))); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_METHOD_DECLARATION); +- } +- } +- +- Future _addFix_removeParameters_inGetterDeclaration() async { +- if (node is MethodDeclaration) { +- MethodDeclaration method = node as MethodDeclaration; +- SimpleIdentifier name = method.name; +- FunctionBody body = method.body; +- if (name != null && body != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.endStart(name, body), ' '); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION); +- } +- } +- } +- +- Future _addFix_removeParentheses_inGetterInvocation() async { +- if (node is SimpleIdentifier && node.parent is MethodInvocation) { +- MethodInvocation invocation = node.parent as MethodInvocation; +- if (invocation.methodName == node && invocation.target != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.endEnd(node, invocation)); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION); +- } +- } +- } +- +- Future _addFix_removeThisExpression() async { +- final thisExpression = node is ThisExpression +- ? node +- : node.getAncestor((node) => node is ThisExpression); +- final parent = thisExpression.parent; +- if (parent is PropertyAccess) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.startEnd(parent, parent.operator)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION); +- } else if (parent is MethodInvocation) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.startEnd(parent, parent.operator)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_THIS_EXPRESSION); +- } +- } +- +- Future _addFix_removeTypeAnnotation() async { +- final TypeAnnotation type = +- node.getAncestor((node) => node is TypeAnnotation); +- if (type != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.startStart(type, type.endToken.next)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_NAME); +- } +- } +- +- Future _addFix_removeUnnecessaryCast() async { +- if (coveredNode is! AsExpression) { +- return; +- } +- AsExpression asExpression = coveredNode as AsExpression; +- Expression expression = asExpression.expression; +- int expressionPrecedence = getExpressionPrecedence(expression); +- // remove 'as T' from 'e as T' +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(range.endEnd(expression, asExpression)); +- _removeEnclosingParentheses(builder, asExpression, expressionPrecedence); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNNECESSARY_CAST); +- } +- +- Future _addFix_removeUnusedCatchClause() async { +- if (node is SimpleIdentifier) { +- AstNode catchClause = node.parent; +- if (catchClause is CatchClause && +- catchClause.exceptionParameter == node) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion( +- range.startStart(catchClause.catchKeyword, catchClause.body)); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE); +- } +- } +- } +- +- Future _addFix_removeUnusedCatchStack() async { +- if (node is SimpleIdentifier) { +- AstNode catchClause = node.parent; +- if (catchClause is CatchClause && +- catchClause.stackTraceParameter == node && +- catchClause.exceptionParameter != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder +- .addDeletion(range.endEnd(catchClause.exceptionParameter, node)); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.REMOVE_UNUSED_CATCH_STACK); +- } +- } +- } +- +- Future _addFix_removeUnusedImport() async { +- // prepare ImportDirective +- ImportDirective importDirective = +- node.getAncestor((node) => node is ImportDirective); +- if (importDirective == null) { +- return; +- } +- // remove the whole line with import +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addDeletion(utils.getLinesRange(range.node(importDirective))); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_IMPORT); +- } +- +- Future _addFix_replaceVarWithDynamic() async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.error(error), 'dynamic'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_VAR_WITH_DYNAMIC); +- } +- +- Future _addFix_replaceWithConditionalAssignment() async { +- IfStatement ifStatement = node is IfStatement +- ? node +- : node.getAncestor((node) => node is IfStatement); +- var thenStatement = ifStatement.thenStatement; +- Statement uniqueStatement(Statement statement) { +- if (statement is Block) { +- return uniqueStatement(statement.statements.first); +- } +- return statement; +- } +- +- thenStatement = uniqueStatement(thenStatement); +- if (thenStatement is ExpressionStatement) { +- final expression = thenStatement.expression.unParenthesized; +- if (expression is AssignmentExpression) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(ifStatement), +- (DartEditBuilder builder) { +- builder.write(utils.getNodeText(expression.leftHandSide)); +- builder.write(' ??= '); +- builder.write(utils.getNodeText(expression.rightHandSide)); +- builder.write(';'); +- }); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT); +- } +- } +- } +- +- Future _addFix_replaceWithConstInstanceCreation() async { +- if (coveredNode is InstanceCreationExpression) { +- var instanceCreation = coveredNode as InstanceCreationExpression; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement( +- range.token(instanceCreation.keyword), 'const'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.USE_CONST); +- } +- } +- +- Future _addFix_replaceWithIdentifier() async { +- final FunctionTypedFormalParameter functionTyped = +- node.getAncestor((node) => node is FunctionTypedFormalParameter); +- if (functionTyped != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(functionTyped), +- utils.getNodeText(functionTyped.identifier)); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_IDENTIFIER); +- } else { +- await _addFix_removeTypeAnnotation(); +- } +- } +- +- Future _addFix_replaceWithLiteral() async { +- final InstanceCreationExpression instanceCreation = +- node.getAncestor((node) => node is InstanceCreationExpression); +- final InterfaceType type = instanceCreation.staticType; +- final generics = instanceCreation.constructorName.type.typeArguments; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(instanceCreation), +- (DartEditBuilder builder) { +- if (generics != null) { +- builder.write(utils.getNodeText(generics)); +- } +- if (type.name == 'List') { +- builder.write('[]'); +- } else { +- builder.write('{}'); +- } +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_LITERAL); +- } +- +- Future _addFix_replaceWithTearOff() async { +- FunctionExpression ancestor = +- node.getAncestor((a) => a is FunctionExpression); +- if (ancestor == null) { +- return; +- } +- Future addFixOfExpression(InvocationExpression expression) async { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addReplacement(range.node(ancestor), (DartEditBuilder builder) { +- if (expression is MethodInvocation && expression.target != null) { +- builder.write(utils.getNodeText(expression.target)); +- builder.write('.'); +- } +- builder.write(utils.getNodeText(expression.function)); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_TEAR_OFF); +- } +- +- final body = ancestor.body; +- if (body is ExpressionFunctionBody) { +- final expression = body.expression; +- await addFixOfExpression(expression.unParenthesized); +- } else if (body is BlockFunctionBody) { +- final statement = body.block.statements.first; +- if (statement is ExpressionStatement) { +- final expression = statement.expression; +- await addFixOfExpression(expression.unParenthesized); +- } else if (statement is ReturnStatement) { +- final expression = statement.expression; +- await addFixOfExpression(expression.unParenthesized); +- } +- } +- } +- +- Future _addFix_undefinedClass_useSimilar() async { +- AstNode node = this.node; +- // Prepare the optional import prefix name. +- String prefixName = null; +- if (node is SimpleIdentifier && node.staticElement is PrefixElement) { +- AstNode parent = node.parent; +- if (parent is PrefixedIdentifier && +- parent.prefix == node && +- parent.parent is TypeName) { +- prefixName = (node as SimpleIdentifier).name; +- node = parent.identifier; +- } +- } +- // Process if looks like a type. +- if (_mayBeTypeIdentifier(node)) { +- // Prepare for selecting the closest element. +- String name = (node as SimpleIdentifier).name; +- _ClosestElementFinder finder = new _ClosestElementFinder( +- name, +- (Element element) => element is ClassElement, +- MAX_LEVENSHTEIN_DISTANCE); +- // Check elements of this library. +- if (prefixName == null) { +- for (CompilationUnitElement unit in unitLibraryElement.units) { +- finder._updateList(unit.types); +- } +- } +- // Check elements from imports. +- for (ImportElement importElement in unitLibraryElement.imports) { +- if (importElement.prefix?.name == prefixName) { +- Map namespace = getImportNamespace(importElement); +- finder._updateList(namespace.values); +- } +- } +- // If we have a close enough element, suggest to use it. +- if (finder._element != null) { +- String closestName = finder._element.name; +- if (closestName != null) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(node), closestName); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO, +- args: [closestName]); +- } +- } +- } +- } +- +- Future _addFix_undefinedClassAccessor_useSimilar() async { +- AstNode node = this.node; +- if (node is SimpleIdentifier) { +- // prepare target +- Expression target = null; +- if (node.parent is PrefixedIdentifier) { +- PrefixedIdentifier invocation = node.parent as PrefixedIdentifier; +- target = invocation.prefix; +- } +- // find getter +- if (node.inGetterContext()) { +- await _addFix_undefinedClassMember_useSimilar(target, +- (Element element) { +- return element is PropertyAccessorElement && element.isGetter || +- element is FieldElement && element.getter != null; +- }); +- } +- // find setter +- if (node.inSetterContext()) { +- await _addFix_undefinedClassMember_useSimilar(target, +- (Element element) { +- return element is PropertyAccessorElement && element.isSetter || +- element is FieldElement && element.setter != null; +- }); +- } +- } +- } +- +- Future _addFix_undefinedClassMember_useSimilar( +- Expression target, ElementPredicate predicate) async { +- if (node is SimpleIdentifier) { +- String name = (node as SimpleIdentifier).name; +- _ClosestElementFinder finder = +- new _ClosestElementFinder(name, predicate, MAX_LEVENSHTEIN_DISTANCE); +- // unqualified invocation +- if (target == null) { +- ClassDeclaration clazz = +- node.getAncestor((node) => node is ClassDeclaration); +- if (clazz != null) { +- ClassElement classElement = clazz.element; +- _updateFinderWithClassMembers(finder, classElement); +- } +- } else { +- DartType type = target.bestType; +- if (type is InterfaceType) { +- ClassElement classElement = type.element; +- _updateFinderWithClassMembers(finder, classElement); +- } +- } +- // if we have close enough element, suggest to use it +- if (finder._element != null) { +- String closestName = finder._element.name; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(node), closestName); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO, +- args: [closestName]); +- } +- } +- } +- +- Future _addFix_undefinedFunction_create() async { +- // should be the name of the invocation +- if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else { +- return; +- } +- String name = (node as SimpleIdentifier).name; +- MethodInvocation invocation = node.parent as MethodInvocation; +- // function invocation has no target +- Expression target = invocation.realTarget; +- if (target != null) { +- return; +- } +- // prepare environment +- int insertOffset; +- String sourcePrefix; +- AstNode enclosingMember = +- node.getAncestor((node) => node is CompilationUnitMember); +- insertOffset = enclosingMember.end; +- sourcePrefix = '$eol$eol'; +- utils.targetClassElement = null; +- // build method source +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addInsertion(insertOffset, (DartEditBuilder builder) { +- builder.write(sourcePrefix); +- // append return type +- { +- DartType type = _inferUndefinedExpressionType(invocation); +- if (builder.writeType(type, groupName: 'RETURN_TYPE')) { +- builder.write(' '); +- } +- } +- // append name +- builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) { +- builder.write(name); +- }); +- builder.write('('); +- builder.writeParametersMatchingArguments(invocation.argumentList); +- builder.write(') {$eol}'); +- }); +- builder.addLinkedPosition(range.node(node), 'NAME'); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION, +- args: [name]); +- } +- +- Future _addFix_undefinedFunction_useSimilar() async { +- AstNode node = this.node; +- if (node is SimpleIdentifier) { +- // Prepare the optional import prefix name. +- String prefixName = null; +- { +- AstNode invocation = node.parent; +- if (invocation is MethodInvocation && invocation.methodName == node) { +- Expression target = invocation.target; +- if (target is SimpleIdentifier && +- target.staticElement is PrefixElement) { +- prefixName = target.name; +- } +- } +- } +- // Prepare for selecting the closest element. +- _ClosestElementFinder finder = new _ClosestElementFinder( +- node.name, +- (Element element) => element is FunctionElement, +- MAX_LEVENSHTEIN_DISTANCE); +- // Check to this library units. +- if (prefixName == null) { +- for (CompilationUnitElement unit in unitLibraryElement.units) { +- finder._updateList(unit.functions); +- } +- } +- // Check unprefixed imports. +- for (ImportElement importElement in unitLibraryElement.imports) { +- if (importElement.prefix?.name == prefixName) { +- Map namespace = getImportNamespace(importElement); +- finder._updateList(namespace.values); +- } +- } +- // If we have a close enough element, suggest to use it. +- if (finder._element != null) { +- String closestName = finder._element.name; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleReplacement(range.node(node), closestName); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO, +- args: [closestName]); +- } +- } +- } +- +- Future _addFix_undefinedMethod_create() async { +- if (node is SimpleIdentifier && node.parent is MethodInvocation) { +- String name = (node as SimpleIdentifier).name; +- MethodInvocation invocation = node.parent as MethodInvocation; +- // prepare environment +- Element targetElement; +- bool staticModifier = false; +- +- ClassDeclaration targetClassNode; +- Expression target = invocation.realTarget; +- if (target == null) { +- targetElement = unitElement; +- ClassMember enclosingMember = +- node.getAncestor((node) => node is ClassMember); +- targetClassNode = enclosingMember.parent; +- utils.targetClassElement = targetClassNode.element; +- staticModifier = _inStaticContext(); +- } else { +- // prepare target interface type +- DartType targetType = target.bestType; +- if (targetType is! InterfaceType) { +- return; +- } +- ClassElement targetClassElement = targetType.element as ClassElement; +- if (targetClassElement.librarySource.isInSystemLibrary) { +- return; +- } +- targetElement = targetClassElement; +- // prepare target ClassDeclaration +- AstNode targetTypeNode = getParsedClassElementNode(targetClassElement); +- if (targetTypeNode is! ClassDeclaration) { +- return; +- } +- targetClassNode = targetTypeNode; +- // maybe static +- if (target is Identifier) { +- staticModifier = +- resolutionMap.bestElementForIdentifier(target).kind == +- ElementKind.CLASS; +- } +- // use different utils +- CompilationUnitElement targetUnitElement = +- getCompilationUnitElement(targetClassElement); +- CompilationUnit targetUnit = getParsedUnit(targetUnitElement); +- utils = new CorrectionUtils(targetUnit); +- } +- ClassMemberLocation targetLocation = +- utils.prepareNewMethodLocation(targetClassNode); +- String targetFile = targetElement.source.fullName; +- // build method source +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, +- (DartFileEditBuilder builder) { +- builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) { +- builder.write(targetLocation.prefix); +- // maybe "static" +- if (staticModifier) { +- builder.write('static '); +- } +- // append return type +- { +- DartType type = _inferUndefinedExpressionType(invocation); +- if (builder.writeType(type, groupName: 'RETURN_TYPE')) { +- builder.write(' '); +- } +- } +- // append name +- builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) { +- builder.write(name); +- }); +- builder.write('('); +- builder.writeParametersMatchingArguments(invocation.argumentList); +- builder.write(') {}'); +- builder.write(targetLocation.suffix); +- }); +- if (targetFile == file) { +- builder.addLinkedPosition(range.node(node), 'NAME'); +- } +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, +- args: [name]); +- } +- } +- +- Future _addFix_undefinedMethod_useSimilar() async { +- if (node.parent is MethodInvocation) { +- MethodInvocation invocation = node.parent as MethodInvocation; +- await _addFix_undefinedClassMember_useSimilar(invocation.realTarget, +- (Element element) => element is MethodElement && !element.isOperator); +- } +- } +- +- Future _addFix_undefinedMethodWithContructor() async { +- if (node is SimpleIdentifier && node.parent is MethodInvocation) { +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- builder.addSimpleInsertion(node.parent.offset, 'new '); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.INVOKE_CONSTRUCTOR_USING_NEW); +- // TODO(brianwilkerson) Figure out whether the constructor is a `const` +- // constructor and all of the parameters are constant expressions, and +- // suggest inserting 'const ' if so. +- } +- } +- +- /** +- * Here we handle cases when a constructors does not initialize all of the +- * final fields. +- */ +- Future _addFix_updateConstructor_forUninitializedFinalFields() async { +- if (node is! SimpleIdentifier || node.parent is! ConstructorDeclaration) { +- return; +- } +- ConstructorDeclaration constructor = node.parent; +- // add these fields +- List fields = +- ErrorVerifier.computeNotInitializedFields(constructor); +- fields.retainWhere((FieldElement field) => field.isFinal); +- // prepare new parameters code +- fields.sort((a, b) => a.nameOffset - b.nameOffset); +- String fieldParametersCode = +- fields.map((field) => 'this.${field.name}').join(', '); +- // prepare the last required parameter +- FormalParameter lastRequiredParameter; +- List parameters = constructor.parameters.parameters; +- for (FormalParameter parameter in parameters) { +- if (parameter.kind == ParameterKind.REQUIRED) { +- lastRequiredParameter = parameter; +- } +- } +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // append new field formal initializers +- if (lastRequiredParameter != null) { +- builder.addSimpleInsertion( +- lastRequiredParameter.end, ', $fieldParametersCode'); +- } else { +- int offset = constructor.parameters.leftParenthesis.end; +- if (parameters.isNotEmpty) { +- fieldParametersCode += ', '; +- } +- builder.addSimpleInsertion(offset, fieldParametersCode); +- } +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.ADD_FIELD_FORMAL_PARAMETERS); +- } +- +- Future _addFix_useEffectiveIntegerDivision() async { +- for (AstNode n = node; n != null; n = n.parent) { +- if (n is MethodInvocation && +- n.offset == errorOffset && +- n.length == errorLength) { +- Expression target = (n as MethodInvocation).target.unParenthesized; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // replace "/" with "~/" +- BinaryExpression binary = target as BinaryExpression; +- builder.addSimpleReplacement(range.token(binary.operator), '~/'); +- // remove everything before and after +- builder.addDeletion(range.startStart(n, binary.leftOperand)); +- builder.addDeletion(range.endEnd(binary.rightOperand, n)); +- }); +- _addFixFromBuilder( +- changeBuilder, DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION); +- // done +- break; +- } +- } +- } +- +- /** +- * Adds a fix that replaces [target] with a reference to the class declaring +- * the given [element]. +- */ +- Future _addFix_useStaticAccess(AstNode target, Element element) async { +- Element declaringElement = element.enclosingElement; +- if (declaringElement is ClassElement) { +- DartType declaringType = declaringElement.type; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { +- // replace "target" with class name +- builder.addReplacement(range.node(target), (DartEditBuilder builder) { +- builder.writeType(declaringType); +- }); +- }); +- _addFixFromBuilder(changeBuilder, DartFixKind.CHANGE_TO_STATIC_ACCESS, +- args: [declaringType]); +- } +- } +- +- Future _addFix_useStaticAccess_method() async { +- if (node is SimpleIdentifier && node.parent is MethodInvocation) { +- MethodInvocation invocation = node.parent as MethodInvocation; +- if (invocation.methodName == node) { +- Expression target = invocation.target; +- Element invokedElement = invocation.methodName.bestElement; +- await _addFix_useStaticAccess(target, invokedElement); +- } +- } +- } +- +- Future _addFix_useStaticAccess_property() async { +- if (node is SimpleIdentifier && node.parent is PrefixedIdentifier) { +- PrefixedIdentifier prefixed = node.parent as PrefixedIdentifier; +- if (prefixed.identifier == node) { +- Expression target = prefixed.prefix; +- Element invokedElement = prefixed.identifier.bestElement; +- await _addFix_useStaticAccess(target, invokedElement); +- } +- } +- } +- +- void _addFixFromBuilder(DartChangeBuilder builder, FixKind kind, +- {List args: null, bool importsOnly: false}) { +- SourceChange change = builder.sourceChange; +- if (change.edits.isEmpty && !importsOnly) { +- return; +- } +- change.message = formatList(kind.message, args); +- fixes.add(new Fix(kind, change)); +- } +- +- /** +- * Prepares proposal for creating function corresponding to the given +- * [FunctionType]. +- */ +- Future _addProposal_createFunction( +- FunctionType functionType, +- String name, +- Source targetSource, +- int insertOffset, +- bool isStatic, +- String prefix, +- String sourcePrefix, +- String sourceSuffix, +- Element target) async { +- // build method source +- String targetFile = targetSource.fullName; +- DartChangeBuilder changeBuilder = new DartChangeBuilder(session); +- await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) { +- builder.addInsertion(insertOffset, (DartEditBuilder builder) { +- builder.write(sourcePrefix); +- builder.write(prefix); +- // may be static +- if (isStatic) { +- builder.write('static '); +- } +- // append return type +- if (builder.writeType(functionType.returnType, +- groupName: 'RETURN_TYPE')) { +- builder.write(' '); +- } +- // append name +- builder.addLinkedEdit('NAME', (DartLinkedEditBuilder builder) { +- builder.write(name); +- }); +- // append parameters +- builder.write('('); +- List parameters = functionType.parameters; +- for (int i = 0; i < parameters.length; i++) { +- ParameterElement parameter = parameters[i]; +- // append separator +- if (i != 0) { +- builder.write(', '); +- } +- // append type name +- DartType type = parameter.type; +- if (!type.isDynamic) { +- builder.addLinkedEdit('TYPE$i', +- (DartLinkedEditBuilder innerBuilder) { +- builder.writeType(type); +- innerBuilder.addSuperTypesAsSuggestions(type); +- }); +- builder.write(' '); +- } +- // append parameter name +- builder.addLinkedEdit('ARG$i', (DartLinkedEditBuilder builder) { +- builder.write(parameter.displayName); +- }); +- } +- builder.write(')'); +- // close method +- builder.write(' {$eol$prefix}'); +- builder.write(sourceSuffix); +- }); +- if (targetSource == unitSource) { +- builder.addLinkedPosition(range.node(node), 'NAME'); +- } +- }); +- return changeBuilder; +- } +- +- /** +- * Adds proposal for creating method corresponding to the given [FunctionType] in the given +- * [ClassElement]. +- */ +- Future _addProposal_createFunction_function( +- FunctionType functionType) async { +- String name = (node as SimpleIdentifier).name; +- // prepare environment +- int insertOffset = unit.end; +- // prepare prefix +- String prefix = ''; +- String sourcePrefix = '$eol'; +- String sourceSuffix = eol; +- DartChangeBuilder changeBuilder = await _addProposal_createFunction( +- functionType, +- name, +- unitSource, +- insertOffset, +- false, +- prefix, +- sourcePrefix, +- sourceSuffix, +- unitElement); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION, +- args: [name]); +- } +- +- /** +- * Adds proposal for creating method corresponding to the given [FunctionType] in the given +- * [ClassElement]. +- */ +- Future _addProposal_createFunction_method( +- ClassElement targetClassElement, FunctionType functionType) async { +- String name = (node as SimpleIdentifier).name; +- // prepare environment +- Source targetSource = targetClassElement.source; +- // prepare insert offset +- ClassDeclaration targetClassNode = +- getParsedClassElementNode(targetClassElement); +- int insertOffset = targetClassNode.end - 1; +- // prepare prefix +- String prefix = ' '; +- String sourcePrefix; +- if (targetClassNode.members.isEmpty) { +- sourcePrefix = ''; +- } else { +- sourcePrefix = eol; +- } +- String sourceSuffix = eol; +- DartChangeBuilder changeBuilder = await _addProposal_createFunction( +- functionType, +- name, +- targetSource, +- insertOffset, +- _inStaticContext(), +- prefix, +- sourcePrefix, +- sourceSuffix, +- targetClassElement); +- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, args: [name]); +- } +- +- /** +- * Computes the name of the library at the given [path]. +- * See https://www.dartlang.org/articles/style-guide/#names for conventions. +- */ +- String _computeLibraryName(String path) { +- Context pathContext = resourceProvider.pathContext; +- String packageFolder = _computePackageFolder(path); +- if (packageFolder == null) { +- return pathContext.basenameWithoutExtension(path); +- } +- String packageName = pathContext.basename(packageFolder); +- String relPath = pathContext.relative(path, from: packageFolder); +- List relPathParts = pathContext.split(relPath); +- if (relPathParts.isNotEmpty) { +- if (relPathParts[0].toLowerCase() == 'lib') { +- relPathParts.removeAt(0); +- } +- if (relPathParts.isNotEmpty) { +- String nameWithoutExt = pathContext.withoutExtension(relPathParts.last); +- relPathParts[relPathParts.length - 1] = nameWithoutExt; +- } +- } +- return packageName + '.' + relPathParts.join('.'); +- } +- +- /** +- * Returns the path of the folder which contains the given [path]. +- */ +- String _computePackageFolder(String path) { +- Context pathContext = resourceProvider.pathContext; +- String pubspecFolder = dirname(path); +- while (true) { +- if (resourceProvider +- .getResource(pathContext.join(pubspecFolder, 'pubspec.yaml')) +- .exists) { +- return pubspecFolder; +- } +- String pubspecFolderNew = pathContext.dirname(pubspecFolder); +- if (pubspecFolderNew == pubspecFolder) { +- return null; +- } +- pubspecFolder = pubspecFolderNew; +- } +- } +- +- /** +- * Return the string to display as the name of the given constructor in a +- * proposal name. +- */ +- String _getConstructorProposalName(ConstructorElement constructor) { +- StringBuffer buffer = new StringBuffer(); +- buffer.write('super'); +- String constructorName = constructor.displayName; +- if (!constructorName.isEmpty) { +- buffer.write('.'); +- buffer.write(constructorName); +- } +- buffer.write('(...)'); +- return buffer.toString(); +- } +- +- /** +- * Returns the [DartType] with given name from the `dart:core` library. +- */ +- DartType _getCoreType(String name) { +- List libraries = unitLibraryElement.importedLibraries; +- for (LibraryElement library in libraries) { +- if (library.isDartCore) { +- ClassElement classElement = library.getType(name); +- if (classElement != null) { +- return classElement.type; +- } +- return null; +- } +- } +- return null; +- } +- +- /** +- * Return the correction utilities that should be used when creating an edit +- * in the compilation unit containing the given [node]. +- */ +- CorrectionUtils _getUtilsFor(AstNode node) { +- CompilationUnit targetUnit = +- node.getAncestor((node) => node is CompilationUnit); +- CompilationUnitElement targetUnitElement = targetUnit?.element; +- CorrectionUtils realUtils = utils; +- if (targetUnitElement != utils.unit.element) { +- realUtils = new CorrectionUtils(targetUnit); +- ClassDeclaration targetClass = +- node.getAncestor((node) => node is ClassDeclaration); +- if (targetClass != null) { +- realUtils.targetClassElement = targetClass.element; +- } +- } +- return realUtils; +- } +- +- /** +- * Returns an expected [DartType] of [expression], may be `null` if cannot be +- * inferred. +- */ +- DartType _inferUndefinedExpressionType(Expression expression) { +- AstNode parent = expression.parent; +- // myFunction(); +- if (parent is ExpressionStatement) { +- if (expression is MethodInvocation) { +- return VoidTypeImpl.instance; +- } +- } +- // return myFunction(); +- if (parent is ReturnStatement) { +- ExecutableElement executable = getEnclosingExecutableElement(expression); +- return executable?.returnType; +- } +- // int v = myFunction(); +- if (parent is VariableDeclaration) { +- VariableDeclaration variableDeclaration = parent; +- if (variableDeclaration.initializer == expression) { +- VariableElement variableElement = variableDeclaration.element; +- if (variableElement != null) { +- return variableElement.type; +- } +- } +- } +- // myField = 42; +- if (parent is AssignmentExpression) { +- AssignmentExpression assignment = parent; +- if (assignment.leftHandSide == expression) { +- Expression rhs = assignment.rightHandSide; +- if (rhs != null) { +- return rhs.bestType; +- } +- } +- } +- // v = myFunction(); +- if (parent is AssignmentExpression) { +- AssignmentExpression assignment = parent; +- if (assignment.rightHandSide == expression) { +- if (assignment.operator.type == TokenType.EQ) { +- // v = myFunction(); +- Expression lhs = assignment.leftHandSide; +- if (lhs != null) { +- return lhs.bestType; +- } +- } else { +- // v += myFunction(); +- MethodElement method = assignment.bestElement; +- if (method != null) { +- List parameters = method.parameters; +- if (parameters.length == 1) { +- return parameters[0].type; +- } +- } +- } +- } +- } +- // v + myFunction(); +- if (parent is BinaryExpression) { +- BinaryExpression binary = parent; +- MethodElement method = binary.bestElement; +- if (method != null) { +- if (binary.rightOperand == expression) { +- List parameters = method.parameters; +- return parameters.length == 1 ? parameters[0].type : null; +- } +- } +- } +- // foo( myFunction() ); +- if (parent is ArgumentList) { +- ParameterElement parameter = expression.bestParameterElement; +- return parameter?.type; +- } +- // bool +- { +- // assert( myFunction() ); +- if (parent is AssertStatement) { +- AssertStatement statement = parent; +- if (statement.condition == expression) { +- return coreTypeBool; +- } +- } +- // if ( myFunction() ) {} +- if (parent is IfStatement) { +- IfStatement statement = parent; +- if (statement.condition == expression) { +- return coreTypeBool; +- } +- } +- // while ( myFunction() ) {} +- if (parent is WhileStatement) { +- WhileStatement statement = parent; +- if (statement.condition == expression) { +- return coreTypeBool; +- } +- } +- // do {} while ( myFunction() ); +- if (parent is DoStatement) { +- DoStatement statement = parent; +- if (statement.condition == expression) { +- return coreTypeBool; +- } +- } +- // !myFunction() +- if (parent is PrefixExpression) { +- PrefixExpression prefixExpression = parent; +- if (prefixExpression.operator.type == TokenType.BANG) { +- return coreTypeBool; +- } +- } +- // binary expression '&&' or '||' +- if (parent is BinaryExpression) { +- BinaryExpression binaryExpression = parent; +- TokenType operatorType = binaryExpression.operator.type; +- if (operatorType == TokenType.AMPERSAND_AMPERSAND || +- operatorType == TokenType.BAR_BAR) { +- return coreTypeBool; +- } +- } +- } +- // we don't know +- return null; +- } +- +- /** +- * Returns `true` if [node] is in static context. +- */ +- bool _inStaticContext() { +- // constructor initializer cannot reference "this" +- if (node.getAncestor((node) => node is ConstructorInitializer) != null) { +- return true; +- } +- // field initializer cannot reference "this" +- if (node.getAncestor((node) => node is FieldDeclaration) != null) { +- return true; +- } +- // static method +- MethodDeclaration method = node.getAncestor((node) { +- return node is MethodDeclaration; +- }); +- return method != null && method.isStatic; +- } +- +- bool _isAwaitNode() { +- AstNode node = this.node; +- return node is SimpleIdentifier && node.name == 'await'; +- } +- +- bool _isLibSrcPath(String path) { +- List parts = resourceProvider.pathContext.split(path); +- for (int i = 0; i < parts.length - 2; i++) { +- if (parts[i] == 'lib' && parts[i + 1] == 'src') { +- return true; +- } +- } +- return false; +- } +- +- /** +- * Return `true` if the [source] can be imported into [unitLibraryFile]. +- */ +- bool _isSourceVisibleToLibrary(Source source) { +- if (!source.uri.isScheme('file')) { +- return true; +- } +- +- // Prepare the root of our package. +- Folder packageRoot; +- for (Folder folder = unitLibraryFolder; +- folder != null; +- folder = folder.parent) { +- if (folder.getChildAssumingFile('pubspec.yaml').exists || +- folder.getChildAssumingFile('BUILD').exists) { +- packageRoot = folder; +- break; +- } +- } +- +- // This should be rare / never situation. +- if (packageRoot == null) { +- return true; +- } +- +- // We cannot use relative URIs to reference files outside of our package. +- return resourceProvider.pathContext +- .isWithin(packageRoot.path, source.fullName); +- } +- +- /** +- * Removes any [ParenthesizedExpression] enclosing [expr]. +- * +- * [exprPrecedence] - the effective precedence of [expr]. +- */ +- void _removeEnclosingParentheses( +- DartFileEditBuilder builder, Expression expr, int exprPrecedence) { +- while (expr.parent is ParenthesizedExpression) { +- ParenthesizedExpression parenthesized = +- expr.parent as ParenthesizedExpression; +- if (getExpressionParentPrecedence(parenthesized) > exprPrecedence) { +- break; +- } +- builder.addDeletion(range.token(parenthesized.leftParenthesis)); +- builder.addDeletion(range.token(parenthesized.rightParenthesis)); +- expr = parenthesized; +- } +- } +- +- void _updateFinderWithClassMembers( +- _ClosestElementFinder finder, ClassElement clazz) { +- if (clazz != null) { +- List members = getMembers(clazz); +- finder._updateList(members); +- } +- } +- +- static bool _isNameOfType(String name) { +- if (name.isEmpty) { +- return false; +- } +- String firstLetter = name.substring(0, 1); +- if (firstLetter.toUpperCase() != firstLetter) { +- return false; +- } +- return true; +- } +- +- /** +- * Returns `true` if [node] is a type name. +- */ +- static bool _mayBeTypeIdentifier(AstNode node) { +- if (node is SimpleIdentifier) { +- AstNode parent = node.parent; +- if (parent is TypeName) { +- return true; +- } +- return _isNameOfType(node.name); +- } +- return false; +- } +-} +- +-/** +- * An enumeration of lint names. +- */ +-class LintNames { +- static const String always_require_non_null_named_parameters = +- 'always_require_non_null_named_parameters'; +- static const String annotate_overrides = 'annotate_overrides'; +- static const String avoid_annotating_with_dynamic = +- 'avoid_annotating_with_dynamic'; +- static const String avoid_empty_else = 'avoid_empty_else'; +- static const String avoid_init_to_null = 'avoid_init_to_null'; +- static const String avoid_return_types_on_setters = +- 'avoid_return_types_on_setters'; +- static const String avoid_types_on_closure_parameters = +- 'avoid_types_on_closure_parameters'; +- static const String await_only_futures = 'await_only_futures'; +- static const String empty_catches = 'empty_catches'; +- static const String empty_constructor_bodies = 'empty_constructor_bodies'; +- static const String empty_statements = 'empty_statements'; +- static const String prefer_collection_literals = 'prefer_collection_literals'; +- static const String prefer_conditional_assignment = +- 'prefer_conditional_assignment'; +- static const String prefer_is_not_empty = 'prefer_is_not_empty'; +- static const String type_init_formals = 'type_init_formals'; +- static const String unnecessary_brace_in_string_interp = +- 'unnecessary_brace_in_string_interp'; +- static const String unnecessary_lambdas = 'unnecessary_lambdas'; +- static const String unnecessary_override = 'unnecessary_override'; +- static const String unnecessary_this = 'unnecessary_this'; +-} +- +-/** +- * Helper for finding [Element] with name closest to the given. +- */ +-class _ClosestElementFinder { +- final String _targetName; +- final ElementPredicate _predicate; +- +- Element _element = null; +- int _distance; +- +- _ClosestElementFinder(this._targetName, this._predicate, this._distance); +- +- void _update(Element element) { +- if (_predicate(element)) { +- int memberDistance = levenshtein(element.name, _targetName, _distance); +- if (memberDistance < _distance) { +- _element = element; +- _distance = memberDistance; +- } +- } +- } +- +- void _updateList(Iterable elements) { +- for (Element element in elements) { +- _update(element); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/levenshtein.dart b/pkg/analysis_server/lib/src/services/correction/levenshtein.dart +deleted file mode 100644 +index 61cb493be7a..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/levenshtein.dart ++++ /dev/null +@@ -1,133 +0,0 @@ +-// 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:math' as math; +- +-/** +- * The value returned by [levenshtein] if the distance is determined +- * to be over the specified threshold. +- */ +-const int LEVENSHTEIN_MAX = 1 << 20; +- +-const int _MAX_VALUE = 1 << 10; +- +-/** +- * Find the Levenshtein distance between two [String]s if it's less than or +- * equal to a given threshold. +- * +- * This is the number of changes needed to change one String into another, +- * where each change is a single character modification (deletion, insertion or +- * substitution). +- * +- * This implementation follows from Algorithms on Strings, Trees and Sequences +- * by Dan Gusfield and Chas Emerick's implementation of the Levenshtein distance +- * algorithm. +- */ +-int levenshtein(String s, String t, int threshold, {bool caseSensitive: true}) { +- if (s == null || t == null) { +- throw new ArgumentError('Strings must not be null'); +- } +- if (threshold < 0) { +- throw new ArgumentError('Threshold must not be negative'); +- } +- +- if (!caseSensitive) { +- s = s.toLowerCase(); +- t = t.toLowerCase(); +- } +- +- int s_len = s.length; +- int t_len = t.length; +- +- // if one string is empty, +- // the edit distance is necessarily the length of the other +- if (s_len == 0) { +- return t_len <= threshold ? t_len : LEVENSHTEIN_MAX; +- } +- if (t_len == 0) { +- return s_len <= threshold ? s_len : LEVENSHTEIN_MAX; +- } +- // the distance can never be less than abs(s_len - t_len) +- if ((s_len - t_len).abs() > threshold) { +- return LEVENSHTEIN_MAX; +- } +- +- // swap the two strings to consume less memory +- if (s_len > t_len) { +- String tmp = s; +- s = t; +- t = tmp; +- s_len = t_len; +- t_len = t.length; +- } +- +- // 'previous' cost array, horizontally +- List p = new List.filled(s_len + 1, 0); +- // cost array, horizontally +- List d = new List.filled(s_len + 1, 0); +- // placeholder to assist in swapping p and d +- List _d; +- +- // fill in starting table values +- int boundary = math.min(s_len, threshold) + 1; +- for (int i = 0; i < boundary; i++) { +- p[i] = i; +- } +- +- // these fills ensure that the value above the rightmost entry of our +- // stripe will be ignored in following loop iterations +- _setRange(p, boundary, p.length, _MAX_VALUE); +- _setRange(d, 0, d.length, _MAX_VALUE); +- +- // iterates through t +- for (int j = 1; j <= t_len; j++) { +- // jth character of t +- int t_j = t.codeUnitAt(j - 1); +- d[0] = j; +- +- // compute stripe indices, constrain to array size +- int min = math.max(1, j - threshold); +- int max = math.min(s_len, j + threshold); +- +- // the stripe may lead off of the table if s and t are of different sizes +- if (min > max) { +- return LEVENSHTEIN_MAX; +- } +- +- // ignore entry left of leftmost +- if (min > 1) { +- d[min - 1] = _MAX_VALUE; +- } +- +- // iterates through [min, max] in s +- for (int i = min; i <= max; i++) { +- if (s.codeUnitAt(i - 1) == t_j) { +- // diagonally left and up +- d[i] = p[i - 1]; +- } else { +- // 1 + minimum of cell to the left, to the top, diagonally left and up +- d[i] = 1 + math.min(math.min(d[i - 1], p[i]), p[i - 1]); +- } +- } +- +- // copy current distance counts to 'previous row' distance counts +- _d = p; +- p = d; +- d = _d; +- } +- +- // if p[n] is greater than the threshold, +- // there's no guarantee on it being the correct distance +- if (p[s_len] <= threshold) { +- return p[s_len]; +- } +- +- return LEVENSHTEIN_MAX; +-} +- +-void _setRange(List a, int start, int end, int value) { +- for (int i = start; i < end; i++) { +- a[i] = value; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart +deleted file mode 100644 +index ebf7ae09b80..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart ++++ /dev/null +@@ -1,238 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +- +-List _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to']; +- +-/** +- * Returns all variants of names by removing leading words one by one. +- */ +-List getCamelWordCombinations(String name) { +- List result = []; +- List parts = getCamelWords(name); +- for (int i = 0; i < parts.length; i++) { +- var s1 = parts[i].toLowerCase(); +- var s2 = parts.skip(i + 1).join(); +- String suggestion = '$s1$s2'; +- result.add(suggestion); +- } +- return result; +-} +- +-/** +- * Returns possible names for a variable with the given expected type and +- * expression assigned. +- */ +-List getVariableNameSuggestionsForExpression( +- DartType expectedType, Expression assignedExpression, Set excluded, +- {bool isMethod: false}) { +- String prefix; +- +- if (isMethod) { +- // If we're in a build() method, use 'build' as the name prefix. +- MethodDeclaration method = +- assignedExpression.getAncestor((n) => n is MethodDeclaration); +- if (method != null) { +- String enclosingName = method.name?.name; +- if (enclosingName != null && enclosingName.startsWith('build')) { +- prefix = 'build'; +- } +- } +- } +- +- Set res = new Set(); +- // use expression +- if (assignedExpression != null) { +- String nameFromExpression = _getBaseNameFromExpression(assignedExpression); +- if (nameFromExpression != null) { +- nameFromExpression = removeStart(nameFromExpression, '_'); +- _addAll(excluded, res, getCamelWordCombinations(nameFromExpression), +- prefix: prefix); +- } +- String nameFromParent = +- _getBaseNameFromLocationInParent(assignedExpression); +- if (nameFromParent != null) { +- _addAll(excluded, res, getCamelWordCombinations(nameFromParent)); +- } +- } +- // use type +- if (expectedType != null && !expectedType.isDynamic) { +- String typeName = expectedType.name; +- if ('int' == typeName) { +- _addSingleCharacterName(excluded, res, 0x69); +- } else if ('double' == typeName) { +- _addSingleCharacterName(excluded, res, 0x64); +- } else if ('String' == typeName) { +- _addSingleCharacterName(excluded, res, 0x73); +- } else { +- _addAll(excluded, res, getCamelWordCombinations(typeName)); +- } +- res.remove(typeName); +- } +- // done +- return new List.from(res); +-} +- +-/** +- * Returns possible names for a [String] variable with [text] value. +- */ +-List getVariableNameSuggestionsForText( +- String text, Set excluded) { +- // filter out everything except of letters and white spaces +- { +- StringBuffer sb = new StringBuffer(); +- for (int i = 0; i < text.length; i++) { +- int c = text.codeUnitAt(i); +- if (isLetter(c) || isWhitespace(c)) { +- sb.writeCharCode(c); +- } +- } +- text = sb.toString(); +- } +- // make single camel-case text +- { +- List words = text.split(' '); +- StringBuffer sb = new StringBuffer(); +- for (int i = 0; i < words.length; i++) { +- String word = words[i]; +- if (i > 0) { +- word = capitalize(word); +- } +- sb.write(word); +- } +- text = sb.toString(); +- } +- // split camel-case into separate suggested names +- Set res = new Set(); +- _addAll(excluded, res, getCamelWordCombinations(text)); +- return new List.from(res); +-} +- +-/** +- * Adds [toAdd] items which are not excluded. +- */ +-void _addAll(Set excluded, Set result, Iterable toAdd, +- {String prefix}) { +- for (String item in toAdd) { +- // add name based on "item", but not "excluded" +- for (int suffix = 1;; suffix++) { +- // prepare name, just "item" or "item2", "item3", etc +- String name = item; +- if (suffix > 1) { +- name += suffix.toString(); +- } +- // add once found not excluded +- if (!excluded.contains(name)) { +- result.add(prefix == null ? name : '$prefix${capitalize(name)}'); +- break; +- } +- } +- } +-} +- +-/** +- * Adds to [result] either [c] or the first ASCII character after it. +- */ +-void _addSingleCharacterName(Set excluded, Set result, int c) { +- while (c < 0x7A) { +- String name = new String.fromCharCode(c); +- // may be done +- if (!excluded.contains(name)) { +- result.add(name); +- break; +- } +- // next character +- c = c + 1; +- } +-} +- +-String _getBaseNameFromExpression(Expression expression) { +- if (expression is AsExpression) { +- return _getBaseNameFromExpression(expression.expression); +- } else if (expression is ParenthesizedExpression) { +- return _getBaseNameFromExpression(expression.expression); +- } +- return _getBaseNameFromUnwrappedExpression(expression); +-} +- +-String _getBaseNameFromLocationInParent(Expression expression) { +- // value in named expression +- if (expression.parent is NamedExpression) { +- NamedExpression namedExpression = expression.parent as NamedExpression; +- if (namedExpression.expression == expression) { +- return namedExpression.name.label.name; +- } +- } +- // positional argument +- { +- ParameterElement parameter = expression.propagatedParameterElement; +- if (parameter == null) { +- parameter = expression.staticParameterElement; +- } +- if (parameter != null) { +- return parameter.displayName; +- } +- } +- // unknown +- return null; +-} +- +-String _getBaseNameFromUnwrappedExpression(Expression expression) { +- String name = null; +- // analyze expressions +- if (expression is SimpleIdentifier) { +- return expression.name; +- } else if (expression is PrefixedIdentifier) { +- return expression.identifier.name; +- } else if (expression is PropertyAccess) { +- return expression.propertyName.name; +- } else if (expression is MethodInvocation) { +- name = expression.methodName.name; +- } else if (expression is InstanceCreationExpression) { +- ConstructorName constructorName = expression.constructorName; +- TypeName typeName = constructorName.type; +- if (typeName != null) { +- Identifier typeNameIdentifier = typeName.name; +- // new ClassName() +- if (typeNameIdentifier is SimpleIdentifier) { +- return typeNameIdentifier.name; +- } +- // new prefix.name(); +- if (typeNameIdentifier is PrefixedIdentifier) { +- PrefixedIdentifier prefixed = typeNameIdentifier; +- // new prefix.ClassName() +- if (prefixed.prefix.staticElement is PrefixElement) { +- return prefixed.identifier.name; +- } +- // new ClassName.constructorName() +- return prefixed.prefix.name; +- } +- } +- } else if (expression is IndexExpression) { +- name = _getBaseNameFromExpression(expression.realTarget); +- if (name.endsWith('s')) { +- name = name.substring(0, name.length - 1); +- } +- } +- // strip known prefixes +- if (name != null) { +- for (int i = 0; i < _KNOWN_METHOD_NAME_PREFIXES.length; i++) { +- String curr = _KNOWN_METHOD_NAME_PREFIXES[i]; +- if (name.startsWith(curr)) { +- if (name == curr) { +- return null; +- } else if (isUpperCase(name.codeUnitAt(curr.length))) { +- return name.substring(curr.length); +- } +- } +- } +- } +- // done +- return name; +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart +deleted file mode 100644 +index fc0d7484fd8..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart ++++ /dev/null +@@ -1,183 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/resolver/scope.dart'; +- +-/** +- * Returns the [Element] exported from the given [LibraryElement]. +- */ +-Element getExportedElement(LibraryElement library, String name) { +- if (library == null) { +- return null; +- } +- return getExportNamespaceForLibrary(library)[name]; +-} +- +-/** +- * Returns the namespace of the given [ExportElement]. +- */ +-Map getExportNamespaceForDirective(ExportElement exp) { +- Namespace namespace = +- new NamespaceBuilder().createExportNamespaceForDirective(exp); +- return namespace.definedNames; +-} +- +-/** +- * Returns the export namespace of the given [LibraryElement]. +- */ +-Map getExportNamespaceForLibrary(LibraryElement library) { +- Namespace namespace = +- new NamespaceBuilder().createExportNamespaceForLibrary(library); +- return namespace.definedNames; +-} +- +-/** +- * Return the [ImportElement] that is referenced by [prefixNode], or `null` if +- * the node does not reference a prefix or if we cannot determine which import +- * is being referenced. +- */ +-ImportElement getImportElement(SimpleIdentifier prefixNode) { +- AstNode parent = prefixNode.parent; +- if (parent is ImportDirective) { +- return parent.element; +- } +- ImportElementInfo info = internal_getImportElementInfo(prefixNode); +- return info?.element; +-} +- +-/** +- * Return the [ImportElement] that declared [prefix] and imports [element]. +- * +- * [libraryElement] - the [LibraryElement] where reference is. +- * [prefix] - the import prefix, maybe `null`. +- * [element] - the referenced element. +- * [importElementsMap] - the cache of [Element]s imported by [ImportElement]s. +- */ +-ImportElement internal_getImportElement( +- LibraryElement libraryElement, +- String prefix, +- Element element, +- Map> importElementsMap) { +- // validate Element +- if (element == null) { +- return null; +- } +- if (element.enclosingElement is! CompilationUnitElement) { +- return null; +- } +- LibraryElement usedLibrary = element.library; +- // find ImportElement that imports used library with used prefix +- List candidates = null; +- for (ImportElement importElement in libraryElement.imports) { +- // required library +- if (importElement.importedLibrary != usedLibrary) { +- continue; +- } +- // required prefix +- PrefixElement prefixElement = importElement.prefix; +- if (prefix == null) { +- if (prefixElement != null) { +- continue; +- } +- } else { +- if (prefixElement == null) { +- continue; +- } +- if (prefix != prefixElement.name) { +- continue; +- } +- } +- // no combinators => only possible candidate +- if (importElement.combinators.length == 0) { +- return importElement; +- } +- // OK, we have candidate +- if (candidates == null) { +- candidates = []; +- } +- candidates.add(importElement); +- } +- // no candidates, probably element is defined in this library +- if (candidates == null) { +- return null; +- } +- // one candidate +- if (candidates.length == 1) { +- return candidates[0]; +- } +- // ensure that each ImportElement has set of elements +- for (ImportElement importElement in candidates) { +- if (importElementsMap.containsKey(importElement)) { +- continue; +- } +- Namespace namespace = +- new NamespaceBuilder().createImportNamespaceForDirective(importElement); +- Set elements = new Set.from(namespace.definedNames.values); +- importElementsMap[importElement] = elements; +- } +- // use import namespace to choose correct one +- for (ImportElement importElement in importElementsMap.keys) { +- Set elements = importElementsMap[importElement]; +- if (elements.contains(element)) { +- return importElement; +- } +- } +- // not found +- return null; +-} +- +-/** +- * Returns the [ImportElementInfo] with the [ImportElement] that is referenced +- * by [prefixNode] with a [PrefixElement], maybe `null`. +- */ +-ImportElementInfo internal_getImportElementInfo(SimpleIdentifier prefixNode) { +- ImportElementInfo info = new ImportElementInfo(); +- // prepare environment +- AstNode parent = prefixNode.parent; +- CompilationUnit unit = +- prefixNode.getAncestor((node) => node is CompilationUnit); +- LibraryElement libraryElement = +- resolutionMap.elementDeclaredByCompilationUnit(unit).library; +- // prepare used element +- Element usedElement = null; +- if (parent is PrefixedIdentifier) { +- PrefixedIdentifier prefixed = parent; +- if (prefixed.prefix == prefixNode) { +- usedElement = prefixed.staticElement; +- info.periodEnd = prefixed.period.end; +- } +- } +- if (parent is MethodInvocation) { +- MethodInvocation invocation = parent; +- if (invocation.target == prefixNode) { +- usedElement = invocation.methodName.staticElement; +- info.periodEnd = invocation.operator.end; +- } +- } +- // we need used Element +- if (usedElement == null) { +- return null; +- } +- // find ImportElement +- String prefix = prefixNode.name; +- Map> importElementsMap = {}; +- info.element = internal_getImportElement( +- libraryElement, prefix, usedElement, importElementsMap); +- if (info.element == null) { +- return null; +- } +- return info; +-} +- +-/** +- * Information about [ImportElement] and place where it is referenced using +- * [PrefixElement]. +- */ +-class ImportElementInfo { +- ImportElement element; +- int periodEnd; +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart +deleted file mode 100644 +index 83a673c0e90..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart ++++ /dev/null +@@ -1,250 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/src/error/codes.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- hide AnalysisError, Element; +- +-/** +- * Organizer of directives in the [unit]. +- */ +-class DirectiveOrganizer { +- final String initialCode; +- final CompilationUnit unit; +- final List errors; +- final bool removeUnresolved; +- final bool removeUnused; +- String code; +- String endOfLine; +- +- DirectiveOrganizer(this.initialCode, this.unit, this.errors, +- {this.removeUnresolved: true, this.removeUnused: true}) { +- this.code = initialCode; +- this.endOfLine = getEOL(code); +- } +- +- /** +- * Return the [SourceEdit]s that organize directives in the [unit]. +- */ +- List organize() { +- _organizeDirectives(); +- // prepare edits +- List edits = []; +- if (code != initialCode) { +- int suffixLength = findCommonSuffix(initialCode, code); +- SourceEdit edit = new SourceEdit(0, initialCode.length - suffixLength, +- code.substring(0, code.length - suffixLength)); +- edits.add(edit); +- } +- return edits; +- } +- +- bool _isUnresolvedUri(UriBasedDirective directive) { +- for (AnalysisError error in errors) { +- ErrorCode errorCode = error.errorCode; +- if ((errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST || +- errorCode == CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED) && +- directive.uri.offset == error.offset) { +- return true; +- } +- } +- return false; +- } +- +- bool _isUnusedImport(UriBasedDirective directive) { +- for (AnalysisError error in errors) { +- if ((error.errorCode == HintCode.DUPLICATE_IMPORT || +- error.errorCode == HintCode.UNUSED_IMPORT) && +- directive.uri.offset == error.offset) { +- return true; +- } +- } +- return false; +- } +- +- /** +- * Oraganize all [Directive]s. +- */ +- void _organizeDirectives() { +- List<_DirectiveInfo> directives = []; +- for (Directive directive in unit.directives) { +- if (directive is UriBasedDirective) { +- _DirectivePriority priority = getDirectivePriority(directive); +- if (priority != null) { +- int offset = directive.offset; +- int length = directive.length; +- String text = code.substring(offset, offset + length); +- String uriContent = directive.uri.stringValue; +- directives +- .add(new _DirectiveInfo(directive, priority, uriContent, text)); +- } +- } +- } +- // nothing to do +- if (directives.isEmpty) { +- return; +- } +- int firstDirectiveOffset = directives.first.directive.offset; +- int lastDirectiveEnd = directives.last.directive.end; +- // sort +- directives.sort(); +- // append directives with grouping +- String directivesCode; +- { +- StringBuffer sb = new StringBuffer(); +- _DirectivePriority currentPriority = null; +- for (_DirectiveInfo directiveInfo in directives) { +- if (removeUnresolved && _isUnresolvedUri(directiveInfo.directive)) { +- continue; +- } +- if (removeUnused && _isUnusedImport(directiveInfo.directive)) { +- continue; +- } +- if (currentPriority != directiveInfo.priority) { +- if (sb.length != 0) { +- sb.write(endOfLine); +- } +- currentPriority = directiveInfo.priority; +- } +- sb.write(directiveInfo.text); +- sb.write(endOfLine); +- } +- directivesCode = sb.toString(); +- directivesCode = directivesCode.trimRight(); +- } +- // append comment tokens which otherwise would be removed completely +- { +- bool firstCommentToken = true; +- Token token = unit.beginToken; +- while (token != null && +- token.type != TokenType.EOF && +- token.end < lastDirectiveEnd) { +- Token commentToken = token.precedingComments; +- while (commentToken != null) { +- int offset = commentToken.offset; +- int end = commentToken.end; +- if (offset > firstDirectiveOffset && offset < lastDirectiveEnd) { +- if (firstCommentToken) { +- directivesCode += endOfLine; +- firstCommentToken = false; +- } +- directivesCode += code.substring(offset, end) + endOfLine; +- } +- commentToken = commentToken.next; +- } +- token = token.next; +- } +- } +- // prepare code +- String beforeDirectives = code.substring(0, firstDirectiveOffset); +- String afterDirectives = code.substring(lastDirectiveEnd); +- code = beforeDirectives + directivesCode + afterDirectives; +- } +- +- static _DirectivePriority getDirectivePriority(UriBasedDirective directive) { +- String uriContent = directive.uri.stringValue; +- if (directive is ImportDirective) { +- if (uriContent.startsWith("dart:")) { +- return _DirectivePriority.IMPORT_SDK; +- } else if (uriContent.startsWith("package:")) { +- return _DirectivePriority.IMPORT_PKG; +- } else if (uriContent.contains('://')) { +- return _DirectivePriority.IMPORT_OTHER; +- } else { +- return _DirectivePriority.IMPORT_REL; +- } +- } +- if (directive is ExportDirective) { +- if (uriContent.startsWith("dart:")) { +- return _DirectivePriority.EXPORT_SDK; +- } else if (uriContent.startsWith("package:")) { +- return _DirectivePriority.EXPORT_PKG; +- } else if (uriContent.contains('://')) { +- return _DirectivePriority.EXPORT_OTHER; +- } else { +- return _DirectivePriority.EXPORT_REL; +- } +- } +- if (directive is PartDirective) { +- return _DirectivePriority.PART; +- } +- return null; +- } +- +- /** +- * Return the EOL to use for [code]. +- */ +- static String getEOL(String code) { +- if (code.contains('\r\n')) { +- return '\r\n'; +- } else { +- return '\n'; +- } +- } +-} +- +-class _DirectiveInfo implements Comparable<_DirectiveInfo> { +- final UriBasedDirective directive; +- final _DirectivePriority priority; +- final String uri; +- final String text; +- +- _DirectiveInfo(this.directive, this.priority, this.uri, this.text); +- +- @override +- int compareTo(_DirectiveInfo other) { +- if (priority == other.priority) { +- return _compareUri(uri, other.uri); +- } +- return priority.ordinal - other.priority.ordinal; +- } +- +- @override +- String toString() => '(priority=$priority; text=$text)'; +- +- static int _compareUri(String a, String b) { +- List aList = _splitUri(a); +- List bList = _splitUri(b); +- int result; +- if ((result = aList[0].compareTo(bList[0])) != 0) return result; +- if ((result = aList[1].compareTo(bList[1])) != 0) return result; +- return 0; +- } +- +- /** +- * Split the given [uri] like `package:some.name/and/path.dart` into a list +- * like `[package:some.name, and/path.dart]`. +- */ +- static List _splitUri(String uri) { +- int index = uri.indexOf('/'); +- if (index == -1) { +- return [uri, '']; +- } +- return [uri.substring(0, index), uri.substring(index + 1)]; +- } +-} +- +-class _DirectivePriority { +- static const IMPORT_SDK = const _DirectivePriority('IMPORT_SDK', 0); +- static const IMPORT_PKG = const _DirectivePriority('IMPORT_PKG', 1); +- static const IMPORT_OTHER = const _DirectivePriority('IMPORT_OTHER', 2); +- static const IMPORT_REL = const _DirectivePriority('IMPORT_REL', 3); +- static const EXPORT_SDK = const _DirectivePriority('EXPORT_SDK', 4); +- static const EXPORT_PKG = const _DirectivePriority('EXPORT_PKG', 5); +- static const EXPORT_OTHER = const _DirectivePriority('EXPORT_OTHER', 6); +- static const EXPORT_REL = const _DirectivePriority('EXPORT_REL', 7); +- static const PART = const _DirectivePriority('PART', 8); +- +- final String name; +- final int ordinal; +- +- const _DirectivePriority(this.name, this.ordinal); +- +- @override +- String toString() => name; +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart +deleted file mode 100644 +index 9b026bd351f..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart ++++ /dev/null +@@ -1,142 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * A visitor for visiting [AstNode]s covered by a selection [SourceRange]. +- */ +-class SelectionAnalyzer extends GeneralizingAstVisitor { +- final SourceRange selection; +- +- AstNode _coveringNode; +- List _selectedNodes; +- +- SelectionAnalyzer(this.selection); +- +- /** +- * Return the [AstNode] with the shortest length which completely covers the +- * specified selection. +- */ +- AstNode get coveringNode => _coveringNode; +- +- /** +- * Returns the first selected [AstNode], may be `null`. +- */ +- AstNode get firstSelectedNode { +- if (_selectedNodes == null || _selectedNodes.isEmpty) { +- return null; +- } +- return _selectedNodes[0]; +- } +- +- /** +- * Returns `true` if there are [AstNode]s fully covered by the +- * selection [SourceRange]. +- */ +- bool get hasSelectedNodes => +- _selectedNodes != null && !_selectedNodes.isEmpty; +- +- /** +- * Returns `true` if there was no selected nodes yet. +- */ +- bool get isFirstNode => _selectedNodes == null; +- +- /** +- * Returns the last selected [AstNode], may be `null`. +- */ +- AstNode get lastSelectedNode { +- if (_selectedNodes == null || _selectedNodes.isEmpty) { +- return null; +- } +- return _selectedNodes[_selectedNodes.length - 1]; +- } +- +- /** +- * Returns the [SourceRange] which covers selected [AstNode]s, may be `null` +- * if there are no [AstNode]s under the selection. +- */ +- SourceRange get selectedNodeRange { +- if (_selectedNodes == null || _selectedNodes.isEmpty) { +- return null; +- } +- AstNode firstNode = _selectedNodes[0]; +- AstNode lastNode = _selectedNodes[_selectedNodes.length - 1]; +- return range.startEnd(firstNode, lastNode); +- } +- +- /** +- * Return the [AstNode]s fully covered by the selection [SourceRange]. +- */ +- List get selectedNodes { +- if (_selectedNodes == null || _selectedNodes.isEmpty) { +- return []; +- } +- return _selectedNodes; +- } +- +- /** +- * Adds first selected [AstNode]. +- */ +- void handleFirstSelectedNode(AstNode node) { +- _selectedNodes = []; +- _selectedNodes.add(node); +- } +- +- /** +- * Adds second or more selected [AstNode]. +- */ +- void handleNextSelectedNode(AstNode node) { +- if (firstSelectedNode.parent == node.parent) { +- _selectedNodes.add(node); +- } +- } +- +- /** +- * Notifies that selection ends in given [AstNode]. +- */ +- void handleSelectionEndsIn(AstNode node) {} +- +- /** +- * Notifies that selection starts in given [AstNode]. +- */ +- void handleSelectionStartsIn(AstNode node) {} +- +- /** +- * Resets selected nodes. +- */ +- void reset() { +- _selectedNodes = null; +- } +- +- @override +- Object visitNode(AstNode node) { +- SourceRange nodeRange = range.node(node); +- if (selection.covers(nodeRange)) { +- if (isFirstNode) { +- handleFirstSelectedNode(node); +- } else { +- handleNextSelectedNode(node); +- } +- return null; +- } else if (selection.coveredBy(nodeRange)) { +- _coveringNode = node; +- node.visitChildren(this); +- return null; +- } else if (selection.startsIn(nodeRange)) { +- handleSelectionStartsIn(node); +- node.visitChildren(this); +- return null; +- } else if (selection.endsIn(nodeRange)) { +- handleSelectionEndsIn(node); +- node.visitChildren(this); +- return null; +- } +- // no intersection +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart +deleted file mode 100644 +index 00175668a0f..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart ++++ /dev/null +@@ -1,504 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +- +-/** +- * Sorter for unit/class members. +- */ +-class MemberSorter { +- static List<_PriorityItem> _PRIORITY_ITEMS = [ +- new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_MAIN, false), +- new _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, false), +- new _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, true), +- new _PriorityItem(false, _MemberKind.UNIT_VARIABLE, false), +- new _PriorityItem(false, _MemberKind.UNIT_VARIABLE, true), +- new _PriorityItem(false, _MemberKind.UNIT_ACCESSOR, false), +- new _PriorityItem(false, _MemberKind.UNIT_ACCESSOR, true), +- new _PriorityItem(false, _MemberKind.UNIT_FUNCTION, false), +- new _PriorityItem(false, _MemberKind.UNIT_FUNCTION, true), +- new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_TYPE, false), +- new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_TYPE, true), +- new _PriorityItem(false, _MemberKind.UNIT_CLASS, false), +- new _PriorityItem(false, _MemberKind.UNIT_CLASS, true), +- new _PriorityItem(true, _MemberKind.CLASS_FIELD, false), +- new _PriorityItem(true, _MemberKind.CLASS_ACCESSOR, false), +- new _PriorityItem(true, _MemberKind.CLASS_ACCESSOR, true), +- new _PriorityItem(false, _MemberKind.CLASS_FIELD, false), +- new _PriorityItem(false, _MemberKind.CLASS_CONSTRUCTOR, false), +- new _PriorityItem(false, _MemberKind.CLASS_CONSTRUCTOR, true), +- new _PriorityItem(false, _MemberKind.CLASS_ACCESSOR, false), +- new _PriorityItem(false, _MemberKind.CLASS_ACCESSOR, true), +- new _PriorityItem(false, _MemberKind.CLASS_METHOD, false), +- new _PriorityItem(false, _MemberKind.CLASS_METHOD, true), +- new _PriorityItem(true, _MemberKind.CLASS_METHOD, false), +- new _PriorityItem(true, _MemberKind.CLASS_METHOD, true) +- ]; +- +- final String initialCode; +- final CompilationUnit unit; +- String code; +- String endOfLine; +- +- MemberSorter(this.initialCode, this.unit) { +- this.code = initialCode; +- this.endOfLine = getEOL(code); +- } +- +- /** +- * Return the [SourceEdit]s that sort [unit]. +- */ +- List sort() { +- _sortClassesMembers(); +- _sortUnitMembers(); +- // Must sort unit directives last because it may insert newlines, which +- // would confuse the offsets used by the other sort functions. +- _sortUnitDirectives(); +- // prepare edits +- List edits = []; +- if (code != initialCode) { +- SimpleDiff diff = computeSimpleDiff(initialCode, code); +- SourceEdit edit = +- new SourceEdit(diff.offset, diff.length, diff.replacement); +- edits.add(edit); +- } +- return edits; +- } +- +- void _sortAndReorderMembers(List<_MemberInfo> members) { +- List<_MemberInfo> membersSorted = _getSortedMembers(members); +- int size = membersSorted.length; +- for (int i = 0; i < size; i++) { +- _MemberInfo newInfo = membersSorted[size - 1 - i]; +- _MemberInfo oldInfo = members[size - 1 - i]; +- if (newInfo != oldInfo) { +- String beforeCode = code.substring(0, oldInfo.offset); +- String afterCode = code.substring(oldInfo.end); +- code = beforeCode + newInfo.text + afterCode; +- } +- } +- } +- +- /** +- * Sorts all members of all [ClassDeclaration]s. +- */ +- void _sortClassesMembers() { +- for (CompilationUnitMember unitMember in unit.declarations) { +- if (unitMember is ClassDeclaration) { +- ClassDeclaration classDeclaration = unitMember; +- _sortClassMembers(classDeclaration); +- } +- } +- } +- +- /** +- * Sorts all members of the given [ClassDeclaration]. +- */ +- void _sortClassMembers(ClassDeclaration classDeclaration) { +- List<_MemberInfo> members = <_MemberInfo>[]; +- for (ClassMember member in classDeclaration.members) { +- _MemberKind kind = null; +- bool isStatic = false; +- String name = null; +- if (member is ConstructorDeclaration) { +- kind = _MemberKind.CLASS_CONSTRUCTOR; +- SimpleIdentifier nameNode = member.name; +- if (nameNode == null) { +- name = ""; +- } else { +- name = nameNode.name; +- } +- } +- if (member is FieldDeclaration) { +- FieldDeclaration fieldDeclaration = member; +- List fields = fieldDeclaration.fields.variables; +- if (!fields.isEmpty) { +- kind = _MemberKind.CLASS_FIELD; +- isStatic = fieldDeclaration.isStatic; +- name = fields[0].name.name; +- } +- } +- if (member is MethodDeclaration) { +- MethodDeclaration method = member; +- isStatic = method.isStatic; +- name = method.name.name; +- if (method.isGetter) { +- kind = _MemberKind.CLASS_ACCESSOR; +- name += " getter"; +- } else if (method.isSetter) { +- kind = _MemberKind.CLASS_ACCESSOR; +- name += " setter"; +- } else { +- kind = _MemberKind.CLASS_METHOD; +- } +- } +- if (name != null) { +- _PriorityItem item = new _PriorityItem.forName(isStatic, name, kind); +- int offset = member.offset; +- int length = member.length; +- String text = code.substring(offset, offset + length); +- members.add(new _MemberInfo(item, name, offset, length, text)); +- } +- } +- // do sort +- _sortAndReorderMembers(members); +- } +- +- /** +- * Sorts all [Directive]s. +- */ +- void _sortUnitDirectives() { +- bool hasLibraryDirective = false; +- List<_DirectiveInfo> directives = []; +- for (Directive directive in unit.directives) { +- if (directive is LibraryDirective) { +- hasLibraryDirective = true; +- } +- if (directive is! UriBasedDirective) { +- continue; +- } +- UriBasedDirective uriDirective = directive as UriBasedDirective; +- String uriContent = uriDirective.uri.stringValue; +- _DirectivePriority kind = null; +- if (directive is ImportDirective) { +- if (uriContent.startsWith("dart:")) { +- kind = _DirectivePriority.IMPORT_SDK; +- } else if (uriContent.startsWith("package:")) { +- kind = _DirectivePriority.IMPORT_PKG; +- } else if (uriContent.contains('://')) { +- kind = _DirectivePriority.IMPORT_OTHER; +- } else { +- kind = _DirectivePriority.IMPORT_REL; +- } +- } +- if (directive is ExportDirective) { +- if (uriContent.startsWith("dart:")) { +- kind = _DirectivePriority.EXPORT_SDK; +- } else if (uriContent.startsWith("package:")) { +- kind = _DirectivePriority.EXPORT_PKG; +- } else if (uriContent.contains('://')) { +- kind = _DirectivePriority.EXPORT_OTHER; +- } else { +- kind = _DirectivePriority.EXPORT_REL; +- } +- } +- if (directive is PartDirective) { +- kind = _DirectivePriority.PART; +- } +- if (kind != null) { +- String documentationText; +- if (directive.documentationComment != null) { +- documentationText = code.substring( +- directive.documentationComment.offset, +- directive.documentationComment.end); +- } +- String annotationText; +- if (directive.metadata.beginToken != null) { +- annotationText = code.substring(directive.metadata.beginToken.offset, +- directive.metadata.endToken.end); +- } +- int offset = directive.firstTokenAfterCommentAndMetadata.offset; +- int length = directive.end - offset; +- String text = code.substring(offset, offset + length); +- directives.add(new _DirectiveInfo(directive, kind, uriContent, +- documentationText, annotationText, text)); +- } +- } +- // nothing to do +- if (directives.isEmpty) { +- return; +- } +- int firstDirectiveOffset = directives[0].directive.offset; +- int lastDirectiveEnd = directives[directives.length - 1].directive.end; +- // Without a library directive, the library comment is the comment of the +- // first directive. +- _DirectiveInfo libraryDocumentationDirective; +- if (!hasLibraryDirective && directives.isNotEmpty) { +- libraryDocumentationDirective = directives.first; +- } +- // do sort +- directives.sort(); +- // append directives with grouping +- String directivesCode; +- { +- StringBuffer sb = new StringBuffer(); +- String endOfLine = this.endOfLine; +- _DirectivePriority currentPriority = null; +- bool firstOutputDirective = true; +- for (_DirectiveInfo directive in directives) { +- if (currentPriority != directive.priority) { +- if (sb.length != 0) { +- sb.write(endOfLine); +- } +- currentPriority = directive.priority; +- } +- if (directive != libraryDocumentationDirective && +- directive.documentationText != null) { +- sb.write(directive.documentationText); +- sb.write(endOfLine); +- } +- if (firstOutputDirective) { +- firstOutputDirective = false; +- if (libraryDocumentationDirective != null && +- libraryDocumentationDirective.documentationText != null) { +- sb.write(libraryDocumentationDirective.documentationText); +- sb.write(endOfLine); +- } +- } +- if (directive.annotationText != null) { +- sb.write(directive.annotationText); +- sb.write(endOfLine); +- } +- sb.write(directive.text); +- sb.write(endOfLine); +- } +- directivesCode = sb.toString(); +- directivesCode = directivesCode.trimRight(); +- } +- // prepare code +- String beforeDirectives = code.substring(0, firstDirectiveOffset); +- String afterDirectives = code.substring(lastDirectiveEnd); +- code = beforeDirectives + directivesCode + afterDirectives; +- } +- +- /** +- * Sorts all [CompilationUnitMember]s. +- */ +- void _sortUnitMembers() { +- List<_MemberInfo> members = []; +- for (CompilationUnitMember member in unit.declarations) { +- _MemberKind kind = null; +- String name = null; +- if (member is ClassDeclaration) { +- kind = _MemberKind.UNIT_CLASS; +- name = member.name.name; +- } +- if (member is ClassTypeAlias) { +- kind = _MemberKind.UNIT_CLASS; +- name = member.name.name; +- } +- if (member is EnumDeclaration) { +- kind = _MemberKind.UNIT_CLASS; +- name = member.name.name; +- } +- if (member is FunctionDeclaration) { +- FunctionDeclaration function = member; +- name = function.name.name; +- if (function.isGetter) { +- kind = _MemberKind.UNIT_ACCESSOR; +- name += " getter"; +- } else if (function.isSetter) { +- kind = _MemberKind.UNIT_ACCESSOR; +- name += " setter"; +- } else { +- if (name == 'main') { +- kind = _MemberKind.UNIT_FUNCTION_MAIN; +- } else { +- kind = _MemberKind.UNIT_FUNCTION; +- } +- } +- } +- if (member is FunctionTypeAlias) { +- kind = _MemberKind.UNIT_FUNCTION_TYPE; +- name = member.name.name; +- } +- if (member is TopLevelVariableDeclaration) { +- TopLevelVariableDeclaration variableDeclaration = member; +- List variables = +- variableDeclaration.variables.variables; +- if (!variables.isEmpty) { +- if (variableDeclaration.variables.isConst) { +- kind = _MemberKind.UNIT_VARIABLE_CONST; +- } else { +- kind = _MemberKind.UNIT_VARIABLE; +- } +- name = variables[0].name.name; +- } +- } +- if (name != null) { +- _PriorityItem item = new _PriorityItem.forName(false, name, kind); +- int offset = member.offset; +- int length = member.length; +- String text = code.substring(offset, offset + length); +- members.add(new _MemberInfo(item, name, offset, length, text)); +- } +- } +- // do sort +- _sortAndReorderMembers(members); +- } +- +- /** +- * Return the EOL to use for [code]. +- */ +- static String getEOL(String code) { +- if (code.contains('\r\n')) { +- return '\r\n'; +- } else { +- return '\n'; +- } +- } +- +- static int _getPriority(_PriorityItem item) { +- for (int i = 0; i < _PRIORITY_ITEMS.length; i++) { +- if (_PRIORITY_ITEMS[i] == item) { +- return i; +- } +- } +- return 0; +- } +- +- static List<_MemberInfo> _getSortedMembers(List<_MemberInfo> members) { +- List<_MemberInfo> membersSorted = new List<_MemberInfo>.from(members); +- membersSorted.sort((_MemberInfo o1, _MemberInfo o2) { +- int priority1 = _getPriority(o1.item); +- int priority2 = _getPriority(o2.item); +- if (priority1 == priority2) { +- // don't reorder class fields +- if (o1.item.kind == _MemberKind.CLASS_FIELD) { +- return o1.offset - o2.offset; +- } +- // sort all other members by name +- String name1 = o1.name.toLowerCase(); +- String name2 = o2.name.toLowerCase(); +- return name1.compareTo(name2); +- } +- return priority1 - priority2; +- }); +- return membersSorted; +- } +-} +- +-class _DirectiveInfo implements Comparable<_DirectiveInfo> { +- final Directive directive; +- final _DirectivePriority priority; +- final String uri; +- final String documentationText; +- final String annotationText; +- final String text; +- +- _DirectiveInfo(this.directive, this.priority, this.uri, +- this.documentationText, this.annotationText, this.text); +- +- @override +- int compareTo(_DirectiveInfo other) { +- if (priority == other.priority) { +- return _compareUri(uri, other.uri); +- } +- return priority.ordinal - other.priority.ordinal; +- } +- +- @override +- String toString() => '(priority=$priority; text=$text)'; +- +- static int _compareUri(String a, String b) { +- List aList = _splitUri(a); +- List bList = _splitUri(b); +- int result; +- if ((result = aList[0].compareTo(bList[0])) != 0) return result; +- if ((result = aList[1].compareTo(bList[1])) != 0) return result; +- return 0; +- } +- +- /** +- * Split the given [uri] like `package:some.name/and/path.dart` into a list +- * like `[package:some.name, and/path.dart]`. +- */ +- static List _splitUri(String uri) { +- int index = uri.indexOf('/'); +- if (index == -1) { +- return [uri, '']; +- } +- return [uri.substring(0, index), uri.substring(index + 1)]; +- } +-} +- +-class _DirectivePriority { +- static const IMPORT_SDK = const _DirectivePriority('IMPORT_SDK', 0); +- static const IMPORT_PKG = const _DirectivePriority('IMPORT_PKG', 1); +- static const IMPORT_OTHER = const _DirectivePriority('IMPORT_OTHER', 2); +- static const IMPORT_REL = const _DirectivePriority('IMPORT_REL', 3); +- static const EXPORT_SDK = const _DirectivePriority('EXPORT_SDK', 4); +- static const EXPORT_PKG = const _DirectivePriority('EXPORT_PKG', 5); +- static const EXPORT_OTHER = const _DirectivePriority('EXPORT_OTHER', 6); +- static const EXPORT_REL = const _DirectivePriority('EXPORT_REL', 7); +- static const PART = const _DirectivePriority('PART', 8); +- +- final String name; +- final int ordinal; +- +- const _DirectivePriority(this.name, this.ordinal); +- +- @override +- String toString() => name; +-} +- +-class _MemberInfo { +- final _PriorityItem item; +- final String name; +- final int offset; +- final int length; +- final int end; +- final String text; +- +- _MemberInfo(this.item, this.name, int offset, int length, this.text) +- : offset = offset, +- length = length, +- end = offset + length; +- +- @override +- String toString() { +- return '(priority=$item; name=$name; offset=$offset; length=$length)'; +- } +-} +- +-class _MemberKind { +- static const UNIT_FUNCTION_MAIN = const _MemberKind('UNIT_FUNCTION_MAIN', 0); +- static const UNIT_ACCESSOR = const _MemberKind('UNIT_ACCESSOR', 1); +- static const UNIT_FUNCTION = const _MemberKind('UNIT_FUNCTION', 2); +- static const UNIT_FUNCTION_TYPE = const _MemberKind('UNIT_FUNCTION_TYPE', 3); +- static const UNIT_CLASS = const _MemberKind('UNIT_CLASS', 4); +- static const UNIT_VARIABLE_CONST = const _MemberKind('UNIT_VARIABLE', 5); +- static const UNIT_VARIABLE = const _MemberKind('UNIT_VARIABLE', 6); +- static const CLASS_ACCESSOR = const _MemberKind('CLASS_ACCESSOR', 7); +- static const CLASS_CONSTRUCTOR = const _MemberKind('CLASS_CONSTRUCTOR', 8); +- static const CLASS_FIELD = const _MemberKind('CLASS_FIELD', 9); +- static const CLASS_METHOD = const _MemberKind('CLASS_METHOD', 10); +- +- final String name; +- final int ordinal; +- +- const _MemberKind(this.name, this.ordinal); +- +- @override +- String toString() => name; +-} +- +-class _PriorityItem { +- final _MemberKind kind; +- final bool isPrivate; +- final bool isStatic; +- +- _PriorityItem(this.isStatic, this.kind, this.isPrivate); +- +- factory _PriorityItem.forName(bool isStatic, String name, _MemberKind kind) { +- bool isPrivate = Identifier.isPrivateName(name); +- return new _PriorityItem(isStatic, kind, isPrivate); +- } +- +- @override +- bool operator ==(Object obj) { +- _PriorityItem other = obj as _PriorityItem; +- if (kind == _MemberKind.CLASS_FIELD) { +- return other.kind == kind && other.isStatic == isStatic; +- } +- return other.kind == kind && +- other.isPrivate == isPrivate && +- other.isStatic == isStatic; +- } +- +- @override +- String toString() => kind.toString(); +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/source_buffer.dart b/pkg/analysis_server/lib/src/services/correction/source_buffer.dart +deleted file mode 100644 +index 24d6848300b..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/source_buffer.dart ++++ /dev/null +@@ -1,99 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * Helper for building Dart source with linked positions. +- */ +-class SourceBuilder { +- final String file; +- final int offset; +- final StringBuffer _buffer = new StringBuffer(); +- +- final Map linkedPositionGroups = +- {}; +- LinkedEditGroup _currentLinkedPositionGroup; +- int _currentPositionStart; +- int _exitOffset; +- +- SourceBuilder(this.file, this.offset); +- +- SourceBuilder.buffer() +- : file = null, +- offset = 0; +- +- /** +- * Returns the exit offset, maybe `null` if not set. +- */ +- int get exitOffset { +- if (_exitOffset == null) { +- return null; +- } +- return offset + _exitOffset; +- } +- +- int get length => _buffer.length; +- +- void addSuggestion(LinkedEditSuggestionKind kind, String value) { +- var suggestion = new LinkedEditSuggestion(value, kind); +- _currentLinkedPositionGroup.addSuggestion(suggestion); +- } +- +- void addSuggestions(LinkedEditSuggestionKind kind, List values) { +- values.forEach((value) => addSuggestion(kind, value)); +- } +- +- /** +- * Appends [s] to the buffer. +- */ +- SourceBuilder append(String s) { +- _buffer.write(s); +- return this; +- } +- +- /** +- * Ends position started using [startPosition]. +- */ +- void endPosition() { +- assert(_currentLinkedPositionGroup != null); +- _addPosition(); +- _currentLinkedPositionGroup = null; +- } +- +- /** +- * Marks the current offset as an "exit" one. +- */ +- void setExitOffset() { +- _exitOffset = _buffer.length; +- } +- +- /** +- * Marks start of a new linked position for the group with the given ID. +- */ +- void startPosition(String id) { +- assert(_currentLinkedPositionGroup == null); +- _currentLinkedPositionGroup = linkedPositionGroups[id]; +- if (_currentLinkedPositionGroup == null) { +- _currentLinkedPositionGroup = new LinkedEditGroup.empty(); +- linkedPositionGroups[id] = _currentLinkedPositionGroup; +- } +- _currentPositionStart = _buffer.length; +- } +- +- @override +- String toString() => _buffer.toString(); +- +- /** +- * Adds position location [SourceRange] using current fields. +- */ +- void _addPosition() { +- int start = offset + _currentPositionStart; +- int end = offset + _buffer.length; +- int length = end - start; +- Position position = new Position(file, start); +- _currentLinkedPositionGroup.addPosition(position, length); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart +deleted file mode 100644 +index 4199f27a4aa..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart ++++ /dev/null +@@ -1,230 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/services/correction/selection_analyzer.dart'; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/scanner/reader.dart'; +-import 'package:analyzer/src/dart/scanner/scanner.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * Returns [Token]s of the given Dart source, not `null`, may be empty if no +- * tokens or some exception happens. +- */ +-List _getTokens(String text) { +- try { +- List tokens = []; +- Scanner scanner = new Scanner(null, new CharSequenceReader(text), null); +- Token token = scanner.tokenize(); +- while (token.type != TokenType.EOF) { +- tokens.add(token); +- token = token.next; +- } +- return tokens; +- } catch (e) { +- return new List(0); +- } +-} +- +-/** +- * Analyzer to check if a selection covers a valid set of statements of AST. +- */ +-class StatementAnalyzer extends SelectionAnalyzer { +- final CompilationUnit unit; +- +- RefactoringStatus _status = new RefactoringStatus(); +- +- StatementAnalyzer(this.unit, SourceRange selection) : super(selection); +- +- /** +- * Returns the [RefactoringStatus] result of selection checking. +- */ +- RefactoringStatus get status => _status; +- +- /** +- * Records fatal error with given message and [Location]. +- */ +- void invalidSelection(String message, [Location context]) { +- if (!_status.hasFatalError) { +- _status.addFatalError(message, context); +- } +- reset(); +- } +- +- @override +- Object visitCompilationUnit(CompilationUnit node) { +- super.visitCompilationUnit(node); +- if (!hasSelectedNodes) { +- return null; +- } +- // check that selection does not begin/end in comment +- { +- int selectionStart = selection.offset; +- int selectionEnd = selection.end; +- List commentRanges = getCommentRanges(unit); +- for (SourceRange commentRange in commentRanges) { +- if (commentRange.contains(selectionStart)) { +- invalidSelection("Selection begins inside a comment."); +- } +- if (commentRange.containsExclusive(selectionEnd)) { +- invalidSelection("Selection ends inside a comment."); +- } +- } +- } +- // more checks +- if (!_status.hasFatalError) { +- _checkSelectedNodes(node); +- } +- return null; +- } +- +- @override +- Object visitDoStatement(DoStatement node) { +- super.visitDoStatement(node); +- List selectedNodes = this.selectedNodes; +- if (_contains(selectedNodes, node.body)) { +- invalidSelection( +- "Operation not applicable to a 'do' statement's body and expression."); +- } +- return null; +- } +- +- @override +- Object visitForStatement(ForStatement node) { +- super.visitForStatement(node); +- List selectedNodes = this.selectedNodes; +- bool containsInit = _contains(selectedNodes, node.initialization) || +- _contains(selectedNodes, node.variables); +- bool containsCondition = _contains(selectedNodes, node.condition); +- bool containsUpdaters = _containsAny(selectedNodes, node.updaters); +- bool containsBody = _contains(selectedNodes, node.body); +- if (containsInit && containsCondition) { +- invalidSelection( +- "Operation not applicable to a 'for' statement's initializer and condition."); +- } else if (containsCondition && containsUpdaters) { +- invalidSelection( +- "Operation not applicable to a 'for' statement's condition and updaters."); +- } else if (containsUpdaters && containsBody) { +- invalidSelection( +- "Operation not applicable to a 'for' statement's updaters and body."); +- } +- return null; +- } +- +- @override +- Object visitSwitchStatement(SwitchStatement node) { +- super.visitSwitchStatement(node); +- List selectedNodes = this.selectedNodes; +- List switchMembers = node.members; +- for (AstNode selectedNode in selectedNodes) { +- if (switchMembers.contains(selectedNode)) { +- invalidSelection( +- "Selection must either cover whole switch statement or parts of a single case block."); +- break; +- } +- } +- return null; +- } +- +- @override +- Object visitTryStatement(TryStatement node) { +- super.visitTryStatement(node); +- AstNode firstSelectedNode = this.firstSelectedNode; +- if (firstSelectedNode != null) { +- if (firstSelectedNode == node.body || +- firstSelectedNode == node.finallyBlock) { +- invalidSelection( +- "Selection must either cover whole try statement or parts of try, catch, or finally block."); +- } else { +- List catchClauses = node.catchClauses; +- for (CatchClause catchClause in catchClauses) { +- if (firstSelectedNode == catchClause || +- firstSelectedNode == catchClause.body || +- firstSelectedNode == catchClause.exceptionParameter) { +- invalidSelection( +- "Selection must either cover whole try statement or parts of try, catch, or finally block."); +- } +- } +- } +- } +- return null; +- } +- +- @override +- Object visitWhileStatement(WhileStatement node) { +- super.visitWhileStatement(node); +- List selectedNodes = this.selectedNodes; +- if (_contains(selectedNodes, node.condition) && +- _contains(selectedNodes, node.body)) { +- invalidSelection( +- "Operation not applicable to a while statement's expression and body."); +- } +- return null; +- } +- +- /** +- * Checks final selected [AstNode]s after processing [CompilationUnit]. +- */ +- void _checkSelectedNodes(CompilationUnit unit) { +- List nodes = selectedNodes; +- // some tokens before first selected node +- { +- AstNode firstNode = nodes[0]; +- SourceRange rangeBeforeFirstNode = +- range.startOffsetEndOffset(selection.offset, firstNode.offset); +- if (_hasTokens(rangeBeforeFirstNode)) { +- invalidSelection( +- "The beginning of the selection contains characters that " +- "do not belong to a statement.", +- newLocation_fromUnit(unit, rangeBeforeFirstNode)); +- } +- } +- // some tokens after last selected node +- { +- AstNode lastNode = nodes.last; +- SourceRange rangeAfterLastNode = +- range.startOffsetEndOffset(lastNode.end, selection.end); +- if (_hasTokens(rangeAfterLastNode)) { +- invalidSelection( +- "The end of the selection contains characters that " +- "do not belong to a statement.", +- newLocation_fromUnit(unit, rangeAfterLastNode)); +- } +- } +- } +- +- /** +- * Returns `true` if there are [Token]s in the given [SourceRange]. +- */ +- bool _hasTokens(SourceRange range) { +- CompilationUnitElement unitElement = unit.element; +- String fullText = unitElement.context.getContents(unitElement.source).data; +- String rangeText = fullText.substring(range.offset, range.end); +- return _getTokens(rangeText).isNotEmpty; +- } +- +- /** +- * Returns `true` if [nodes] contains [node]. +- */ +- static bool _contains(List nodes, AstNode node) => +- nodes.contains(node); +- +- /** +- * Returns `true` if [nodes] contains one of the [otherNodes]. +- */ +- static bool _containsAny(List nodes, List otherNodes) { +- for (AstNode otherNode in otherNodes) { +- if (nodes.contains(otherNode)) { +- return true; +- } +- } +- return false; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/status.dart b/pkg/analysis_server/lib/src/services/correction/status.dart +deleted file mode 100644 +index 5cc4cc3b8d8..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/status.dart ++++ /dev/null +@@ -1,179 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * An outcome of a condition checking operation. +- */ +-class RefactoringStatus { +- /** +- * The current severity of this [RefactoringStatus] - the maximum of the +- * severities of its [entries]. +- */ +- RefactoringProblemSeverity _severity = null; +- +- /** +- * A list of [RefactoringProblem]s. +- */ +- final List problems = []; +- +- /** +- * Creates a new OK [RefactoringStatus]. +- */ +- RefactoringStatus(); +- +- /** +- * Creates a new [RefactoringStatus] with the ERROR severity. +- */ +- factory RefactoringStatus.error(String msg, [Location location]) { +- RefactoringStatus status = new RefactoringStatus(); +- status.addError(msg, location); +- return status; +- } +- +- /** +- * Creates a new [RefactoringStatus] with the FATAL severity. +- */ +- factory RefactoringStatus.fatal(String msg, [Location location]) { +- RefactoringStatus status = new RefactoringStatus(); +- status.addFatalError(msg, location); +- return status; +- } +- +- /** +- * Creates a new [RefactoringStatus] with the WARNING severity. +- */ +- factory RefactoringStatus.warning(String msg, [Location location]) { +- RefactoringStatus status = new RefactoringStatus(); +- status.addWarning(msg, location); +- return status; +- } +- +- /** +- * Returns `true` if the severity is FATAL or ERROR. +- */ +- bool get hasError { +- return _severity == RefactoringProblemSeverity.FATAL || +- _severity == RefactoringProblemSeverity.ERROR; +- } +- +- /** +- * Returns `true` if the severity is FATAL. +- */ +- bool get hasFatalError => _severity == RefactoringProblemSeverity.FATAL; +- +- /** +- * Returns `true` if the severity is WARNING. +- */ +- bool get hasWarning => _severity == RefactoringProblemSeverity.WARNING; +- +- /** +- * Return `true` if the severity is `OK`. +- */ +- bool get isOK => _severity == null; +- +- /** +- * Returns the message of the [RefactoringProblem] with highest severity; +- * may be `null` if no problems. +- */ +- String get message { +- RefactoringProblem problem = this.problem; +- if (problem == null) { +- return null; +- } +- return problem.message; +- } +- +- /** +- * Returns the first [RefactoringProblem] with the highest severity. +- * +- * Returns `null` if no entries. +- */ +- RefactoringProblem get problem { +- for (RefactoringProblem problem in problems) { +- if (problem.severity == _severity) { +- return problem; +- } +- } +- return null; +- } +- +- /** +- * Returns the current severity of this [RefactoringStatus]. +- */ +- RefactoringProblemSeverity get severity => _severity; +- +- /** +- * Adds an ERROR problem with the given message and location. +- */ +- void addError(String msg, [Location location]) { +- _addProblem(new RefactoringProblem(RefactoringProblemSeverity.ERROR, msg, +- location: location)); +- } +- +- /** +- * Adds a FATAL problem with the given message and location. +- */ +- void addFatalError(String msg, [Location location]) { +- _addProblem(new RefactoringProblem(RefactoringProblemSeverity.FATAL, msg, +- location: location)); +- } +- +- /** +- * Merges [other] into this [RefactoringStatus]. +- * +- * The [other]'s entries are added to this. +- * +- * The resulting severity is the more severe of this and [other] severities. +- * +- * Merging with `null` is allowed - it has no effect. +- */ +- void addStatus(RefactoringStatus other) { +- if (other == null) { +- return; +- } +- problems.addAll(other.problems); +- _severity = RefactoringProblemSeverity.max(_severity, other.severity); +- } +- +- /** +- * Adds a WARNING problem with the given message and location. +- */ +- void addWarning(String msg, [Location location]) { +- _addProblem(new RefactoringProblem(RefactoringProblemSeverity.WARNING, msg, +- location: location)); +- } +- +- @override +- String toString() { +- StringBuffer sb = new StringBuffer(); +- sb.write("<"); +- if (_severity == null) { +- sb.write('OK'); +- } else { +- sb.write(_severity.name); +- } +- if (!isOK) { +- sb.write("\n"); +- for (RefactoringProblem problem in problems) { +- sb.write("\t"); +- sb.write(problem); +- sb.write("\n"); +- } +- } +- sb.write(">"); +- return sb.toString(); +- } +- +- /** +- * Adds the given [RefactoringProblem] and updates [severity]. +- */ +- void _addProblem(RefactoringProblem problem) { +- problems.add(problem); +- // update maximum severity +- RefactoringProblemSeverity severity = problem.severity; +- _severity = RefactoringProblemSeverity.max(_severity, severity); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/strings.dart b/pkg/analysis_server/lib/src/services/correction/strings.dart +deleted file mode 100644 +index 33a4c6a99d3..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/strings.dart ++++ /dev/null +@@ -1,263 +0,0 @@ +-// Copyright (c) 2014, 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:math'; +- +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +- +-/** +- * "$" +- */ +-const int CHAR_DOLLAR = 0x24; +- +-/** +- * "." +- */ +-const int CHAR_DOT = 0x2E; +- +-/** +- * "_" +- */ +-const int CHAR_UNDERSCORE = 0x5F; +- +-String capitalize(String str) { +- if (isEmpty(str)) { +- return str; +- } +- return str.substring(0, 1).toUpperCase() + str.substring(1); +-} +- +-int compareStrings(String a, String b) { +- if (a == b) { +- return 0; +- } +- if (a == null) { +- return 1; +- } +- if (b == null) { +- return -1; +- } +- return a.compareTo(b); +-} +- +-/** +- * Return a simple difference between the given [oldStr] and [newStr]. +- */ +-SimpleDiff computeSimpleDiff(String oldStr, String newStr) { +- int prefixLength = findCommonPrefix(oldStr, newStr); +- int suffixLength = findCommonSuffix(oldStr, newStr); +- while (prefixLength >= 0) { +- int oldReplaceLength = oldStr.length - prefixLength - suffixLength; +- int newReplaceLength = newStr.length - prefixLength - suffixLength; +- if (oldReplaceLength >= 0 && newReplaceLength >= 0) { +- return new SimpleDiff(prefixLength, oldReplaceLength, +- newStr.substring(prefixLength, newStr.length - suffixLength)); +- } +- prefixLength--; +- } +- return new SimpleDiff(0, oldStr.length, newStr); +-} +- +-int countLeadingWhitespaces(String str) { +- int i = 0; +- for (; i < str.length; i++) { +- int c = str.codeUnitAt(i); +- if (!isWhitespace(c)) { +- break; +- } +- } +- return i; +-} +- +-/** +- * Counts how many times [sub] appears in [str]. +- */ +-int countMatches(String str, String sub) { +- if (isEmpty(str) || isEmpty(sub)) { +- return 0; +- } +- int count = 0; +- int idx = 0; +- while ((idx = str.indexOf(sub, idx)) != -1) { +- count++; +- idx += sub.length; +- } +- return count; +-} +- +-int countTrailingWhitespaces(String str) { +- int i = 0; +- for (; i < str.length; i++) { +- int c = str.codeUnitAt(str.length - 1 - i); +- if (!isWhitespace(c)) { +- break; +- } +- } +- return i; +-} +- +-/** +- * Returns the number of characters common to the end of [a] and the start +- * of [b]. +- */ +-int findCommonOverlap(String a, String b) { +- int a_length = a.length; +- int b_length = b.length; +- // all empty +- if (a_length == 0 || b_length == 0) { +- return 0; +- } +- // truncate +- if (a_length > b_length) { +- a = a.substring(a_length - b_length); +- } else if (a_length < b_length) { +- b = b.substring(0, a_length); +- } +- int text_length = min(a_length, b_length); +- // the worst case +- if (a == b) { +- return text_length; +- } +- // increase common length one by one +- int length = 0; +- while (length < text_length) { +- if (a.codeUnitAt(text_length - 1 - length) != b.codeUnitAt(length)) { +- break; +- } +- length++; +- } +- return length; +-} +- +-/** +- * Return the number of characters common to the start of [a] and [b]. +- */ +-int findCommonPrefix(String a, String b) { +- int n = min(a.length, b.length); +- for (int i = 0; i < n; i++) { +- if (a.codeUnitAt(i) != b.codeUnitAt(i)) { +- return i; +- } +- } +- return n; +-} +- +-/** +- * Return the number of characters common to the end of [a] and [b]. +- */ +-int findCommonSuffix(String a, String b) { +- int a_length = a.length; +- int b_length = b.length; +- int n = min(a_length, b_length); +- for (int i = 1; i <= n; i++) { +- if (a.codeUnitAt(a_length - i) != b.codeUnitAt(b_length - i)) { +- return i - 1; +- } +- } +- return n; +-} +- +-/** +- * Checks if [str] is `null`, empty or is whitespace. +- */ +-bool isBlank(String str) { +- if (str == null) { +- return true; +- } +- if (str.isEmpty) { +- return true; +- } +- return str.codeUnits.every(isSpace); +-} +- +-bool isDigit(int c) { +- return c >= 0x30 && c <= 0x39; +-} +- +-bool isEOL(int c) { +- return c == 0x0D || c == 0x0A; +-} +- +-bool isLetter(int c) { +- return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); +-} +- +-bool isLetterOrDigit(int c) { +- return isLetter(c) || isDigit(c); +-} +- +-bool isSpace(int c) => c == 0x20 || c == 0x09; +- +-bool isWhitespace(int c) { +- return isSpace(c) || isEOL(c); +-} +- +-String remove(String str, String remove) { +- if (isEmpty(str) || isEmpty(remove)) { +- return str; +- } +- return str.replaceAll(remove, ''); +-} +- +-String removeEnd(String str, String remove) { +- if (isEmpty(str) || isEmpty(remove)) { +- return str; +- } +- if (str.endsWith(remove)) { +- return str.substring(0, str.length - remove.length); +- } +- return str; +-} +- +-String repeat(String s, int n) { +- StringBuffer sb = new StringBuffer(); +- for (int i = 0; i < n; i++) { +- sb.write(s); +- } +- return sb.toString(); +-} +- +-/** +- * If the [text] length is above the [limit], replace the middle with `...`. +- */ +-String shorten(String text, int limit) { +- if (text.length > limit) { +- int headLength = limit ~/ 2 - 1; +- int tailLength = limit - headLength - 3; +- return text.substring(0, headLength) + +- '...' + +- text.substring(text.length - tailLength); +- } +- return text; +-} +- +-/** +- * Gets the substring after the last occurrence of a separator. +- * The separator is not returned. +- */ +-String substringAfterLast(String str, String separator) { +- if (isEmpty(str)) { +- return str; +- } +- if (isEmpty(separator)) { +- return ''; +- } +- int pos = str.lastIndexOf(separator); +- if (pos == -1) { +- return str; +- } +- return str.substring(pos + separator.length); +-} +- +-/** +- * Information about a single replacement that should be made to convert the +- * "old" string to the "new" one. +- */ +-class SimpleDiff { +- final int offset; +- final int length; +- final String replacement; +- +- SimpleDiff(this.offset, this.length, this.replacement); +-} +diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart +deleted file mode 100644 +index b31343cf9b7..00000000000 +--- a/pkg/analysis_server/lib/src/services/correction/util.dart ++++ /dev/null +@@ -1,1530 +0,0 @@ +-// Copyright (c) 2014, 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:math'; +- +-import 'package:analysis_server/src/protocol_server.dart' +- show doSourceChange_addElementEdit; +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/scanner/reader.dart'; +-import 'package:analyzer/src/dart/scanner/scanner.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/resolver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show SourceChange, SourceEdit; +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +-import 'package:path/path.dart'; +- +-/** +- * Adds edits to the given [change] that ensure that all the [libraries] are +- * imported into the given [targetLibrary]. +- */ +-void addLibraryImports( +- SourceChange change, LibraryElement targetLibrary, Set libraries) { +- CorrectionUtils libUtils; +- try { +- CompilationUnitElement unitElement = targetLibrary.definingCompilationUnit; +- CompilationUnit unitAst = getParsedUnit(unitElement); +- libUtils = new CorrectionUtils(unitAst); +- } catch (e) { +- throw new CancelCorrectionException(exception: e); +- } +- String eol = libUtils.endOfLine; +- // Prepare information about existing imports. +- LibraryDirective libraryDirective; +- List<_ImportDirectiveInfo> importDirectives = <_ImportDirectiveInfo>[]; +- for (Directive directive in libUtils.unit.directives) { +- if (directive is LibraryDirective) { +- libraryDirective = directive; +- } else if (directive is ImportDirective) { +- importDirectives.add(new _ImportDirectiveInfo( +- directive.uriContent, directive.offset, directive.end)); +- } +- } +- +- // Prepare all URIs to import. +- List uriList = libraries +- .map((library) => getLibrarySourceUri(targetLibrary, library)) +- .toList(); +- uriList.sort((a, b) => a.compareTo(b)); +- +- // Insert imports: between existing imports. +- if (importDirectives.isNotEmpty) { +- bool isFirstPackage = true; +- for (String importUri in uriList) { +- bool inserted = false; +- bool isPackage = importUri.startsWith('package:'); +- bool isAfterDart = false; +- for (_ImportDirectiveInfo existingImport in importDirectives) { +- if (existingImport.uri.startsWith('dart:')) { +- isAfterDart = true; +- } +- if (existingImport.uri.startsWith('package:')) { +- isFirstPackage = false; +- } +- if (importUri.compareTo(existingImport.uri) < 0) { +- String importCode = "import '$importUri';$eol"; +- doSourceChange_addElementEdit(change, targetLibrary, +- new SourceEdit(existingImport.offset, 0, importCode)); +- inserted = true; +- break; +- } +- } +- if (!inserted) { +- String importCode = "${eol}import '$importUri';"; +- if (isPackage && isFirstPackage && isAfterDart) { +- importCode = eol + importCode; +- } +- doSourceChange_addElementEdit(change, targetLibrary, +- new SourceEdit(importDirectives.last.end, 0, importCode)); +- } +- if (isPackage) { +- isFirstPackage = false; +- } +- } +- return; +- } +- +- // Insert imports: after the library directive. +- if (libraryDirective != null) { +- String prefix = eol + eol; +- for (String importUri in uriList) { +- String importCode = "${prefix}import '$importUri';"; +- prefix = eol; +- doSourceChange_addElementEdit(change, targetLibrary, +- new SourceEdit(libraryDirective.end, 0, importCode)); +- } +- return; +- } +- +- // If still at the beginning of the file, skip shebang and line comments. +- { +- CorrectionUtils_InsertDesc desc = libUtils.getInsertDescTop(); +- int offset = desc.offset; +- for (int i = 0; i < uriList.length; i++) { +- String importUri = uriList[i]; +- String importCode = "import '$importUri';$eol"; +- if (i == 0) { +- importCode = desc.prefix + importCode; +- } +- if (i == uriList.length - 1) { +- importCode = importCode + desc.suffix; +- } +- doSourceChange_addElementEdit( +- change, targetLibrary, new SourceEdit(offset, 0, importCode)); +- } +- } +-} +- +-/** +- * Climbs up [PrefixedIdentifier] and [PropertyAccess] nodes that include [node]. +- */ +-Expression climbPropertyAccess(AstNode node) { +- while (true) { +- AstNode parent = node.parent; +- if (parent is PrefixedIdentifier && parent.identifier == node) { +- node = parent; +- continue; +- } +- if (parent is PropertyAccess && parent.propertyName == node) { +- node = parent; +- continue; +- } +- return node; +- } +-} +- +-/** +- * TODO(scheglov) replace with nodes once there will be [CompilationUnit.getComments]. +- * +- * Returns [SourceRange]s of all comments in [unit]. +- */ +-List getCommentRanges(CompilationUnit unit) { +- List ranges = []; +- Token token = unit.beginToken; +- while (token != null && token.type != TokenType.EOF) { +- Token commentToken = token.precedingComments; +- while (commentToken != null) { +- ranges.add(range.token(commentToken)); +- commentToken = commentToken.next; +- } +- token = token.next; +- } +- return ranges; +-} +- +-/** +- * Return the given [element] if it is a [CompilationUnitElement]. +- * Return the enclosing [CompilationUnitElement] of the given [element], +- * maybe `null`. +- */ +-CompilationUnitElement getCompilationUnitElement(Element element) { +- if (element is CompilationUnitElement) { +- return element; +- } +- return element.getAncestor((e) => e is CompilationUnitElement); +-} +- +-String getDefaultValueCode(DartType type) { +- if (type != null) { +- String typeName = type.displayName; +- if (typeName == "bool") { +- return "false"; +- } +- if (typeName == "int") { +- return "0"; +- } +- if (typeName == "double") { +- return "0.0"; +- } +- if (typeName == "String") { +- return "''"; +- } +- } +- // no better guess +- return "null"; +-} +- +-/** +- * Return all [LocalElement]s defined in the given [node]. +- */ +-List getDefinedLocalElements(AstNode node) { +- var collector = new _LocalElementsCollector(); +- node.accept(collector); +- return collector.elements; +-} +- +-/** +- * Return the name of the [Element] kind. +- */ +-String getElementKindName(Element element) { +- return element.kind.displayName; +-} +- +-/** +- * Returns the name to display in the UI for the given [Element]. +- */ +-String getElementQualifiedName(Element element) { +- ElementKind kind = element.kind; +- if (kind == ElementKind.CONSTRUCTOR || +- kind == ElementKind.FIELD || +- kind == ElementKind.METHOD) { +- return '${element.enclosingElement.displayName}.${element.displayName}'; +- } else { +- return element.displayName; +- } +-} +- +-/** +- * If the given [AstNode] is in a [ClassDeclaration], returns the +- * [ClassElement]. Otherwise returns `null`. +- */ +-ClassElement getEnclosingClassElement(AstNode node) { +- ClassDeclaration enclosingClassNode = +- node.getAncestor((node) => node is ClassDeclaration); +- if (enclosingClassNode != null) { +- return enclosingClassNode.element; +- } +- return null; +-} +- +-/** +- * Returns a class or an unit member enclosing the given [node]. +- */ +-AstNode getEnclosingClassOrUnitMember(AstNode node) { +- AstNode member = node; +- while (node != null) { +- if (node is ClassDeclaration) { +- return member; +- } +- if (node is CompilationUnit) { +- return member; +- } +- member = node; +- node = node.parent; +- } +- return null; +-} +- +-/** +- * Return the [ExecutableElement] of the enclosing executable [AstNode]. +- */ +-ExecutableElement getEnclosingExecutableElement(AstNode node) { +- while (node != null) { +- if (node is FunctionDeclaration) { +- return node.element; +- } +- if (node is ConstructorDeclaration) { +- return node.element; +- } +- if (node is MethodDeclaration) { +- return node.element; +- } +- node = node.parent; +- } +- return null; +-} +- +-/** +- * Return the enclosing executable [AstNode]. +- */ +-AstNode getEnclosingExecutableNode(AstNode node) { +- while (node != null) { +- if (node is FunctionDeclaration) { +- return node; +- } +- if (node is ConstructorDeclaration) { +- return node; +- } +- if (node is MethodDeclaration) { +- return node; +- } +- node = node.parent; +- } +- return null; +-} +- +-/** +- * Returns [getExpressionPrecedence] for the parent of [node], or `0` if the +- * parent node is a [ParenthesizedExpression]. +- * +- * The reason is that `(expr)` is always executed after `expr`. +- */ +-int getExpressionParentPrecedence(AstNode node) { +- AstNode parent = node.parent; +- if (parent is ParenthesizedExpression) { +- return 0; +- } else if (parent is IndexExpression && parent.index == node) { +- return 0; +- } else if (parent is AssignmentExpression && +- node == parent.rightHandSide && +- parent.parent is CascadeExpression) { +- // This is a hack to allow nesting of cascade expressions within other +- // cascade expressions. The problem is that if the precedence of two +- // expressions are equal it sometimes means that we don't need parentheses +- // (such as replacing the `b` in `a + b` with `c + d`) and sometimes do +- // (such as replacing the `v` in `..f = v` with `a..b`). +- return 3; +- } +- return getExpressionPrecedence(parent); +-} +- +-/** +- * Returns the precedence of [node] it is an [Expression], negative otherwise. +- */ +-int getExpressionPrecedence(AstNode node) { +- if (node is Expression) { +- return node.precedence; +- } +- return -1000; +-} +- +-/** +- * Returns the namespace of the given [ImportElement]. +- */ +-Map getImportNamespace(ImportElement imp) { +- NamespaceBuilder builder = new NamespaceBuilder(); +- Namespace namespace = builder.createImportNamespaceForDirective(imp); +- return namespace.definedNames; +-} +- +-/** +- * Computes the best URI to import [what] into [from]. +- */ +-String getLibrarySourceUri(LibraryElement from, Source what) { +- String whatPath = what.fullName; +- // check if an absolute URI (such as 'dart:' or 'package:') +- Uri whatUri = what.uri; +- String whatUriScheme = whatUri.scheme; +- if (whatUriScheme != '' && whatUriScheme != 'file') { +- return whatUri.toString(); +- } +- // compute a relative URI +- String fromFolder = dirname(from.source.fullName); +- String relativeFile = relative(whatPath, from: fromFolder); +- return split(relativeFile).join('/'); +-} +- +-/** +- * Returns the line prefix from the given source, i.e. basically just a +- * whitespace prefix of the given [String]. +- */ +-String getLinePrefix(String line) { +- int index = 0; +- while (index < line.length) { +- int c = line.codeUnitAt(index); +- if (!isWhitespace(c)) { +- break; +- } +- index++; +- } +- return line.substring(0, index); +-} +- +-/** +- * Return the [LocalVariableElement] if given [node] is a reference to a local +- * variable, or `null` in the other case. +- */ +-LocalVariableElement getLocalVariableElement(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is LocalVariableElement) { +- return element; +- } +- return null; +-} +- +-/** +- * Return the nearest common ancestor of the given [nodes]. +- */ +-AstNode getNearestCommonAncestor(List nodes) { +- // may be no nodes +- if (nodes.isEmpty) { +- return null; +- } +- // prepare parents +- List> parents = []; +- for (AstNode node in nodes) { +- parents.add(getParents(node)); +- } +- // find min length +- int minLength = 1 << 20; +- for (List parentList in parents) { +- minLength = min(minLength, parentList.length); +- } +- // find deepest parent +- int i = 0; +- for (; i < minLength; i++) { +- if (!_allListsIdentical(parents, i)) { +- break; +- } +- } +- return parents[0][i - 1]; +-} +- +-/** +- * Returns the [Expression] qualifier if given [node] is the name part of a +- * [PropertyAccess] or a [PrefixedIdentifier]. Maybe `null`. +- */ +-Expression getNodeQualifier(SimpleIdentifier node) { +- AstNode parent = node.parent; +- if (parent is MethodInvocation && identical(parent.methodName, node)) { +- return parent.target; +- } +- if (parent is PropertyAccess && identical(parent.propertyName, node)) { +- return parent.target; +- } +- if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { +- return parent.prefix; +- } +- return null; +-} +- +-/** +- * Returns the [ParameterElement] if the given [node] is a reference to a +- * parameter, or `null` in the other case. +- */ +-ParameterElement getParameterElement(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is ParameterElement) { +- return element; +- } +- return null; +-} +- +-/** +- * Return parent [AstNode]s from compilation unit (at index "0") to the given +- * [node]. +- */ +-List getParents(AstNode node) { +- // prepare number of parents +- int numParents = 0; +- { +- AstNode current = node.parent; +- while (current != null) { +- numParents++; +- current = current.parent; +- } +- } +- // fill array of parents +- List parents = new List(numParents); +- AstNode current = node.parent; +- int index = numParents; +- while (current != null) { +- parents[--index] = current; +- current = current.parent; +- } +- return parents; +-} +- +-/** +- * Returns a parsed [AstNode] for the given [classElement]. +- * +- * The resulting AST structure may or may not be resolved. +- */ +-AstNode getParsedClassElementNode(ClassElement classElement) { +- CompilationUnitElement unitElement = getCompilationUnitElement(classElement); +- CompilationUnit unit = getParsedUnit(unitElement); +- int offset = classElement.nameOffset; +- AstNode classNameNode = new NodeLocator(offset).searchWithin(unit); +- if (classElement.isEnum) { +- return classNameNode.getAncestor((node) => node is EnumDeclaration); +- } else { +- return classNameNode.getAncestor( +- (node) => node is ClassDeclaration || node is ClassTypeAlias); +- } +-} +- +-/** +- * Returns a parsed [CompilationUnit] for the given [unitElement]. +- * +- * The resulting AST structure may or may not be resolved. +- * If it is not resolved, then at least the given [unitElement] will be set. +- */ +-CompilationUnit getParsedUnit(CompilationUnitElement unitElement) { +- AnalysisContext context = unitElement.context; +- Source source = unitElement.source; +- CompilationUnit unit = context.parseCompilationUnit(source); +- if (unit.element == null) { +- unit.element = unitElement; +- } +- return unit; +-} +- +-/** +- * If given [node] is name of qualified property extraction, returns target from +- * which this property is extracted, otherwise `null`. +- */ +-Expression getQualifiedPropertyTarget(AstNode node) { +- AstNode parent = node.parent; +- if (parent is PrefixedIdentifier) { +- PrefixedIdentifier prefixed = parent; +- if (prefixed.identifier == node) { +- return parent.prefix; +- } +- } +- if (parent is PropertyAccess) { +- PropertyAccess access = parent; +- if (access.propertyName == node) { +- return access.realTarget; +- } +- } +- return null; +-} +- +-/** +- * Returns the given [statement] if not a block, or the first child statement if +- * a block, or `null` if more than one child. +- */ +-Statement getSingleStatement(Statement statement) { +- if (statement is Block) { +- List blockStatements = statement.statements; +- if (blockStatements.length != 1) { +- return null; +- } +- return blockStatements[0]; +- } +- return statement; +-} +- +-/** +- * Returns the given [statement] if not a block, or all the children statements +- * if a block. +- */ +-List getStatements(Statement statement) { +- if (statement is Block) { +- return statement.statements; +- } +- return [statement]; +-} +- +-/** +- * Checks if the given [element]'s display name equals to the given [name]. +- */ +-bool hasDisplayName(Element element, String name) { +- if (element == null) { +- return false; +- } +- return element.displayName == name; +-} +- +-/** +- * Checks if given [DartNode] is the left hand side of an assignment, or a +- * declaration of a variable. +- */ +-bool isLeftHandOfAssignment(SimpleIdentifier node) { +- if (node.inSetterContext()) { +- return true; +- } +- return node.parent is VariableDeclaration && +- (node.parent as VariableDeclaration).name == node; +-} +- +-/** +- * Return `true` if the given [node] is the name of a [NamedExpression]. +- */ +-bool isNamedExpressionName(SimpleIdentifier node) { +- AstNode parent = node.parent; +- if (parent is Label) { +- Label label = parent; +- if (identical(label.label, node)) { +- AstNode parent2 = label.parent; +- if (parent2 is NamedExpression) { +- return identical(parent2.name, label); +- } +- } +- } +- return false; +-} +- +-/** +- * If the given [expression] is the `expression` property of a [NamedExpression] +- * then returns this [NamedExpression], otherwise returns [expression]. +- */ +-Expression stepUpNamedExpression(Expression expression) { +- if (expression != null) { +- AstNode parent = expression.parent; +- if (parent is NamedExpression && parent.expression == expression) { +- return parent; +- } +- } +- return expression; +-} +- +-/** +- * Return `true` if the given [lists] are identical at the given [position]. +- */ +-bool _allListsIdentical(List lists, int position) { +- Object element = lists[0][position]; +- for (List list in lists) { +- if (list[position] != element) { +- return false; +- } +- } +- return true; +-} +- +-/** +- * This exception is thrown to cancel the current correction operation, +- * such as quick assist or quick fix because an inconsistency was detected. +- * These inconsistencies may happen as a part of normal workflow, e.g. because +- * a resource was deleted, or an analysis result was invalidated. +- */ +-class CancelCorrectionException { +- final Object exception; +- +- CancelCorrectionException({this.exception}); +-} +- +-/** +- * Describes the location for a newly created [ClassMember]. +- */ +-class ClassMemberLocation { +- final String prefix; +- final int offset; +- final String suffix; +- +- ClassMemberLocation(this.prefix, this.offset, this.suffix); +-} +- +-class CorrectionUtils { +- final CompilationUnit unit; +- +- /** +- * The [ClassElement] the generated code is inserted to, so we can decide if +- * a type parameter may or may not be used. +- */ +- ClassElement targetClassElement; +- +- ExecutableElement targetExecutableElement; +- +- LibraryElement _library; +- String _buffer; +- String _endOfLine; +- +- CorrectionUtils(this.unit) { +- CompilationUnitElement unitElement = unit.element; +- AnalysisContext context = unitElement.context; +- if (context == null) { +- throw new CancelCorrectionException(); +- } +- this._library = unitElement.library; +- this._buffer = context.getContents(unitElement.source).data; +- } +- +- /** +- * Returns the EOL to use for this [CompilationUnit]. +- */ +- String get endOfLine { +- if (_endOfLine == null) { +- if (_buffer.contains("\r\n")) { +- _endOfLine = "\r\n"; +- } else { +- _endOfLine = "\n"; +- } +- } +- return _endOfLine; +- } +- +- /** +- * Returns the [AstNode] that encloses the given offset. +- */ +- AstNode findNode(int offset) => new NodeLocator(offset).searchWithin(unit); +- +- /** +- * Returns names of elements that might conflict with a new local variable +- * declared at [offset]. +- */ +- Set findPossibleLocalVariableConflicts(int offset) { +- Set conflicts = new Set(); +- AstNode enclosingNode = findNode(offset); +- Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block); +- if (enclosingBlock != null) { +- _CollectReferencedUnprefixedNames visitor = +- new _CollectReferencedUnprefixedNames(); +- enclosingBlock.accept(visitor); +- return visitor.names; +- } +- return conflicts; +- } +- +- /** +- * Returns the indentation with the given level. +- */ +- String getIndent(int level) => repeat(' ', level); +- +- /** +- * Returns a [InsertDesc] describing where to insert a new directive or a +- * top-level declaration at the top of the file. +- */ +- CorrectionUtils_InsertDesc getInsertDescTop() { +- // skip leading line comments +- int offset = 0; +- bool insertEmptyLineBefore = false; +- bool insertEmptyLineAfter = false; +- String source = _buffer; +- // skip hash-bang +- if (offset < source.length - 2) { +- String linePrefix = getText(offset, 2); +- if (linePrefix == "#!") { +- insertEmptyLineBefore = true; +- offset = getLineNext(offset); +- // skip empty lines to first line comment +- int emptyOffset = offset; +- while (emptyOffset < source.length - 2) { +- int nextLineOffset = getLineNext(emptyOffset); +- String line = source.substring(emptyOffset, nextLineOffset); +- if (line.trim().isEmpty) { +- emptyOffset = nextLineOffset; +- continue; +- } else if (line.startsWith("//")) { +- offset = emptyOffset; +- break; +- } else { +- break; +- } +- } +- } +- } +- // skip line comments +- while (offset < source.length - 2) { +- String linePrefix = getText(offset, 2); +- if (linePrefix == "//") { +- insertEmptyLineBefore = true; +- offset = getLineNext(offset); +- } else { +- break; +- } +- } +- // determine if empty line is required after +- int nextLineOffset = getLineNext(offset); +- String insertLine = source.substring(offset, nextLineOffset); +- if (!insertLine.trim().isEmpty) { +- insertEmptyLineAfter = true; +- } +- // fill InsertDesc +- CorrectionUtils_InsertDesc desc = new CorrectionUtils_InsertDesc(); +- desc.offset = offset; +- if (insertEmptyLineBefore) { +- desc.prefix = endOfLine; +- } +- if (insertEmptyLineAfter) { +- desc.suffix = endOfLine; +- } +- return desc; +- } +- +- /** +- * Skips whitespace characters and single EOL on the right from [index]. +- * +- * If [index] the end of a statement or method, then in the most cases it is +- * a start of the next line. +- */ +- int getLineContentEnd(int index) { +- int length = _buffer.length; +- // skip whitespace characters +- while (index < length) { +- int c = _buffer.codeUnitAt(index); +- if (!isWhitespace(c) || c == 0x0D || c == 0x0A) { +- break; +- } +- index++; +- } +- // skip single \r +- if (index < length && _buffer.codeUnitAt(index) == 0x0D) { +- index++; +- } +- // skip single \n +- if (index < length && _buffer.codeUnitAt(index) == 0x0A) { +- index++; +- } +- // done +- return index; +- } +- +- /** +- * Skips spaces and tabs on the left from [index]. +- * +- * If [index] is the start or a statement, then in the most cases it is a +- * start on its line. +- */ +- int getLineContentStart(int index) { +- while (index > 0) { +- int c = _buffer.codeUnitAt(index - 1); +- if (!isSpace(c)) { +- break; +- } +- index--; +- } +- return index; +- } +- +- /** +- * Returns a start index of the next line after the line which contains the +- * given index. +- */ +- int getLineNext(int index) { +- int length = _buffer.length; +- // skip to the end of the line +- while (index < length) { +- int c = _buffer.codeUnitAt(index); +- if (c == 0xD || c == 0xA) { +- break; +- } +- index++; +- } +- // skip single \r +- if (index < length && _buffer.codeUnitAt(index) == 0xD) { +- index++; +- } +- // skip single \n +- if (index < length && _buffer.codeUnitAt(index) == 0xA) { +- index++; +- } +- // done +- return index; +- } +- +- /** +- * Returns the whitespace prefix of the line which contains given offset. +- */ +- String getLinePrefix(int index) { +- int lineStart = getLineThis(index); +- int length = _buffer.length; +- int lineNonWhitespace = lineStart; +- while (lineNonWhitespace < length) { +- int c = _buffer.codeUnitAt(lineNonWhitespace); +- if (c == 0xD || c == 0xA) { +- break; +- } +- if (!isWhitespace(c)) { +- break; +- } +- lineNonWhitespace++; +- } +- return getText(lineStart, lineNonWhitespace - lineStart); +- } +- +- /** +- * Returns a [SourceRange] that covers [sourceRange] and extends (if possible) +- * to cover whole lines. +- */ +- SourceRange getLinesRange(SourceRange sourceRange, +- {bool skipLeadingEmptyLines: false}) { +- // start +- int startOffset = sourceRange.offset; +- int startLineOffset = getLineContentStart(startOffset); +- if (skipLeadingEmptyLines) { +- startLineOffset = skipEmptyLinesLeft(startLineOffset); +- } +- // end +- int endOffset = sourceRange.end; +- int afterEndLineOffset = endOffset; +- int lineStart = unit.lineInfo.getOffsetOfLine( +- unit.lineInfo.getLocation(startLineOffset).lineNumber - 1); +- if (lineStart == startLineOffset) { +- // Only consume line ends after the end of the range if there is nothing +- // else on the line containing the beginning of the range. Otherwise this +- // will end up incorrectly merging two line. +- afterEndLineOffset = getLineContentEnd(endOffset); +- } +- // range +- return range.startOffsetEndOffset(startLineOffset, afterEndLineOffset); +- } +- +- /** +- * Returns a [SourceRange] that covers all the given [Statement]s. +- */ +- SourceRange getLinesRangeStatements(List statements) { +- return getLinesRange(range.nodes(statements)); +- } +- +- /** +- * Returns the start index of the line which contains given index. +- */ +- int getLineThis(int index) { +- while (index > 0) { +- int c = _buffer.codeUnitAt(index - 1); +- if (c == 0xD || c == 0xA) { +- break; +- } +- index--; +- } +- return index; +- } +- +- /** +- * Returns the line prefix consisting of spaces and tabs on the left from the given +- * [AstNode]. +- */ +- String getNodePrefix(AstNode node) { +- int offset = node.offset; +- // function literal is special, it uses offset of enclosing line +- if (node is FunctionExpression) { +- return getLinePrefix(offset); +- } +- // use just prefix directly before node +- return getPrefix(offset); +- } +- +- /** +- * Returns the text of the given [AstNode] in the unit. +- */ +- String getNodeText(AstNode node) { +- return getText(node.offset, node.length); +- } +- +- /** +- * Returns the line prefix consisting of spaces and tabs on the left from the +- * given offset. +- */ +- String getPrefix(int endIndex) { +- int startIndex = getLineContentStart(endIndex); +- return _buffer.substring(startIndex, endIndex); +- } +- +- /** +- * Returns the text of the given range in the unit. +- */ +- String getRangeText(SourceRange range) { +- return getText(range.offset, range.length); +- } +- +- /** +- * Returns the text of the given range in the unit. +- */ +- String getText(int offset, int length) { +- return _buffer.substring(offset, offset + length); +- } +- +- /** +- * Returns the source to reference [type] in this [CompilationUnit]. +- * +- * Fills [librariesToImport] with [LibraryElement]s whose elements are +- * used by the generated source, but not imported. +- */ +- String getTypeSource(DartType type, Set librariesToImport, +- {StringBuffer parametersBuffer}) { +- StringBuffer sb = new StringBuffer(); +- // type parameter +- if (!_isTypeVisible(type)) { +- return 'dynamic'; +- } +- +- Element element = type.element; +- +- // Typedef(s) are represented as GenericFunctionTypeElement(s). +- if (element is GenericFunctionTypeElement && +- element.typeParameters.isEmpty && +- element.enclosingElement is GenericTypeAliasElement) { +- element = element.enclosingElement; +- } +- +- // just a Function, not FunctionTypeAliasElement +- if (type is FunctionType && element is! FunctionTypeAliasElement) { +- if (parametersBuffer == null) { +- return "Function"; +- } +- parametersBuffer.write('('); +- for (ParameterElement parameter in type.parameters) { +- String parameterType = getTypeSource(parameter.type, librariesToImport); +- if (parametersBuffer.length != 1) { +- parametersBuffer.write(', '); +- } +- parametersBuffer.write(parameterType); +- parametersBuffer.write(' '); +- parametersBuffer.write(parameter.name); +- } +- parametersBuffer.write(')'); +- return getTypeSource(type.returnType, librariesToImport); +- } +- // , Null +- if (type.isBottom || type.isDartCoreNull) { +- return 'dynamic'; +- } +- // prepare element +- if (element == null) { +- String source = type.toString(); +- source = source.replaceAll('', ''); +- source = source.replaceAll('', ''); +- return source; +- } +- // check if imported +- LibraryElement library = element.library; +- if (library != null && library != _library) { +- // no source, if private +- if (element.isPrivate) { +- return null; +- } +- // ensure import +- ImportElement importElement = _getImportElement(element); +- if (importElement != null) { +- if (importElement.prefix != null) { +- sb.write(importElement.prefix.displayName); +- sb.write("."); +- } +- } else { +- librariesToImport.add(library.source); +- } +- } +- // append simple name +- String name = element.displayName; +- sb.write(name); +- // may be type arguments +- if (type is ParameterizedType) { +- List arguments = type.typeArguments; +- // check if has arguments +- bool hasArguments = false; +- bool allArgumentsVisible = true; +- for (DartType argument in arguments) { +- hasArguments = hasArguments || !argument.isDynamic; +- allArgumentsVisible = allArgumentsVisible && _isTypeVisible(argument); +- } +- // append type arguments +- if (hasArguments && allArgumentsVisible) { +- sb.write("<"); +- for (int i = 0; i < arguments.length; i++) { +- DartType argument = arguments[i]; +- if (i != 0) { +- sb.write(", "); +- } +- String argumentSrc = getTypeSource(argument, librariesToImport); +- if (argumentSrc != null) { +- sb.write(argumentSrc); +- } else { +- return null; +- } +- } +- sb.write(">"); +- } +- } +- // done +- return sb.toString(); +- } +- +- /** +- * Indents given source left or right. +- */ +- String indentSourceLeftRight(String source, {bool indentLeft: true}) { +- StringBuffer sb = new StringBuffer(); +- String indent = getIndent(1); +- String eol = endOfLine; +- List lines = source.split(eol); +- for (int i = 0; i < lines.length; i++) { +- String line = lines[i]; +- // last line, stop if empty +- if (i == lines.length - 1 && isEmpty(line)) { +- break; +- } +- // update line +- if (indentLeft) { +- line = removeStart(line, indent); +- } else { +- line = "$indent$line"; +- } +- // append line +- sb.write(line); +- sb.write(eol); +- } +- return sb.toString(); +- } +- +- /** +- * @return the source of the inverted condition for the given logical expression. +- */ +- String invertCondition(Expression expression) => +- _invertCondition0(expression)._source; +- +- /** +- * Return `true` if the given [classDeclaration] has open '{' and close '}' +- * at the same line, e.g. `class X {}`. +- */ +- bool isClassWithEmptyBody(ClassDeclaration classDeclaration) { +- return getLineThis(classDeclaration.leftBracket.offset) == +- getLineThis(classDeclaration.rightBracket.offset); +- } +- +- /** +- * @return true if selection range contains only whitespace or comments +- */ +- bool isJustWhitespaceOrComment(SourceRange range) { +- String trimmedText = getRangeText(range).trim(); +- // may be whitespace +- if (trimmedText.isEmpty) { +- return true; +- } +- // may be comment +- return TokenUtils.getTokens(trimmedText).isEmpty; +- } +- +- ClassMemberLocation prepareNewClassMemberLocation( +- ClassDeclaration classDeclaration, +- bool shouldSkip(ClassMember existingMember)) { +- String indent = getIndent(1); +- // Find the last target member. +- ClassMember targetMember = null; +- List members = classDeclaration.members; +- for (ClassMember member in members) { +- if (shouldSkip(member)) { +- targetMember = member; +- } else { +- break; +- } +- } +- // After the last target member. +- if (targetMember != null) { +- return new ClassMemberLocation( +- endOfLine + endOfLine + indent, targetMember.end, ''); +- } +- // At the beginning of the class. +- String suffix = members.isNotEmpty || isClassWithEmptyBody(classDeclaration) +- ? endOfLine +- : ''; +- return new ClassMemberLocation( +- endOfLine + indent, classDeclaration.leftBracket.end, suffix); +- } +- +- ClassMemberLocation prepareNewConstructorLocation( +- ClassDeclaration classDeclaration) { +- return prepareNewClassMemberLocation( +- classDeclaration, +- (member) => +- member is FieldDeclaration || member is ConstructorDeclaration); +- } +- +- ClassMemberLocation prepareNewFieldLocation( +- ClassDeclaration classDeclaration) { +- return prepareNewClassMemberLocation( +- classDeclaration, (member) => member is FieldDeclaration); +- } +- +- ClassMemberLocation prepareNewGetterLocation( +- ClassDeclaration classDeclaration) { +- return prepareNewClassMemberLocation( +- classDeclaration, +- (member) => +- member is FieldDeclaration || +- member is ConstructorDeclaration || +- member is MethodDeclaration && member.isGetter); +- } +- +- ClassMemberLocation prepareNewMethodLocation( +- ClassDeclaration classDeclaration) { +- return prepareNewClassMemberLocation( +- classDeclaration, +- (member) => +- member is FieldDeclaration || +- member is ConstructorDeclaration || +- member is MethodDeclaration); +- } +- +- /** +- * Returns the source with indentation changed from [oldIndent] to +- * [newIndent], keeping indentation of lines relative to each other. +- */ +- String replaceSourceIndent( +- String source, String oldIndent, String newIndent) { +- // prepare STRING token ranges +- List lineRanges = []; +- { +- List tokens = TokenUtils.getTokens(source); +- for (Token token in tokens) { +- if (token.type == TokenType.STRING) { +- lineRanges.add(range.token(token)); +- } +- token = token.next; +- } +- } +- // re-indent lines +- StringBuffer sb = new StringBuffer(); +- String eol = endOfLine; +- List lines = source.split(eol); +- int lineOffset = 0; +- for (int i = 0; i < lines.length; i++) { +- String line = lines[i]; +- // last line, stop if empty +- if (i == lines.length - 1 && isEmpty(line)) { +- break; +- } +- // check if "offset" is in one of the String ranges +- bool inString = false; +- for (SourceRange lineRange in lineRanges) { +- if (lineOffset > lineRange.offset && lineOffset < lineRange.end) { +- inString = true; +- } +- if (lineOffset > lineRange.end) { +- break; +- } +- } +- lineOffset += line.length + eol.length; +- // update line indent +- if (!inString) { +- line = "$newIndent${removeStart(line, oldIndent)}"; +- } +- // append line +- sb.write(line); +- sb.write(eol); +- } +- return sb.toString(); +- } +- +- /** +- * Returns the source of the given [SourceRange] with indentation changed +- * from [oldIndent] to [newIndent], keeping indentation of lines relative +- * to each other. +- */ +- String replaceSourceRangeIndent( +- SourceRange range, String oldIndent, String newIndent) { +- String oldSource = getRangeText(range); +- return replaceSourceIndent(oldSource, oldIndent, newIndent); +- } +- +- /** +- * @return true if "selection" covers "node" and there are any non-whitespace tokens +- * between "selection" and "node" start/end. +- */ +- bool selectionIncludesNonWhitespaceOutsideNode( +- SourceRange selection, AstNode node) { +- return _selectionIncludesNonWhitespaceOutsideRange( +- selection, range.node(node)); +- } +- +- /** +- * Skip spaces, tabs and EOLs on the left from [index]. +- * +- * If [index] is the start of a method, then in the most cases return the end +- * of the previous not-whitespace line. +- */ +- int skipEmptyLinesLeft(int index) { +- int lastLine = index; +- while (index > 0) { +- int c = _buffer.codeUnitAt(index - 1); +- if (!isWhitespace(c)) { +- return lastLine; +- } +- if (isEOL(c)) { +- lastLine = index; +- } +- index--; +- } +- return 0; +- } +- +- /** +- * @return the [ImportElement] used to import given [Element] into [library]. +- * May be `null` if was not imported, i.e. declared in the same library. +- */ +- ImportElement _getImportElement(Element element) { +- for (ImportElement imp in _library.imports) { +- Map definedNames = getImportNamespace(imp); +- if (definedNames.containsValue(element)) { +- return imp; +- } +- } +- return null; +- } +- +- /** +- * @return the [InvertedCondition] for the given logical expression. +- */ +- _InvertedCondition _invertCondition0(Expression expression) { +- if (expression is BooleanLiteral) { +- if (expression.value) { +- return _InvertedCondition._simple("false"); +- } else { +- return _InvertedCondition._simple("true"); +- } +- } else if (expression is BinaryExpression) { +- TokenType operator = expression.operator.type; +- Expression le = expression.leftOperand; +- Expression re = expression.rightOperand; +- _InvertedCondition ls = _invertCondition0(le); +- _InvertedCondition rs = _invertCondition0(re); +- if (operator == TokenType.LT) { +- return _InvertedCondition._binary2(ls, " >= ", rs); +- } +- if (operator == TokenType.GT) { +- return _InvertedCondition._binary2(ls, " <= ", rs); +- } +- if (operator == TokenType.LT_EQ) { +- return _InvertedCondition._binary2(ls, " > ", rs); +- } +- if (operator == TokenType.GT_EQ) { +- return _InvertedCondition._binary2(ls, " < ", rs); +- } +- if (operator == TokenType.EQ_EQ) { +- return _InvertedCondition._binary2(ls, " != ", rs); +- } +- if (operator == TokenType.BANG_EQ) { +- return _InvertedCondition._binary2(ls, " == ", rs); +- } +- if (operator == TokenType.AMPERSAND_AMPERSAND) { +- return _InvertedCondition._binary( +- TokenType.BAR_BAR.precedence, ls, " || ", rs); +- } +- if (operator == TokenType.BAR_BAR) { +- return _InvertedCondition._binary( +- TokenType.AMPERSAND_AMPERSAND.precedence, ls, " && ", rs); +- } +- } else if (expression is IsExpression) { +- String expressionSource = getNodeText(expression.expression); +- String typeSource = getNodeText(expression.type); +- if (expression.notOperator == null) { +- return _InvertedCondition._simple("$expressionSource is! $typeSource"); +- } else { +- return _InvertedCondition._simple("$expressionSource is $typeSource"); +- } +- } else if (expression is PrefixExpression) { +- TokenType operator = expression.operator.type; +- if (operator == TokenType.BANG) { +- Expression operand = expression.operand.unParenthesized; +- return _InvertedCondition._simple(getNodeText(operand)); +- } +- } else if (expression is ParenthesizedExpression) { +- return _invertCondition0(expression.unParenthesized); +- } +- DartType type = expression.bestType; +- if (type.displayName == "bool") { +- return _InvertedCondition._simple("!${getNodeText(expression)}"); +- } +- return _InvertedCondition._simple(getNodeText(expression)); +- } +- +- /** +- * Checks if [type] is visible in [targetExecutableElement] or +- * [targetClassElement]. +- */ +- bool _isTypeVisible(DartType type) { +- if (type is TypeParameterType) { +- TypeParameterElement parameterElement = type.element; +- Element parameterClassElement = parameterElement.enclosingElement; +- return identical(parameterClassElement, targetExecutableElement) || +- identical(parameterClassElement, targetClassElement); +- } +- return true; +- } +- +- /** +- * @return true if "selection" covers "range" and there are any non-whitespace tokens +- * between "selection" and "range" start/end. +- */ +- bool _selectionIncludesNonWhitespaceOutsideRange( +- SourceRange selection, SourceRange sourceRange) { +- // selection should cover range +- if (!selection.covers(sourceRange)) { +- return false; +- } +- // non-whitespace between selection start and range start +- if (!isJustWhitespaceOrComment( +- range.startOffsetEndOffset(selection.offset, sourceRange.offset))) { +- return true; +- } +- // non-whitespace after range +- if (!isJustWhitespaceOrComment( +- range.startOffsetEndOffset(sourceRange.end, selection.end))) { +- return true; +- } +- // only whitespace in selection around range +- return false; +- } +-} +- +-/** +- * Describes where to insert new directive or top-level declaration. +- */ +-class CorrectionUtils_InsertDesc { +- int offset = 0; +- String prefix = ""; +- String suffix = ""; +-} +- +-/** +- * Utilities to work with [Token]s. +- */ +-class TokenUtils { +- /** +- * Return the first token in the list of [tokens] representing the given +- * [keyword], or `null` if there is no such token. +- */ +- static Token findKeywordToken(List tokens, Keyword keyword) { +- for (Token token in tokens) { +- if (token.keyword == keyword) { +- return token; +- } +- } +- return null; +- } +- +- /** +- * @return the first [Token] with given [TokenType], may be null if not +- * found. +- */ +- static Token findToken(List tokens, TokenType type) { +- for (Token token in tokens) { +- if (token.type == type) { +- return token; +- } +- } +- return null; +- } +- +- /** +- * @return [Token]s of the given Dart source, not null, may be empty if no +- * tokens or some exception happens. +- */ +- static List getTokens(String s) { +- try { +- List tokens = []; +- Scanner scanner = new Scanner(null, new CharSequenceReader(s), null); +- Token token = scanner.tokenize(); +- while (token.type != TokenType.EOF) { +- tokens.add(token); +- token = token.next; +- } +- return tokens; +- } catch (e) { +- return []; +- } +- } +- +- /** +- * @return true if given [Token]s contain only single [Token] with given +- * [TokenType]. +- */ +- static bool hasOnly(List tokens, TokenType type) => +- tokens.length == 1 && tokens[0].type == type; +-} +- +-class _CollectReferencedUnprefixedNames extends RecursiveAstVisitor { +- final Set names = new Set(); +- +- void visitSimpleIdentifier(SimpleIdentifier node) { +- if (!_isPrefixed(node)) { +- names.add(node.name); +- } +- } +- +- static bool _isPrefixed(SimpleIdentifier node) { +- AstNode parent = node.parent; +- return parent is ConstructorName && parent.name == node || +- parent is MethodInvocation && +- parent.methodName == node && +- parent.realTarget != null || +- parent is PrefixedIdentifier && parent.identifier == node || +- parent is PropertyAccess && parent.target == node; +- } +-} +- +-class _ImportDirectiveInfo { +- final String uri; +- final int offset; +- final int end; +- +- _ImportDirectiveInfo(this.uri, this.offset, this.end); +-} +- +-/** +- * A container with a source and its precedence. +- */ +-class _InvertedCondition { +- final int _precedence; +- +- final String _source; +- +- _InvertedCondition(this._precedence, this._source); +- +- static _InvertedCondition _binary(int precedence, _InvertedCondition left, +- String operation, _InvertedCondition right) { +- String src = _parenthesizeIfRequired(left, precedence) + +- operation + +- _parenthesizeIfRequired(right, precedence); +- return new _InvertedCondition(precedence, src); +- } +- +- static _InvertedCondition _binary2( +- _InvertedCondition left, String operation, _InvertedCondition right) { +- // TODO(scheglov) consider merging with "_binary()" after testing +- return new _InvertedCondition( +- 1 << 20, "${left._source}$operation${right._source}"); +- } +- +- /** +- * Adds enclosing parenthesis if the precedence of the [_InvertedCondition] if less than the +- * precedence of the expression we are going it to use in. +- */ +- static String _parenthesizeIfRequired( +- _InvertedCondition expr, int newOperatorPrecedence) { +- if (expr._precedence < newOperatorPrecedence) { +- return "(${expr._source})"; +- } +- return expr._source; +- } +- +- static _InvertedCondition _simple(String source) => +- new _InvertedCondition(2147483647, source); +-} +- +-/** +- * Visitor that collects defined [LocalElement]s. +- */ +-class _LocalElementsCollector extends RecursiveAstVisitor { +- final elements = []; +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- if (node.inDeclarationContext()) { +- Element element = node.staticElement; +- if (element is LocalElement) { +- elements.add(element); +- } +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart +deleted file mode 100644 +index 3f26f7a3759..00000000000 +--- a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart ++++ /dev/null +@@ -1,1407 +0,0 @@ +-// 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:convert'; +- +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/ast/syntactic_entity.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; +-import 'package:analyzer/src/generated/bazel.dart'; +-import 'package:analyzer/src/generated/gn.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show KytheEntry, KytheVName; +- +-import 'schema.dart' as schema; +- +-const int _notFound = -1; +- +-/// Given some [ConstructorElement], this method returns '' as the +-/// name of the constructor, unless the constructor is a named constructor in +-/// which '.' is returned. +-String _computeConstructorElementName(ConstructorElement element) { +- assert(element != null); +- var name = element.enclosingElement.name; +- var constructorName = element.name; +- if (!constructorName.isEmpty) { +- name = name + '.' + constructorName; +- } +- return name; +-} +- +-/// Create an anchor signature of the form '-'. +-String _getAnchorSignature(int start, int end) { +- return '$start-$end'; +-} +- +-String _getPath(ResourceProvider provider, Element e) { +- // TODO(jwren) This method simply serves to provide the WORKSPACE relative +- // path for sources in Elements, it needs to be written in a more robust way. +- // TODO(jwren) figure out what source generates a e != null, but +- // e.source == null to ensure that it is not a bug somewhere in the stack. +- if (e == null || e.source == null) { +- // null sometimes when the element is used to generate the node type +- // "dynamic" +- return ''; +- } +- String path = e.source.fullName; +- BazelWorkspace bazelWorkspace = BazelWorkspace.find(provider, path); +- if (bazelWorkspace != null) { +- return provider.pathContext.relative(path, from: bazelWorkspace.root); +- } +- GnWorkspace gnWorkspace = GnWorkspace.find(provider, path); +- if (gnWorkspace != null) { +- return provider.pathContext.relative(path, from: gnWorkspace.root); +- } +- if (path.lastIndexOf('CORPUS_NAME') != -1) { +- return path.substring(path.lastIndexOf('CORPUS_NAME') + 12); +- } +- return path; +-} +- +-/// If a non-null element is passed, the [SignatureElementVisitor] is used to +-/// generate and return a [String] signature, otherwise [schema.DYNAMIC_KIND] is +-/// returned. +-String _getSignature(ResourceProvider provider, Element element, +- String nodeKind, String corpus) { +- assert(nodeKind != schema.ANCHOR_KIND); // Call _getAnchorSignature instead +- if (element == null) { +- return schema.DYNAMIC_KIND; +- } +- if (element is CompilationUnitElement) { +- return _getPath(provider, element); +- } +- return '$nodeKind:${element.accept(SignatureElementVisitor.instance)}'; +-} +- +-class CodedBufferWriter { +- CodedBufferWriter(var v); +- toBuffer() {} +-} +- +-/// This visitor writes out Kythe facts and edges as specified by the Kythe +-/// Schema here https://kythe.io/docs/schema/. This visitor handles all nodes, +-/// facts and edges. +-class KytheDartVisitor extends GeneralizingAstVisitor with OutputUtils { +- final ResourceProvider resourceProvider; +- final List entries; +- final String corpus; +- final InheritanceManager _inheritanceManager; +- final String _contents; +- +- String _enclosingFilePath = ''; +- Element _enclosingElement; +- ClassElement _enclosingClassElement; +- KytheVName _enclosingVName; +- KytheVName _enclosingFileVName; +- KytheVName _enclosingClassVName; +- +- KytheDartVisitor(this.resourceProvider, this.entries, this.corpus, +- this._inheritanceManager, this._contents); +- +- @override +- String get enclosingFilePath => _enclosingFilePath; +- +- @override +- visitAnnotation(Annotation node) { +- // TODO(jwren) To get the full set of cross refs correct, additional ref +- // edges are needed, example: from "A" in "A.namedConstructor()" +- +- var start = node.name.offset; +- var end = node.name.end; +- if (node.constructorName != null) { +- end = node.constructorName.end; +- } +- var refVName = _handleRefEdge( +- node.element, +- const [schema.REF_EDGE], +- start: start, +- end: end, +- ); +- if (refVName != null) { +- var parentNode = node.parent; +- if (parentNode is Declaration) { +- Element parentElement = parentNode.element; +- if (parentNode is TopLevelVariableDeclaration) { +- _handleVariableDeclarationListAnnotations( +- parentNode.variables, refVName); +- } else if (parentNode is FieldDeclaration) { +- _handleVariableDeclarationListAnnotations( +- parentNode.fields, refVName); +- } else if (parentElement != null) { +- var parentVName = +- _vNameFromElement(parentElement, _getNodeKind(parentElement)); +- addEdge(parentVName, schema.ANNOTATED_BY_EDGE, refVName); +- } else { +- // parentAstNode is not a variable declaration node and +- // parentElement == null +- assert(false); +- } +- } else { +- // parentAstNode is not a Declaration +- // TODO(jwren) investigate +-// throw new Exception('parentAstNode.runtimeType = ${parentAstNode.runtimeType}'); +-// assert(false); +- } +- } +- +- // visit children +- _safelyVisit(node.arguments); +- } +- +- @override +- visitAssignmentExpression(AssignmentExpression node) { +- // +- // operator +- // NOTE: usage node only written out if assignment is not the '=' operator, +- // we are looking for an operator such as +=, -=, *=, /= +- // +- Token operator = node.operator; +- MethodElement element = node.bestElement; +- if (operator.type != TokenType.EQ && element != null) { +- // method +- _vNameFromElement(element, schema.FUNCTION_KIND); +- +- // anchor- ref/call +- _handleRefCallEdge(element, +- syntacticEntity: node.operator, enclosingTarget: _enclosingVName); +- +- // TODO (jwren) Add function type information +- } +- // visit children +- _safelyVisit(node.leftHandSide); +- _safelyVisit(node.rightHandSide); +- } +- +- @override +- visitBinaryExpression(BinaryExpression node) { +- // +- // operators such as +, -, *, / +- // +- MethodElement element = node.bestElement; +- if (element != null) { +- // method +- _vNameFromElement(element, schema.FUNCTION_KIND); +- +- // anchor- ref/call +- _handleRefCallEdge(element, +- syntacticEntity: node.operator, enclosingTarget: _enclosingVName); +- +- // TODO (jwren) Add function type information +- } +- // visit children +- _safelyVisit(node.leftOperand); +- _safelyVisit(node.rightOperand); +- } +- +- @override +- visitClassDeclaration(ClassDeclaration node) { +- return _withEnclosingElement(node.element, () { +- // record/ class node +- addNodeAndFacts(schema.RECORD_KIND, +- nodeVName: _enclosingClassVName, +- subKind: schema.CLASS_SUBKIND, +- completeFact: schema.DEFINITION); +- +- // anchor- defines/binding +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.name, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: _enclosingClassVName, +- enclosingTarget: _enclosingFileVName); +- +- // anchor- defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node, +- edges: [ +- schema.DEFINES_EDGE, +- ], +- target: _enclosingClassVName); +- +- // extends +- var supertype = _enclosingClassElement.supertype; +- if (supertype?.element != null) { +- var recordSupertypeVName = +- _vNameFromElement(supertype.element, schema.RECORD_KIND); +- addEdge( +- _enclosingClassVName, schema.EXTENDS_EDGE, recordSupertypeVName); +- } +- +- // implements +- var interfaces = _enclosingClassElement.interfaces; +- for (var interface in interfaces) { +- if (interface.element != null) { +- var recordInterfaceVName = +- _vNameFromElement(interface.element, schema.RECORD_KIND); +- addEdge( +- _enclosingClassVName, schema.EXTENDS_EDGE, recordInterfaceVName); +- } +- } +- +- // mixins +- var mixins = _enclosingClassElement.mixins; +- for (var mixin in mixins) { +- if (mixin.element != null) { +- var recordMixinVName = +- _vNameFromElement(mixin.element, schema.RECORD_KIND); +- addEdge(_enclosingClassVName, schema.EXTENDS_EDGE, recordMixinVName); +- } +- } +- +- // TODO (jwren) type parameters +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.extendsClause); +- _safelyVisit(node.implementsClause); +- _safelyVisit(node.withClause); +- _safelyVisit(node.nativeClause); +- _safelyVisitList(node.members); +- _safelyVisit(node.typeParameters); +- }); +- } +- +- @override +- visitClassTypeAlias(ClassTypeAlias node) { +- return _withEnclosingElement(node.element, () { +- // record/ class node +- addNodeAndFacts(schema.RECORD_KIND, +- nodeVName: _enclosingClassVName, +- subKind: schema.CLASS_SUBKIND, +- completeFact: schema.DEFINITION); +- +- // anchor +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.name, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: _enclosingClassVName, +- enclosingTarget: _enclosingFileVName); +- +- // +- // superclass +- // The super type is not in an ExtendsClause (as is the case with +- // ClassDeclarations) and super.visitClassTypeAlias is not sufficient. +- // +- _handleRefEdge( +- node.superclass.name.bestElement, +- const [schema.REF_EDGE], +- syntacticEntity: node.superclass, +- ); +- // TODO(jwren) refactor the following lines into a method that can be used +- // by visitClassDeclaration() +- // extends +- var recordSupertypeVName = _vNameFromElement( +- node.superclass.name.bestElement, schema.RECORD_KIND); +- addEdge(_enclosingClassVName, schema.EXTENDS_EDGE, recordSupertypeVName); +- +- // implements +- var interfaces = _enclosingClassElement.interfaces; +- for (var interface in interfaces) { +- if (interface.element != null) { +- var recordInterfaceVName = +- _vNameFromElement(interface.element, schema.RECORD_KIND); +- addEdge( +- _enclosingClassVName, schema.EXTENDS_EDGE, recordInterfaceVName); +- } +- } +- +- // mixins +- var mixins = _enclosingClassElement.mixins; +- for (var mixin in mixins) { +- if (mixin.element != null) { +- var recordMixinVName = +- _vNameFromElement(mixin.element, schema.RECORD_KIND); +- addEdge(_enclosingClassVName, schema.EXTENDS_EDGE, recordMixinVName); +- } +- } +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.typeParameters); +- _safelyVisit(node.withClause); +- _safelyVisit(node.implementsClause); +- }); +- } +- +- @override +- visitCompilationUnit(CompilationUnit node) { +- _enclosingFilePath = _getPath(resourceProvider, node.element); +- return _withEnclosingElement(node.element, () { +- addFact(_enclosingFileVName, schema.NODE_KIND_FACT, +- _encode(schema.FILE_KIND)); +- addFact(_enclosingFileVName, schema.TEXT_FACT, _encode(_contents)); +- addFact(_enclosingFileVName, schema.TEXT_ENCODING_FACT, +- _encode(schema.DEFAULT_TEXT_ENCODING)); +- +- // handle LibraryDirective: +- +- // A "package" VName in Kythe, schema.PACKAGE_KIND, is a Dart "library". +- +- // Don't use visitLibraryDirective as this won't generate a package +- // VName for libraries that don't have a library directive. +- var libraryElement = +- resolutionMap.elementDeclaredByCompilationUnit(node).library; +- if (libraryElement.definingCompilationUnit == node.element) { +- LibraryDirective libraryDirective; +- for (var directive in node.directives) { +- if (directive is LibraryDirective) { +- libraryDirective = directive; +- break; +- } +- } +- +- var start = 0; +- var end = 0; +- if (libraryDirective != null) { +- start = libraryDirective.name.offset; +- end = libraryDirective.name.end; +- } +- +- // package node +- var packageVName = addNodeAndFacts(schema.PACKAGE_KIND, +- element: libraryElement, completeFact: schema.DEFINITION); +- +- // anchor +- addAnchorEdgesContainingEdge( +- start: start, +- end: end, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: packageVName, +- enclosingTarget: _enclosingFileVName); +- } +- +- super.visitCompilationUnit(node); +- }); +- } +- +- @override +- visitConstructorDeclaration(ConstructorDeclaration node) { +- return _withEnclosingElement(node.element, () { +- // function/ constructor node +- var constructorVName = addNodeAndFacts(schema.FUNCTION_KIND, +- element: node.element, +- subKind: schema.CONSTRUCTOR_SUBKIND, +- completeFact: schema.DEFINITION); +- +- // anchor +- var start = node.returnType.offset; +- var end = node.returnType.end; +- if (node.name != null) { +- end = node.name.end; +- } +- addAnchorEdgesContainingEdge( +- start: start, +- end: end, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: constructorVName, +- enclosingTarget: _enclosingClassVName); +- +- // function type +- addFunctionType(node.element, node.parameters, constructorVName, +- returnNode: node.returnType); +- +- // TODO(jwren) handle implicit constructor case +- // TODO(jwren) handle redirected constructor case +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.parameters); +- _safelyVisitList(node.initializers); +- _safelyVisit(node.body); +- }); +- } +- +- @override +- visitDeclaredIdentifier(DeclaredIdentifier node) { +- _handleVariableDeclaration(node.element, node.identifier, +- subKind: schema.LOCAL_SUBKIND, +- type: resolutionMap.elementDeclaredByDeclaredIdentifier(node).type); +- +- // no children +- } +- +- @override +- visitEnumConstantDeclaration(EnumConstantDeclaration node) { +- // constant node +- var constDeclVName = +- addNodeAndFacts(schema.CONSTANT_KIND, element: node.element); +- +- // anchor- defines/binding, defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.name, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- schema.DEFINES_EDGE, +- ], +- target: constDeclVName, +- enclosingTarget: _enclosingClassVName); +- +- // no children +- } +- +- @override +- visitEnumDeclaration(EnumDeclaration node) { +- return _withEnclosingElement(node.element, () { +- // record/ enum node +- addNodeAndFacts(schema.RECORD_KIND, +- nodeVName: _enclosingClassVName, +- subKind: schema.ENUM_CLASS_SUBKIND, +- completeFact: schema.DEFINITION); +- +- // anchor- defines/binding +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.name, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: _enclosingClassVName, +- enclosingTarget: _enclosingFileVName); +- +- // anchor- defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node, +- edges: [ +- schema.DEFINES_EDGE, +- ], +- target: _enclosingClassVName); +- +- // visit children +- _safelyVisitList(node.constants); +- }); +- } +- +- @override +- visitFieldFormalParameter(FieldFormalParameter node) { +- // identifier +- // Specified as Element, not var, so that the type can be changed in the +- // if-block. +- Element element = node.element; +- if (element is FieldFormalParameterElement) { +- element = (element as FieldFormalParameterElement).field; +- } +- _handleRefEdge( +- element, +- const [schema.REF_EDGE], +- syntacticEntity: node.identifier, +- ); +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.type); +- _safelyVisit(node.typeParameters); +- _safelyVisit(node.parameters); +- } +- +- @override +- visitFunctionDeclaration(FunctionDeclaration node) { +- return _withEnclosingElement(node.element, () { +- // function node +- var functionVName = addNodeAndFacts(schema.FUNCTION_KIND, +- element: node.element, completeFact: schema.DEFINITION); +- +- // anchor- defines/binding +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.name, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: functionVName, +- enclosingTarget: _enclosingFileVName); +- +- // anchor- defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node, +- edges: [ +- schema.DEFINES_EDGE, +- ], +- target: functionVName); +- +- // function type +- addFunctionType( +- node.element, node.functionExpression.parameters, functionVName, +- returnNode: node.returnType); +- +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.returnType); +- _safelyVisit(node.functionExpression); +- }); +- } +- +- @override +- visitFunctionExpression(FunctionExpression node) { +- return _withEnclosingElement( +- node.element, () => super.visitFunctionExpression(node)); +- } +- +- @override +- visitFunctionTypeAlias(FunctionTypeAlias node) { +- // +- // return type +- // +- var returnType = node.returnType; +- if (returnType is TypeName) { +- _handleRefEdge( +- returnType.name?.bestElement, +- const [schema.REF_EDGE], +- syntacticEntity: returnType.name, +- ); +- } else if (returnType is GenericFunctionType) { +- // TODO(jwren): add support for generic function types. +- throw new UnimplementedError(); +- } else if (returnType != null) { +- throw new StateError( +- 'Unexpected TypeAnnotation subtype: ${returnType.runtimeType}'); +- } +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.typeParameters); +- _safelyVisit(node.parameters); +- } +- +- @override +- visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { +- // TODO(jwren) Missing graph coverage on FunctionTypedFormalParameters +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.identifier); +- _safelyVisit(node.typeParameters); +- _safelyVisit(node.parameters); +- } +- +- @override +- visitImportDirective(ImportDirective node) { +- // uri +- _handleUriReference(node.uri, node.uriElement); +- +- // prefix +- var prefixIdentifier = node.prefix; +- +- if (prefixIdentifier != null) { +- // variable +- _handleVariableDeclaration( +- prefixIdentifier.staticElement, prefixIdentifier); +- } +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisitList(node.combinators); +- _safelyVisitList(node.configurations); +- _safelyVisit(node.uri); +- } +- +- @override +- visitIndexExpression(IndexExpression node) { +- // +- // index method ref/call +- // +- var element = node.bestElement; +- var start = node.leftBracket.offset; +- var end = node.rightBracket.end; +- +- // anchor- ref/call +- _handleRefCallEdge(element, +- start: start, end: end, enclosingTarget: _enclosingVName); +- +- // visit children +- _safelyVisit(node.target); +- _safelyVisit(node.index); +- } +- +- @override +- visitInstanceCreationExpression(InstanceCreationExpression node) { +- // +- // constructorName +- // +- var constructorName = node.constructorName; +- var constructorElement = +- resolutionMap.staticElementForConstructorReference(constructorName); +- if (constructorElement != null) { +- // anchor- ref/call +- _handleRefCallEdge(constructorElement, +- syntacticEntity: constructorName, enclosingTarget: _enclosingVName); +- +- // Now write out a ref edge from the same anchor (constructorName) to the +- // enclosing class of the called constructor, this will make the +- // invocation of a constructor discoverable when someone inquires about +- // references to the class. +- // +- // We can't call _handleRefEdge as the anchor node has already been +- // written out. +- var enclosingEltVName = _vNameFromElement( +- constructorElement.enclosingElement, schema.RECORD_KIND); +- var anchorVName = +- _vNameAnchor(constructorName.offset, constructorName.end); +- addEdge(anchorVName, schema.REF_EDGE, enclosingEltVName); +- +- // TODO(jwren): investigate +- // assert (element.enclosingElement != null); +- } +- // visit children +- _safelyVisitList(constructorName.type.typeArguments?.arguments); +- _safelyVisit(node.argumentList); +- } +- +- @override +- visitMethodDeclaration(MethodDeclaration node) { +- return _withEnclosingElement(node.element, () { +- // function node +- var methodVName = addNodeAndFacts(schema.FUNCTION_KIND, +- element: node.element, completeFact: schema.DEFINITION); +- +- // anchor- defines/binding +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.name, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: methodVName, +- enclosingTarget: _enclosingClassVName); +- +- // anchor- defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node, +- edges: [ +- schema.DEFINES_EDGE, +- ], +- target: methodVName); +- +- // function type +- addFunctionType(node.element, node.parameters, methodVName, +- returnNode: node.returnType); +- +- // override edges +- List overriddenList = +- _inheritanceManager.lookupOverrides(_enclosingClassElement, +- resolutionMap.elementDeclaredByMethodDeclaration(node).name); +- for (ExecutableElement overridden in overriddenList) { +- if (overridden is MultiplyInheritedExecutableElement) { +- for (ExecutableElement elt in overridden.inheritedElements) { +- addEdge(methodVName, schema.OVERRIDES_EDGE, +- _vNameFromElement(elt, schema.FUNCTION_KIND)); +- } +- } else { +- addEdge(methodVName, schema.OVERRIDES_EDGE, +- _vNameFromElement(overridden, schema.FUNCTION_KIND)); +- } +- } +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.returnType); +- _safelyVisit(node.typeParameters); +- _safelyVisit(node.parameters); +- _safelyVisit(node.body); +- }); +- } +- +- @override +- visitMethodInvocation(MethodInvocation node) { +- var element = node.methodName?.bestElement; +- +- // anchor- ref/call +- _handleRefCallEdge(element, syntacticEntity: node.methodName); +- +- // visit children +- _safelyVisit(node.target); +- _safelyVisit(node.typeArguments); +- _safelyVisit(node.argumentList); +- } +- +- @override +- visitSimpleFormalParameter(SimpleFormalParameter node) { +- // parameter node +- var paramVName = addNodeAndFacts(schema.VARIABLE_KIND, +- element: node.element, +- subKind: schema.LOCAL_PARAMETER_SUBKIND, +- completeFact: schema.DEFINITION); +- +- // node.identifier can be null in cases with the new generic function type +- // syntax +- // TODO(jwren) add test cases for this situation +- if (node.identifier != null) { +- // The anchor and anchor edges generation are broken into two cases, the +- // first case is "method(parameter_name) ...", where the the parameter +- // character range only includes a parameter name. The second case is for +- // parameter declarations which are prefixed with a type, 'var', or +- // 'dynamic', as in "method(var parameter_name) ...". +- // +- // With the first case a single anchor range is created, for the second +- // case an anchor is created on parameter_name, as well as the range +- // including any prefixes. +- if (node.offset == node.identifier.offset && +- node.length == node.identifier.length) { +- // anchor- defines/binding, defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.identifier, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- schema.DEFINES_EDGE, +- ], +- target: paramVName, +- enclosingTarget: _enclosingVName); +- } else { +- // anchor- defines/binding +- addAnchorEdgesContainingEdge( +- syntacticEntity: node.identifier, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: paramVName, +- enclosingTarget: _enclosingVName); +- +- // anchor- defines +- addAnchorEdgesContainingEdge( +- syntacticEntity: node, +- edges: [ +- schema.DEFINES_EDGE, +- ], +- target: paramVName); +- } +- } +- +- // type +- addEdge( +- paramVName, +- schema.TYPED_EDGE, +- _vNameFromType( +- resolutionMap.elementDeclaredByFormalParameter(node).type)); +- +- // visit children +- _safelyVisit(node.documentationComment); +- _safelyVisitList(node.metadata); +- _safelyVisit(node.type); +- } +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- // Most simple identifiers are "ref" edges. In cases some cases, there may +- // be other ref/* edges. +- +- if (node.getAncestor((node) => node is CommentReference) != null) { +- // The identifier is in a comment, add just the "ref" edge. +- _handleRefEdge( +- node.bestElement, +- const [schema.REF_EDGE], +- syntacticEntity: node, +- ); +- } else if (node.inDeclarationContext()) { +- // The node is in a declaration context, and should have +- // "ref/defines/binding" edge as well as the default "ref" edge. +- _handleRefEdge( +- node.bestElement, +- const [schema.DEFINES_BINDING_EDGE, schema.REF_EDGE], +- syntacticEntity: node, +- ); +- } else { +- _handleRefCallEdge(node.bestElement, syntacticEntity: node); +- } +- +- // no children to visit +- } +- +- @override +- visitSuperExpression(SuperExpression node) { +- _handleThisOrSuper(node); +- } +- +- @override +- visitThisExpression(ThisExpression node) { +- _handleThisOrSuper(node); +- } +- +- @override +- visitUriBasedDirective(UriBasedDirective node) { +- _handleUriReference(node.uri, node.uriElement); +- +- // visit children +- super.visitUriBasedDirective(node); +- } +- +- @override +- visitVariableDeclaration(VariableDeclaration node) { +- var isLocal = _enclosingVName != _enclosingClassVName && +- _enclosingVName != _enclosingFileVName; +- +- // variable +- _handleVariableDeclaration(node.element, node.name, +- subKind: isLocal ? schema.LOCAL_SUBKIND : schema.FIELD_SUBKIND, +- type: resolutionMap.elementDeclaredByVariableDeclaration(node).type); +- +- // visit children +- _safelyVisit(node.initializer); +- } +- +- Element _findNonSyntheticElement(Element element) { +- if (element == null || !element.isSynthetic) { +- return element; +- } +- if (element is PropertyAccessorElement) { +- if (!element.variable.isSynthetic) { +- return element.variable; +- } else if (element.correspondingGetter != null && +- !element.correspondingGetter.isSynthetic) { +- return element.correspondingGetter; +- } else if (element.correspondingSetter != null && +- !element.correspondingSetter.isSynthetic) { +- return element.correspondingSetter; +- } +- } +- return null; +- } +- +- String _getNodeKind(Element e) { +- if (e is FieldElement && e.isEnumConstant) { +- // FieldElement is a kind of VariableElement, so this test case must be +- // before the e is VariableElement check. +- return schema.CONSTANT_KIND; +- } else if (e is VariableElement || e is PrefixElement) { +- return schema.VARIABLE_KIND; +- } else if (e is ExecutableElement) { +- return schema.FUNCTION_KIND; +- } else if (e is ClassElement || e is TypeParameterElement) { +- // TODO(jwren): this should be using absvar instead, see +- // https://kythe.io/docs/schema/#absvar +- return schema.RECORD_KIND; +- } +- return null; +- } +- +- _handleRefCallEdge( +- Element element, { +- SyntacticEntity syntacticEntity: null, +- start: _notFound, +- end: _notFound, +- KytheVName enclosingTarget: null, +- }) { +- if (element is ExecutableElement && +- _enclosingVName != _enclosingFileVName) { +- _handleRefEdge( +- element, +- const [schema.REF_CALL_EDGE, schema.REF_EDGE], +- syntacticEntity: syntacticEntity, +- start: start, +- end: end, +- enclosingTarget: enclosingTarget, +- enclosingAnchor: _enclosingVName, +- ); +- } else { +- _handleRefEdge( +- element, +- const [schema.REF_EDGE], +- syntacticEntity: syntacticEntity, +- start: start, +- end: end, +- enclosingTarget: enclosingTarget, +- ); +- } +- } +- +- /// This is a convenience method for adding ref edges. If the [start] and +- /// [end] offsets are provided, they are used, otherwise the offsets are +- /// computed by using the [syntacticEntity]. The list of edges is assumed to +- /// be non-empty, and are added from the anchor to the target generated using +- /// the passed [Element]. The created [KytheVName] is returned, if not `null` +- /// is returned. +- KytheVName _handleRefEdge( +- Element element, +- List refEdgeTypes, { +- SyntacticEntity syntacticEntity: null, +- start: _notFound, +- end: _notFound, +- KytheVName enclosingTarget: null, +- KytheVName enclosingAnchor: null, +- }) { +- assert(refEdgeTypes.isNotEmpty); +- element = _findNonSyntheticElement(element); +- if (element == null) { +- return null; +- } +- +- // vname +- var nodeKind = _getNodeKind(element); +- if (nodeKind == null || nodeKind.isEmpty) { +- return null; +- } +- var vName = _vNameFromElement(element, nodeKind); +- assert(vName != null); +- +- // anchor +- addAnchorEdgesContainingEdge( +- start: start, +- end: end, +- syntacticEntity: syntacticEntity, +- edges: refEdgeTypes, +- target: vName, +- enclosingTarget: enclosingTarget, +- enclosingAnchor: enclosingAnchor, +- ); +- +- return vName; +- } +- +- void _handleThisOrSuper(Expression thisOrSuperNode) { +- DartType type = thisOrSuperNode.staticType; +- if (type != null && type.element != null) { +- // Expected SuperExpression.staticType to return the type of the +- // supertype, but it returns the type of the enclosing class (same as +- // ThisExpression), do some additional work to correct assumption: +- if (thisOrSuperNode is SuperExpression && type.element is ClassElement) { +- DartType supertype = (type.element as ClassElement).supertype; +- if (supertype != null) { +- type = supertype; +- } +- } +- // vname +- var vName = _vNameFromElement(type.element, schema.RECORD_KIND); +- +- // anchor +- var anchorVName = addAnchorEdgesContainingEdge( +- syntacticEntity: thisOrSuperNode, +- edges: [schema.REF_EDGE], +- target: vName); +- +- // childof from the anchor +- addEdge(anchorVName, schema.CHILD_OF_EDGE, _enclosingVName); +- } +- +- // no children to visit +- } +- +- void _handleVariableDeclaration( +- Element element, SyntacticEntity syntacticEntity, +- {String subKind, DartType type}) { +- // variable +- var variableVName = addNodeAndFacts(schema.VARIABLE_KIND, +- element: element, subKind: subKind, completeFact: schema.DEFINITION); +- +- // anchor +- addAnchorEdgesContainingEdge( +- syntacticEntity: syntacticEntity, +- edges: [ +- schema.DEFINES_BINDING_EDGE, +- ], +- target: variableVName, +- enclosingTarget: _enclosingVName); +- +- // type +- if (type != null) { +- addEdge(variableVName, schema.TYPED_EDGE, _vNameFromType(type)); +- } +- } +- +- /// Add a "ref/imports" edge from the passed [uriNode] location to the +- /// [referencedElement] [Element]. If the passed element is null, the edge is +- /// not written out. +- void _handleUriReference(StringLiteral uriNode, Element referencedElement) { +- if (referencedElement != null) { +- var start = uriNode.offset; +- var end = uriNode.end; +- +- // The following is the expected and common case. +- // The contents between the quotes is used as the location to work well +- // with CodeSearch. +- if (uriNode is SimpleStringLiteral) { +- start = uriNode.contentsOffset; +- end = uriNode.contentsEnd; +- } +- +- // package node +- var packageVName = +- _vNameFromElement(referencedElement, schema.PACKAGE_KIND); +- +- // anchor +- addAnchorEdgesContainingEdge( +- start: start, +- end: end, +- edges: [schema.REF_IMPORTS_EDGE], +- target: packageVName, +- enclosingTarget: _enclosingFileVName); +- } +- } +- +- _handleVariableDeclarationListAnnotations( +- VariableDeclarationList variableDeclarationList, KytheVName refVName) { +- assert(refVName != null); +- for (var varDecl in variableDeclarationList.variables) { +- if (varDecl.element != null) { +- var parentVName = +- _vNameFromElement(varDecl.element, schema.VARIABLE_KIND); +- addEdge(parentVName, schema.ANNOTATED_BY_EDGE, refVName); +- } else { +- // The element out of the VarDeclarationList is null +- assert(false); +- } +- } +- } +- +- /// If the given [node] is not `null`, accept this visitor. +- void _safelyVisit(AstNode node) { +- if (node != null) { +- node.accept(this); +- } +- } +- +- /// If the given [nodeList] is not `null`, accept this visitor. +- void _safelyVisitList(NodeList nodeList) { +- if (nodeList != null) { +- nodeList.accept(this); +- } +- } +- +- _withEnclosingElement(Element element, f()) { +- Element outerEnclosingElement = _enclosingElement; +- Element outerEnclosingClassElement = _enclosingClassElement; +- var outerEnclosingVName = _enclosingVName; +- var outerEnclosingClassVName = _enclosingClassVName; +- try { +- _enclosingElement = element; +- if (element is CompilationUnitElement) { +- _enclosingFileVName = _enclosingVName = _vNameFile(); +- } else if (element is ClassElement) { +- _enclosingClassElement = element; +- _enclosingClassVName = _enclosingVName = +- _vNameFromElement(_enclosingClassElement, schema.RECORD_KIND); +- } else if (element is MethodElement || +- element is FunctionElement || +- element is ConstructorElement) { +- _enclosingVName = +- _vNameFromElement(_enclosingElement, schema.FUNCTION_KIND); +- } +- return f(); +- } finally { +- _enclosingElement = outerEnclosingElement; +- _enclosingClassElement = outerEnclosingClassElement; +- _enclosingClassVName = outerEnclosingClassVName; +- _enclosingVName = outerEnclosingVName; +- } +- } +-} +- +-/// This class is meant to be a mixin to concrete visitor methods to walk the +-/// [Element] or [AstNode]s produced by the Dart Analyzer to output Kythe +-/// [KytheEntry] protos. +-abstract class OutputUtils { +- /// A set of [String]s which have already had a name [KytheVName] created. +- final Set nameNodes = new Set(); +- +- String get corpus; +- +- KytheVName get dynamicBuiltin => _vName(schema.DYNAMIC_KIND, '', '', ''); +- +- String get enclosingFilePath; +- +- List get entries; +- +- KytheVName get fnBuiltin => _vName(schema.FN_BUILTIN, '', '', ''); +- +- ResourceProvider get resourceProvider; +- +- KytheVName get voidBuiltin => _vName(schema.VOID_BUILTIN, '', '', ''); +- +- /// This is a convenience method for adding anchors. If the [start] and [end] +- /// offsets are provided, they are used, otherwise the offsets are computed by +- /// using the [syntacticEntity]. If a non-empty list of edges is provided, as +- /// well as a target, then this method also adds the edges from the anchor to +- /// target. The anchor [KytheVName] is returned. +- /// +- /// If a [target] and [enclosingTarget] are provided, a childof edge is +- /// written out from the target to the enclosing target. +- /// +- /// If an [enclosingAnchor] is provided a childof edge is written out from the +- /// anchor to the enclosing anchor. In cases where ref/call is an edge, this +- /// is required to generate the callgraph. +- /// +- /// Finally, for all anchors, a childof edge with a target of the enclosing +- /// file is written out. +- KytheVName addAnchorEdgesContainingEdge({ +- SyntacticEntity syntacticEntity: null, +- int start: _notFound, +- int end: _notFound, +- List edges: const [], +- KytheVName target: null, +- KytheVName enclosingTarget: null, +- KytheVName enclosingAnchor: null, +- }) { +- if (start == _notFound && end == _notFound) { +- if (syntacticEntity != null) { +- start = syntacticEntity.offset; +- end = syntacticEntity.end; +- } else { +- throw new Exception('Offset positions were not provided when calling ' +- 'addAnchorEdgesContainingEdge'); +- } +- } +- // TODO(jwren) investigate +-// assert(start < end); +- var anchorVName = _vNameAnchor(start, end); +- addFact(anchorVName, schema.NODE_KIND_FACT, _encode(schema.ANCHOR_KIND)); +- addFact(anchorVName, schema.ANCHOR_START_FACT, _encodeInt(start)); +- addFact(anchorVName, schema.ANCHOR_END_FACT, _encodeInt(end)); +- if (target != null) { +- for (String edge in edges) { +- addEdge(anchorVName, edge, target); +- } +- if (enclosingTarget != null) { +- addEdge(target, schema.CHILD_OF_EDGE, enclosingTarget); +- } +- } +- // If provided, write out the childof edge to the enclosing anchor +- if (enclosingAnchor != null) { +- addEdge(anchorVName, schema.CHILD_OF_EDGE, enclosingAnchor); +- } +- +- // Assert that if ref/call is one of the edges, that and enclosing anchor +- // was provided for the callgraph. +- // Documentation at http://kythe.io/docs/schema/callgraph.html +- if (edges.contains(schema.REF_CALL_EDGE)) { +- assert(enclosingAnchor != null); +- } +- +- // Finally add the childof edge to the enclosing file VName. +- addEdge(anchorVName, schema.CHILD_OF_EDGE, _vNameFile()); +- return anchorVName; +- } +- +- /// TODO(jwren): for cases where the target is a name, we need the same kind +- /// of logic as [addNameFact] to prevent the edge from being written out. +- /// This is a convenience method for visitors to add an edge Entry. +- KytheEntry addEdge(KytheVName source, String edgeKind, KytheVName target, +- {int ordinalIntValue: _notFound}) { +- if (ordinalIntValue == _notFound) { +- return addEntry(source, edgeKind, target, "/", new List()); +- } else { +- return addEntry(source, edgeKind, target, schema.ORDINAL, +- _encodeInt(ordinalIntValue)); +- } +- } +- +- KytheEntry addEntry(KytheVName source, String edgeKind, KytheVName target, +- String factName, List factValue) { +- assert(source != null); +- assert(factName != null); +- assert(factValue != null); +- // factValue may be an empty array, the fact may be that a file text or +- // document text is empty +- if (edgeKind == null || edgeKind.isEmpty) { +- edgeKind = null; +- target = null; +- } +- var entry = new KytheEntry(source, factName, +- kind: edgeKind, target: target, value: factValue); +- entries.add(entry); +- return entry; +- } +- +- /// This is a convenience method for visitors to add a fact [KytheEntry]. +- KytheEntry addFact(KytheVName source, String factName, List factValue) { +- return addEntry(source, null, null, factName, factValue); +- } +- +- /// This is a convenience method for adding function types. +- KytheVName addFunctionType( +- Element functionElement, +- FormalParameterList paramNodes, +- KytheVName functionVName, { +- AstNode returnNode: null, +- }) { +- var i = 0; +- var funcTypeVName = +- addNodeAndFacts(schema.TAPP_KIND, element: functionElement); +- addEdge(funcTypeVName, schema.PARAM_EDGE, fnBuiltin, ordinalIntValue: i++); +- +- var returnTypeVName; +- if (returnNode is TypeName) { +- // MethodDeclaration and FunctionDeclaration both return a TypeName from +- // returnType +- if (resolutionMap.typeForTypeName(returnNode).isVoid) { +- returnTypeVName = voidBuiltin; +- } else { +- returnTypeVName = +- _vNameFromElement(returnNode.name.bestElement, schema.TAPP_KIND); +- } +- } else if (returnNode is Identifier) { +- // ConstructorDeclaration returns an Identifier from returnType +- if (resolutionMap.bestTypeForExpression(returnNode).isVoid) { +- returnTypeVName = voidBuiltin; +- } else { +- returnTypeVName = +- _vNameFromElement(returnNode.bestElement, schema.TAPP_KIND); +- } +- } +- // else: return type is null, void, unresolved. +- +- if (returnTypeVName != null) { +- addEdge(funcTypeVName, schema.PARAM_EDGE, returnTypeVName, +- ordinalIntValue: i++); +- } +- +- if (paramNodes != null) { +- for (FormalParameter paramNode in paramNodes.parameters) { +- var paramTypeVName = dynamicBuiltin; +- if (!resolutionMap +- .elementDeclaredByFormalParameter(paramNode) +- .type +- .isDynamic) { +- paramTypeVName = _vNameFromElement( +- resolutionMap +- .elementDeclaredByFormalParameter(paramNode) +- .type +- .element, +- schema.TAPP_KIND); +- } +- addEdge(funcTypeVName, schema.PARAM_EDGE, paramTypeVName, +- ordinalIntValue: i++); +- } +- } +- addEdge(functionVName, schema.TYPED_EDGE, funcTypeVName); +- return funcTypeVName; +- } +- +- /// This is a convenience method for adding nodes with facts. +- /// If an [KytheVName] is passed, it is used, otherwise an element is required +- /// which is used to create a [KytheVName]. Either [nodeVName] must be non-null or +- /// [element] must be non-null. Other optional parameters if passed are then +- /// used to set the associated facts on the [KytheVName]. This method does not +- /// currently guarantee that the inputs to these fact kinds are valid for the +- /// associated nodeKind- if a non-null, then it will set. +- KytheVName addNodeAndFacts(String nodeKind, +- {Element element: null, +- KytheVName nodeVName: null, +- String subKind: null, +- String completeFact: null}) { +- if (nodeVName == null) { +- nodeVName = _vNameFromElement(element, nodeKind); +- } +- addFact(nodeVName, schema.NODE_KIND_FACT, _encode(nodeKind)); +- if (subKind != null) { +- addFact(nodeVName, schema.SUBKIND_FACT, _encode(subKind)); +- } +- if (completeFact != null) { +- addFact(nodeVName, schema.COMPLETE_FACT, _encode(completeFact)); +- } +- return nodeVName; +- } +- +- List _encode(String str) { +- return UTF8.encode(str); +- } +- +- List _encodeInt(int i) { +- return UTF8.encode(i.toString()); +- } +- +- /// Given all parameters for a [KytheVName] this method creates and returns a +- /// [KytheVName]. +- KytheVName _vName(String signature, String corpus, String root, String path, +- [String language = schema.DART_LANG]) { +- return new KytheVName(signature, corpus, root, path, language); +- } +- +- /// Returns an anchor [KytheVName] corresponding to the given start and end +- /// offsets. +- KytheVName _vNameAnchor(int start, int end) { +- return _vName( +- _getAnchorSignature(start, end), corpus, '', enclosingFilePath); +- } +- +- /// Return the [KytheVName] for this file. +- KytheVName _vNameFile() { +- // file vnames, the signature and language are not set +- return _vName('', corpus, '', enclosingFilePath, ''); +- } +- +- /// Given some [Element] and Kythe node kind, this method generates and +- /// returns the [KytheVName]. +- KytheVName _vNameFromElement(Element e, String nodeKind) { +- assert(nodeKind != schema.FILE_KIND); +- // general case +- return _vName(_getSignature(resourceProvider, e, nodeKind, corpus), corpus, +- '', _getPath(resourceProvider, e)); +- } +- +- /// Returns a [KytheVName] corresponding to the given [DartType]. +- KytheVName _vNameFromType(DartType type) { +- if (type == null || type.isDynamic) { +- return dynamicBuiltin; +- } else if (type.isVoid) { +- return voidBuiltin; +- } else if (type.element is ClassElement) { +- return _vNameFromElement(type.element, schema.RECORD_KIND); +- } else { +- return dynamicBuiltin; +- } +- } +-} +- +-/// This visitor class should be used by [_getSignature]. +-/// +-/// This visitor is an [GeneralizingElementVisitor] which builds up a [String] +-/// signature for a given [Element], uniqueness is guaranteed within the +-/// enclosing file. +-class SignatureElementVisitor extends GeneralizingElementVisitor { +- static SignatureElementVisitor instance = new SignatureElementVisitor(); +- +- @override +- StringBuffer visitCompilationUnitElement(CompilationUnitElement e) { +- return new StringBuffer(); +- } +- +- @override +- StringBuffer visitElement(Element e) { +- assert(e is! MultiplyInheritedExecutableElement); +- var enclosingElt = e.enclosingElement; +- var buffer = enclosingElt.accept(this); +- if (buffer.isNotEmpty) { +- buffer.write('#'); +- } +- if (e is MethodElement && e.name == '-' && e.parameters.length == 1) { +- buffer.write('unary-'); +- } else if (e is ConstructorElement) { +- buffer.write(_computeConstructorElementName(e)); +- } else { +- buffer.write(e.name); +- } +- if (enclosingElt is ExecutableElement) { +- buffer..write('@')..write(e.nameOffset - enclosingElt.nameOffset); +- } +- return buffer; +- } +- +- @override +- StringBuffer visitLibraryElement(LibraryElement e) { +- return new StringBuffer('library:${e.displayName}'); +- } +- +- @override +- StringBuffer visitTypeParameterElement(TypeParameterElement e) { +- // It is legal to have a named constructor with the same name as a type +- // parameter. So we distinguish them by using '.' between the class (or +- // typedef) name and the type parameter name. +- return e.enclosingElement.accept(this)..write('.')..write(e.name); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/kythe/schema.dart b/pkg/analysis_server/lib/src/services/kythe/schema.dart +deleted file mode 100644 +index c354abb498b..00000000000 +--- a/pkg/analysis_server/lib/src/services/kythe/schema.dart ++++ /dev/null +@@ -1,82 +0,0 @@ +-// 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. +- +-/// This file gathers constant strings from the Kythe Schema: +-/// kythe.io/docs/schema/ +- +-/// Dart specific facts, labels, and kinds +-const DART_LANG = 'dart'; +-const DYNAMIC_KIND = 'dynamic#builtin'; +-const FN_BUILTIN = 'fn#builtin'; +-const VOID_BUILTIN = 'void#builtin'; +- +-/// Kythe node fact labels +-const NODE_KIND_FACT = '/kythe/node/kind'; +-const SUBKIND_FACT = '/kythe/subkind'; +- +-const ANCHOR_START_FACT = '/kythe/loc/start'; +-const ANCHOR_END_FACT = '/kythe/loc/end'; +- +-const SNIPPET_START_FACT = '/kythe/snippet/start'; +-const SNIPPET_END_FACT = '/kythe/snippet/end'; +- +-const TEXT_FACT = '/kythe/text'; +-const TEXT_ENCODING_FACT = '/kythe/text/encoding'; +- +-const COMPLETE_FACT = '/kythe/complete'; +- +-const TEXT_FORMAT = '/kythe/format'; +- +-/// DEFAULT_TEXT_ENCODING is the assumed value of the TEXT_ENCODING_FACT if it +-/// is empty or missing from a node with a TEXT_FACT. +-const DEFAULT_TEXT_ENCODING = 'UTF-8'; +- +-/// Kythe node kinds +-const ANCHOR_KIND = 'anchor'; +-const FILE_KIND = 'file'; +- +-const CONSTANT_KIND = 'constant'; +-const DOC_KIND = 'doc'; +-const ENUM_KIND = 'enum'; +-const FUNCTION_KIND = 'function'; +-const PACKAGE_KIND = 'package'; +-const RECORD_KIND = 'record'; +-const TAPP_KIND = 'tapp'; +-const VARIABLE_KIND = 'variable'; +- +-/// Kythe node subkinds +-const CLASS_SUBKIND = 'class'; +-const CONSTRUCTOR_SUBKIND = 'constructor'; +-const ENUM_CLASS_SUBKIND = 'enumClass'; +-const IMPLICIT_SUBKIND = 'implicit'; +-const FIELD_SUBKIND = 'field'; +-const LOCAL_SUBKIND = 'local'; +-const LOCAL_PARAMETER_SUBKIND = 'local/parameter'; +- +-/// Kythe complete states +-const INCOMPLETE = 'incomplete'; +-const DEFINITION = 'definition'; +- +-/// Kythe ordinal +-const ORDINAL = '/kythe/ordinal'; +- +-/// EdgePrefix is the standard Kythe prefix for all edge kinds. +-const EDGE_PREFIX = '/kythe/edge/'; +- +-/// Kythe edge kinds +-const ANNOTATED_BY_EDGE = EDGE_PREFIX + "annotatedby"; +-const CHILD_OF_EDGE = EDGE_PREFIX + "childof"; +-const EXTENDS_EDGE = EDGE_PREFIX + "extends"; +-const INSTANTIATES_EDGE = EDGE_PREFIX + "instantiates"; +-const OVERRIDES_EDGE = EDGE_PREFIX + "overrides"; +-const PARAM_EDGE = EDGE_PREFIX + "param"; +-const TYPED_EDGE = EDGE_PREFIX + "typed"; +- +-/// Kythe edge kinds associated with anchors +-const DEFINES_EDGE = EDGE_PREFIX + "defines"; +-const DEFINES_BINDING_EDGE = EDGE_PREFIX + "defines/binding"; +-const DOCUMENTS_EDGE = EDGE_PREFIX + "documents"; +-const REF_EDGE = EDGE_PREFIX + "ref"; +-const REF_CALL_EDGE = EDGE_PREFIX + "ref/call"; +-const REF_IMPORTS_EDGE = EDGE_PREFIX + "ref/imports"; +diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart +deleted file mode 100644 +index 0051772b52a..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart ++++ /dev/null +@@ -1,127 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * [ConvertMethodToGetterRefactoring] implementation. +- */ +-class ConvertGetterToMethodRefactoringImpl extends RefactoringImpl +- implements ConvertGetterToMethodRefactoring { +- final SearchEngine searchEngine; +- final AstProvider astProvider; +- final PropertyAccessorElement element; +- +- SourceChange change; +- +- ConvertGetterToMethodRefactoringImpl( +- this.searchEngine, this.astProvider, this.element); +- +- @override +- String get refactoringName => 'Convert Getter To Method'; +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- Future checkInitialConditions() { +- RefactoringStatus result = _checkInitialConditions(); +- return new Future.value(result); +- } +- +- @override +- Future createChange() async { +- change = new SourceChange(refactoringName); +- // function +- if (element.enclosingElement is CompilationUnitElement) { +- await _updateElementDeclaration(element); +- await _updateElementReferences(element); +- } +- // method +- if (element.enclosingElement is ClassElement) { +- FieldElement field = element.variable; +- Set elements = +- await getHierarchyMembers(searchEngine, field); +- await Future.forEach(elements, (ClassMemberElement member) async { +- if (member is FieldElement) { +- PropertyAccessorElement getter = member.getter; +- if (!getter.isSynthetic) { +- await _updateElementDeclaration(getter); +- return _updateElementReferences(getter); +- } +- } +- }); +- } +- // done +- return change; +- } +- +- @override +- bool requiresPreview() => false; +- +- RefactoringStatus _checkInitialConditions() { +- if (!element.isGetter || element.isSynthetic) { +- return new RefactoringStatus.fatal( +- 'Only explicit getters can be converted to methods.'); +- } +- return new RefactoringStatus(); +- } +- +- Future _updateElementDeclaration( +- PropertyAccessorElement element) async { +- // prepare "get" keyword +- Token getKeyword = null; +- { +- AstNode name = await astProvider.getParsedNameForElement(element); +- AstNode declaration = name?.parent; +- if (declaration is MethodDeclaration) { +- getKeyword = declaration.propertyKeyword; +- } else if (declaration is FunctionDeclaration) { +- getKeyword = declaration.propertyKeyword; +- } else { +- return; +- } +- } +- // remove "get " +- if (getKeyword != null) { +- SourceRange getRange = +- range.startOffsetEndOffset(getKeyword.offset, element.nameOffset); +- SourceEdit edit = newSourceEdit_range(getRange, ''); +- doSourceChange_addElementEdit(change, element, edit); +- } +- // add parameters "()" +- { +- SourceEdit edit = new SourceEdit(range.elementName(element).end, 0, '()'); +- doSourceChange_addElementEdit(change, element, edit); +- } +- } +- +- Future _updateElementReferences(Element element) async { +- List matches = await searchEngine.searchReferences(element); +- List references = getSourceReferences(matches); +- for (SourceReference reference in references) { +- Element refElement = reference.element; +- SourceRange refRange = reference.range; +- // insert "()" +- var edit = new SourceEdit(refRange.end, 0, "()"); +- doSourceChange_addElementEdit(change, refElement, edit); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart +deleted file mode 100644 +index 2ff0f5bf10d..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart ++++ /dev/null +@@ -1,143 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * [ConvertMethodToGetterRefactoring] implementation. +- */ +-class ConvertMethodToGetterRefactoringImpl extends RefactoringImpl +- implements ConvertMethodToGetterRefactoring { +- final SearchEngine searchEngine; +- final AstProvider astProvider; +- final ExecutableElement element; +- +- SourceChange change; +- +- ConvertMethodToGetterRefactoringImpl( +- this.searchEngine, this.astProvider, this.element); +- +- @override +- String get refactoringName => 'Convert Method To Getter'; +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- Future checkInitialConditions() async { +- // check Element type +- if (element is FunctionElement) { +- if (element.enclosingElement is! CompilationUnitElement) { +- return new RefactoringStatus.fatal( +- 'Only top-level functions can be converted to getters.'); +- } +- } else if (element is! MethodElement) { +- return new RefactoringStatus.fatal( +- 'Only class methods or top-level functions can be converted to getters.'); +- } +- // returns a value +- if (element.returnType != null && element.returnType.isVoid) { +- return new RefactoringStatus.fatal( +- 'Cannot convert ${element.kind.displayName} returning void.'); +- } +- // no parameters +- if (element.parameters.isNotEmpty) { +- return new RefactoringStatus.fatal( +- 'Only methods without parameters can be converted to getters.'); +- } +- // OK +- return new RefactoringStatus(); +- } +- +- @override +- Future createChange() async { +- change = new SourceChange(refactoringName); +- // FunctionElement +- if (element is FunctionElement) { +- await _updateElementDeclaration(element); +- await _updateElementReferences(element); +- } +- // MethodElement +- if (element is MethodElement) { +- MethodElement method = element; +- Set elements = +- await getHierarchyMembers(searchEngine, method); +- await Future.forEach(elements, (Element element) async { +- await _updateElementDeclaration(element); +- return _updateElementReferences(element); +- }); +- } +- // done +- return change; +- } +- +- @override +- bool requiresPreview() => false; +- +- Future _updateElementDeclaration(Element element) async { +- // prepare parameters +- FormalParameterList parameters; +- { +- AstNode name = await astProvider.getParsedNameForElement(element); +- AstNode declaration = name?.parent; +- if (declaration is MethodDeclaration) { +- parameters = declaration.parameters; +- } else if (declaration is FunctionDeclaration) { +- parameters = declaration.functionExpression.parameters; +- } else { +- return; +- } +- } +- // insert "get " +- { +- SourceEdit edit = new SourceEdit(element.nameOffset, 0, 'get '); +- doSourceChange_addElementEdit(change, element, edit); +- } +- // remove parameters +- { +- SourceEdit edit = newSourceEdit_range(range.node(parameters), ''); +- doSourceChange_addElementEdit(change, element, edit); +- } +- } +- +- Future _updateElementReferences(Element element) async { +- List matches = await searchEngine.searchReferences(element); +- List references = getSourceReferences(matches); +- for (SourceReference reference in references) { +- Element refElement = reference.element; +- SourceRange refRange = reference.range; +- // prepare invocation +- MethodInvocation invocation; +- { +- CompilationUnit refUnit = +- await astProvider.getParsedUnitForElement(refElement); +- AstNode refNode = +- new NodeLocator(refRange.offset).searchWithin(refUnit); +- invocation = refNode.getAncestor((node) => node is MethodInvocation); +- } +- // we need invocation +- if (invocation != null) { +- SourceEdit edit = newSourceEdit_range( +- range.startOffsetEndOffset(refRange.end, invocation.end), ''); +- doSourceChange_addElementEdit(change, refElement, edit); +- } +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart +deleted file mode 100644 +index 59153af0251..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart ++++ /dev/null +@@ -1,699 +0,0 @@ +-// Copyright (c) 2014, 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:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/name_suggestion.dart'; +-import 'package:analysis_server/src/services/correction/selection_analyzer.dart'; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-const String _TOKEN_SEPARATOR = "\uFFFF"; +- +-/** +- * [ExtractLocalRefactoring] implementation. +- */ +-class ExtractLocalRefactoringImpl extends RefactoringImpl +- implements ExtractLocalRefactoring { +- final CompilationUnit unit; +- final int selectionOffset; +- final int selectionLength; +- CompilationUnitElement unitElement; +- String file; +- SourceRange selectionRange; +- CorrectionUtils utils; +- +- String name; +- bool extractAll = true; +- final List coveringExpressionOffsets = []; +- final List coveringExpressionLengths = []; +- final List names = []; +- final List offsets = []; +- final List lengths = []; +- +- Expression rootExpression; +- Expression singleExpression; +- bool wholeStatementExpression = false; +- String stringLiteralPart; +- final List occurrences = []; +- final Map elementIds = {}; +- Set excludedVariableNames = new Set(); +- +- ExtractLocalRefactoringImpl( +- this.unit, this.selectionOffset, this.selectionLength) { +- unitElement = unit.element; +- selectionRange = new SourceRange(selectionOffset, selectionLength); +- utils = new CorrectionUtils(unit); +- file = unitElement.source.fullName; +- } +- +- @override +- String get refactoringName => 'Extract Local Variable'; +- +- String get _declarationKeyword { +- if (_isPartOfConstantExpression(rootExpression)) { +- return "const"; +- } else { +- return "var"; +- } +- } +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- result.addStatus(checkName()); +- return new Future.value(result); +- } +- +- @override +- Future checkInitialConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- // selection +- result.addStatus(_checkSelection()); +- if (result.hasFatalError) { +- return new Future.value(result); +- } +- // occurrences +- _prepareOccurrences(); +- _prepareOffsetsLengths(); +- // names +- excludedVariableNames = +- utils.findPossibleLocalVariableConflicts(selectionOffset); +- _prepareNames(); +- // done +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkName() { +- RefactoringStatus result = new RefactoringStatus(); +- result.addStatus(validateVariableName(name)); +- if (excludedVariableNames.contains(name)) { +- result.addError( +- format("The name '{0}' is already used in the scope.", name)); +- } +- return result; +- } +- +- @override +- Future createChange() { +- SourceChange change = new SourceChange(refactoringName); +- // prepare occurrences +- List occurrences; +- if (extractAll) { +- occurrences = this.occurrences; +- } else { +- occurrences = [selectionRange]; +- } +- occurrences.sort((a, b) => a.offset - b.offset); +- // If the whole expression of a statement is selected, like '1 + 2', +- // then convert it into a variable declaration statement. +- if (wholeStatementExpression && occurrences.length == 1) { +- String keyword = _declarationKeyword; +- String declarationSource = '$keyword $name = '; +- SourceEdit edit = +- new SourceEdit(singleExpression.offset, 0, declarationSource); +- doSourceChange_addElementEdit(change, unitElement, edit); +- return new Future.value(change); +- } +- // prepare positions +- List positions = []; +- int occurrencesShift = 0; +- void addPosition(int offset) { +- positions.add(new Position(file, offset)); +- } +- +- // add variable declaration +- { +- String declarationCode; +- int nameOffsetInDeclarationCode; +- if (stringLiteralPart != null) { +- declarationCode = 'var '; +- nameOffsetInDeclarationCode = declarationCode.length; +- declarationCode += "$name = '$stringLiteralPart';"; +- } else { +- String keyword = _declarationKeyword; +- String initializerCode = utils.getRangeText(selectionRange); +- declarationCode = '$keyword '; +- nameOffsetInDeclarationCode = declarationCode.length; +- declarationCode += '$name = $initializerCode;'; +- } +- // prepare location for declaration +- AstNode target = _findDeclarationTarget(occurrences); +- String eol = utils.endOfLine; +- // insert variable declaration +- if (target is Statement) { +- String prefix = utils.getNodePrefix(target); +- SourceEdit edit = +- new SourceEdit(target.offset, 0, declarationCode + eol + prefix); +- doSourceChange_addElementEdit(change, unitElement, edit); +- addPosition(edit.offset + nameOffsetInDeclarationCode); +- occurrencesShift = edit.replacement.length; +- } else if (target is ExpressionFunctionBody) { +- String prefix = utils.getNodePrefix(target.parent); +- String indent = utils.getIndent(1); +- Expression expr = target.expression; +- { +- String code = '{' + eol + prefix + indent; +- addPosition( +- target.offset + code.length + nameOffsetInDeclarationCode); +- code += declarationCode + eol; +- code += prefix + indent + 'return '; +- SourceEdit edit = +- new SourceEdit(target.offset, expr.offset - target.offset, code); +- occurrencesShift = target.offset + code.length - expr.offset; +- doSourceChange_addElementEdit(change, unitElement, edit); +- } +- doSourceChange_addElementEdit( +- change, +- unitElement, +- new SourceEdit( +- expr.end, target.end - expr.end, ';' + eol + prefix + '}')); +- } +- } +- // prepare replacement +- String occurrenceReplacement = name; +- if (stringLiteralPart != null) { +- occurrenceReplacement = "\${$name}"; +- occurrencesShift += 2; +- } +- // replace occurrences with variable reference +- for (SourceRange range in occurrences) { +- SourceEdit edit = newSourceEdit_range(range, occurrenceReplacement); +- addPosition(range.offset + occurrencesShift); +- occurrencesShift += name.length - range.length; +- doSourceChange_addElementEdit(change, unitElement, edit); +- } +- // add the linked group +- change.addLinkedEditGroup(new LinkedEditGroup( +- positions, +- name.length, +- names +- .map((name) => new LinkedEditSuggestion( +- name, LinkedEditSuggestionKind.VARIABLE)) +- .toList())); +- // done +- return new Future.value(change); +- } +- +- @override +- bool requiresPreview() => false; +- +- /** +- * Checks if [selectionRange] selects [Expression] which can be extracted, and +- * location of this [Expression] in AST allows extracting. +- */ +- RefactoringStatus _checkSelection() { +- String selectionStr; +- // exclude whitespaces +- { +- selectionStr = utils.getRangeText(selectionRange); +- int numLeading = countLeadingWhitespaces(selectionStr); +- int numTrailing = countTrailingWhitespaces(selectionStr); +- int offset = selectionRange.offset + numLeading; +- int end = selectionRange.end - numTrailing; +- selectionRange = new SourceRange(offset, end - offset); +- } +- // get covering node +- AstNode coveringNode = +- new NodeLocator(selectionRange.offset, selectionRange.end) +- .searchWithin(unit); +- // compute covering expressions +- for (AstNode node = coveringNode; node != null; node = node.parent) { +- AstNode parent = node.parent; +- // skip some nodes +- if (node is ArgumentList || +- node is AssignmentExpression || +- node is NamedExpression || +- node is TypeArgumentList) { +- continue; +- } +- if (node is ConstructorName || node is Label || node is TypeName) { +- rootExpression = null; +- coveringExpressionOffsets.clear(); +- coveringExpressionLengths.clear(); +- continue; +- } +- // cannot extract the name part of a property access +- if (parent is PrefixedIdentifier && parent.identifier == node || +- parent is PropertyAccess && parent.propertyName == node) { +- continue; +- } +- // stop if not an Expression +- if (node is! Expression) { +- break; +- } +- // stop at void method invocations +- if (node is MethodInvocation) { +- MethodInvocation invocation = node; +- Element element = invocation.methodName.bestElement; +- if (element is ExecutableElement && +- element.returnType != null && +- element.returnType.isVoid) { +- if (rootExpression == null) { +- return new RefactoringStatus.fatal( +- 'Cannot extract the void expression.', +- newLocation_fromNode(node)); +- } +- break; +- } +- } +- // fatal selection problems +- if (coveringExpressionOffsets.isEmpty) { +- if (node is SimpleIdentifier) { +- if (node.inDeclarationContext()) { +- return new RefactoringStatus.fatal( +- 'Cannot extract the name part of a declaration.', +- newLocation_fromNode(node)); +- } +- Element element = node.bestElement; +- if (element is FunctionElement || element is MethodElement) { +- continue; +- } +- } +- if (parent is AssignmentExpression && parent.leftHandSide == node) { +- return new RefactoringStatus.fatal( +- 'Cannot extract the left-hand side of an assignment.', +- newLocation_fromNode(node)); +- } +- } +- // set selected expression +- if (coveringExpressionOffsets.isEmpty) { +- rootExpression = node; +- } +- // add the expression range +- coveringExpressionOffsets.add(node.offset); +- coveringExpressionLengths.add(node.length); +- } +- // We need an enclosing function. +- // If it has a block body, we can add a new variable declaration statement +- // into this block. If it has an expression body, we can convert it into +- // the block body first. +- if (coveringNode == null || +- coveringNode.getAncestor((node) => node is FunctionBody) == null) { +- return new RefactoringStatus.fatal( +- 'An expression inside a function must be selected ' +- 'to activate this refactoring.'); +- } +- // part of string literal +- if (coveringNode is StringLiteral) { +- if (selectionRange.length != 0 && +- selectionRange.offset > coveringNode.offset && +- selectionRange.end < coveringNode.end) { +- stringLiteralPart = selectionStr; +- return new RefactoringStatus(); +- } +- } +- // single node selected +- if (rootExpression != null) { +- singleExpression = rootExpression; +- selectionRange = range.node(singleExpression); +- wholeStatementExpression = singleExpression.parent is ExpressionStatement; +- return new RefactoringStatus(); +- } +- // invalid selection +- return new RefactoringStatus.fatal( +- 'Expression must be selected to activate this refactoring.'); +- } +- +- /** +- * Return an unique identifier for the given [Element], or `null` if [element] +- * is `null`. +- */ +- int _encodeElement(Element element) { +- if (element == null) { +- return null; +- } +- int id = elementIds[element]; +- if (id == null) { +- id = elementIds.length; +- elementIds[element] = id; +- } +- return id; +- } +- +- /** +- * Returns an [Element]-sensitive encoding of [tokens]. +- * Each [Token] with a [LocalVariableElement] has a suffix of the element id. +- * +- * So, we can distinguish different local variables with the same name, if +- * there are multiple variables with the same name are declared in the +- * function we are searching occurrences in. +- */ +- String _encodeExpressionTokens(Expression expr, List tokens) { +- // no expression, i.e. a part of a string +- if (expr == null) { +- return tokens.join(_TOKEN_SEPARATOR); +- } +- // prepare Token -> LocalElement map +- Map map = new HashMap( +- equals: (Token a, Token b) => a.lexeme == b.lexeme, +- hashCode: (Token t) => t.lexeme.hashCode); +- expr.accept(new _TokenLocalElementVisitor(map)); +- // map and join tokens +- return tokens.map((Token token) { +- String tokenString = token.lexeme; +- // append token's Element id +- Element element = map[token]; +- if (element != null) { +- int elementId = _encodeElement(element); +- if (elementId != null) { +- tokenString += '-$elementId'; +- } +- } +- // done +- return tokenString; +- }).join(_TOKEN_SEPARATOR); +- } +- +- /** +- * Return the [AstNode] to defined the variable before. +- * It should be accessible by all the given [occurrences]. +- */ +- AstNode _findDeclarationTarget(List occurrences) { +- List nodes = _findNodes(occurrences); +- AstNode commonParent = getNearestCommonAncestor(nodes); +- // Block +- if (commonParent is Block) { +- List firstParents = getParents(nodes[0]); +- int commonIndex = firstParents.indexOf(commonParent); +- return firstParents[commonIndex + 1]; +- } +- // ExpressionFunctionBody +- AstNode expressionBody = _getEnclosingExpressionBody(commonParent); +- if (expressionBody != null) { +- return expressionBody; +- } +- // single Statement +- AstNode target = commonParent.getAncestor((node) => node is Statement); +- while (target.parent is! Block) { +- target = target.parent; +- } +- return target; +- } +- +- /** +- * Returns [AstNode]s at the offsets of the given [SourceRange]s. +- */ +- List _findNodes(List ranges) { +- List nodes = []; +- for (SourceRange range in ranges) { +- AstNode node = new NodeLocator(range.offset).searchWithin(unit); +- nodes.add(node); +- } +- return nodes; +- } +- +- /** +- * Returns the [ExpressionFunctionBody] that encloses [node], or `null` +- * if [node] is not enclosed with an [ExpressionFunctionBody]. +- */ +- ExpressionFunctionBody _getEnclosingExpressionBody(AstNode node) { +- while (node != null) { +- if (node is Statement) { +- return null; +- } +- if (node is ExpressionFunctionBody) { +- return node; +- } +- node = node.parent; +- } +- return null; +- } +- +- /** +- * Checks if it is OK to extract the node with the given [SourceRange]. +- */ +- bool _isExtractable(SourceRange range) { +- _ExtractExpressionAnalyzer analyzer = new _ExtractExpressionAnalyzer(range); +- utils.unit.accept(analyzer); +- return analyzer.status.isOK; +- } +- +- bool _isPartOfConstantExpression(AstNode node) { +- if (node is TypedLiteral) { +- return node.constKeyword != null; +- } +- if (node is InstanceCreationExpression) { +- InstanceCreationExpression creation = node; +- return creation.isConst; +- } +- if (node is ArgumentList || +- node is ConditionalExpression || +- node is BinaryExpression || +- node is ParenthesizedExpression || +- node is PrefixExpression || +- node is Literal || +- node is MapLiteralEntry) { +- return _isPartOfConstantExpression(node.parent); +- } +- return false; +- } +- +- void _prepareNames() { +- names.clear(); +- if (stringLiteralPart != null) { +- names.addAll(getVariableNameSuggestionsForText( +- stringLiteralPart, excludedVariableNames)); +- } else if (singleExpression != null) { +- names.addAll(getVariableNameSuggestionsForExpression( +- singleExpression.staticType, +- singleExpression, +- excludedVariableNames)); +- } +- } +- +- /** +- * Prepares all occurrences of the source which matches given selection, +- * sorted by offsets. +- */ +- void _prepareOccurrences() { +- occurrences.clear(); +- elementIds.clear(); +- // prepare selection +- String selectionSource; +- { +- String rawSelectionSource = utils.getRangeText(selectionRange); +- List selectionTokens = TokenUtils.getTokens(rawSelectionSource); +- selectionSource = +- _encodeExpressionTokens(rootExpression, selectionTokens); +- } +- // prepare enclosing function +- AstNode enclosingFunction; +- { +- AstNode selectionNode = +- new NodeLocator(selectionOffset).searchWithin(unit); +- enclosingFunction = getEnclosingExecutableNode(selectionNode); +- } +- // visit function +- enclosingFunction +- .accept(new _OccurrencesVisitor(this, occurrences, selectionSource)); +- } +- +- void _prepareOffsetsLengths() { +- offsets.clear(); +- lengths.clear(); +- for (SourceRange occurrence in occurrences) { +- offsets.add(occurrence.offset); +- lengths.add(occurrence.length); +- } +- } +-} +- +-/** +- * [SelectionAnalyzer] for [ExtractLocalRefactoringImpl]. +- */ +-class _ExtractExpressionAnalyzer extends SelectionAnalyzer { +- final RefactoringStatus status = new RefactoringStatus(); +- +- _ExtractExpressionAnalyzer(SourceRange selection) : super(selection); +- +- /** +- * Records fatal error with given message. +- */ +- void invalidSelection(String message) { +- _invalidSelection(message, null); +- } +- +- @override +- Object visitAssignmentExpression(AssignmentExpression node) { +- super.visitAssignmentExpression(node); +- Expression lhs = node.leftHandSide; +- if (_isFirstSelectedNode(lhs)) { +- _invalidSelection('Cannot extract the left-hand side of an assignment.', +- newLocation_fromNode(lhs)); +- } +- return null; +- } +- +- @override +- Object visitSimpleIdentifier(SimpleIdentifier node) { +- super.visitSimpleIdentifier(node); +- if (_isFirstSelectedNode(node)) { +- // name of declaration +- if (node.inDeclarationContext()) { +- invalidSelection('Cannot extract the name part of a declaration.'); +- } +- // method name +- Element element = node.bestElement; +- if (element is FunctionElement || element is MethodElement) { +- invalidSelection('Cannot extract a single method name.'); +- } +- // name in property access +- AstNode parent = node.parent; +- if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { +- invalidSelection('Cannot extract name part of a property access.'); +- } +- if (parent is PropertyAccess && identical(parent.propertyName, node)) { +- invalidSelection('Cannot extract name part of a property access.'); +- } +- } +- return null; +- } +- +- /** +- * Records fatal error with given [message] and [location]. +- */ +- void _invalidSelection(String message, Location location) { +- status.addFatalError(message, location); +- reset(); +- } +- +- bool _isFirstSelectedNode(AstNode node) => node == firstSelectedNode; +-} +- +-class _HasStatementVisitor extends GeneralizingAstVisitor { +- bool result = false; +- +- _HasStatementVisitor(); +- +- @override +- visitStatement(Statement node) { +- result = true; +- } +-} +- +-class _OccurrencesVisitor extends GeneralizingAstVisitor { +- final ExtractLocalRefactoringImpl ref; +- final List occurrences; +- final String selectionSource; +- +- _OccurrencesVisitor(this.ref, this.occurrences, this.selectionSource); +- +- @override +- Object visitBinaryExpression(BinaryExpression node) { +- if (!_hasStatements(node)) { +- _tryToFindOccurrenceFragments(node); +- return null; +- } +- return super.visitBinaryExpression(node); +- } +- +- @override +- Object visitExpression(Expression node) { +- if (ref._isExtractable(range.node(node))) { +- _tryToFindOccurrence(node); +- } +- return super.visitExpression(node); +- } +- +- @override +- Object visitStringLiteral(StringLiteral node) { +- if (ref.stringLiteralPart != null) { +- int length = ref.stringLiteralPart.length; +- String value = ref.utils.getNodeText(node); +- int lastIndex = 0; +- while (true) { +- int index = value.indexOf(ref.stringLiteralPart, lastIndex); +- if (index == -1) { +- break; +- } +- lastIndex = index + length; +- int start = node.offset + index; +- SourceRange range = new SourceRange(start, length); +- occurrences.add(range); +- } +- return null; +- } +- return visitExpression(node); +- } +- +- void _addOccurrence(SourceRange range) { +- if (range.intersects(ref.selectionRange)) { +- occurrences.add(ref.selectionRange); +- } else { +- occurrences.add(range); +- } +- } +- +- bool _hasStatements(AstNode root) { +- _HasStatementVisitor visitor = new _HasStatementVisitor(); +- root.accept(visitor); +- return visitor.result; +- } +- +- void _tryToFindOccurrence(Expression node) { +- String nodeSource = ref.utils.getNodeText(node); +- List nodeTokens = TokenUtils.getTokens(nodeSource); +- nodeSource = ref._encodeExpressionTokens(node, nodeTokens); +- if (nodeSource == selectionSource) { +- _addOccurrence(range.node(node)); +- } +- } +- +- void _tryToFindOccurrenceFragments(Expression node) { +- int nodeOffset = node.offset; +- String nodeSource = ref.utils.getNodeText(node); +- List nodeTokens = TokenUtils.getTokens(nodeSource); +- nodeSource = ref._encodeExpressionTokens(node, nodeTokens); +- // find "selection" in "node" tokens +- int lastIndex = 0; +- while (true) { +- // find next occurrence +- int index = nodeSource.indexOf(selectionSource, lastIndex); +- if (index == -1) { +- break; +- } +- lastIndex = index + selectionSource.length; +- // find start/end tokens +- int startTokenIndex = +- countMatches(nodeSource.substring(0, index), _TOKEN_SEPARATOR); +- int endTokenIndex = +- countMatches(nodeSource.substring(0, lastIndex), _TOKEN_SEPARATOR); +- Token startToken = nodeTokens[startTokenIndex]; +- Token endToken = nodeTokens[endTokenIndex]; +- // add occurrence range +- int start = nodeOffset + startToken.offset; +- int end = nodeOffset + endToken.end; +- _addOccurrence(range.startOffsetEndOffset(start, end)); +- } +- } +-} +- +-class _TokenLocalElementVisitor extends RecursiveAstVisitor { +- final Map map; +- +- _TokenLocalElementVisitor(this.map); +- +- visitSimpleIdentifier(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is LocalVariableElement) { +- map[node.token] = element; +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart +deleted file mode 100644 +index 65905be2076..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart ++++ /dev/null +@@ -1,1350 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/name_suggestion.dart'; +-import 'package:analysis_server/src/services/correction/selection_analyzer.dart'; +-import 'package:analysis_server/src/services/correction/statement_analyzer.dart'; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_class_member.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/analysis/session.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/resolver.dart' show ExitDetector; +-import 'package:analyzer/src/generated/resolver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/type_system.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-const String _TOKEN_SEPARATOR = '\uFFFF'; +- +-Element _getLocalElement(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is LocalVariableElement || +- element is ParameterElement || +- element is FunctionElement && element.visibleRange != null) { +- return element; +- } +- return null; +-} +- +-/** +- * Returns the "normalized" version of the given source, which is reconstructed +- * from tokens, so ignores all the comments and spaces. +- */ +-String _getNormalizedSource(String src) { +- List selectionTokens = TokenUtils.getTokens(src); +- return selectionTokens.join(_TOKEN_SEPARATOR); +-} +- +-/** +- * Returns the [Map] which maps [map] values to their keys. +- */ +-Map _inverseMap(Map map) { +- Map result = {}; +- map.forEach((String key, String value) { +- result[value] = key; +- }); +- return result; +-} +- +-/** +- * [ExtractMethodRefactoring] implementation. +- */ +-class ExtractMethodRefactoringImpl extends RefactoringImpl +- implements ExtractMethodRefactoring { +- static const ERROR_EXITS = +- 'Selected statements contain a return statement, but not all possible ' +- 'execution flows exit. Semantics may not be preserved.'; +- +- final SearchEngine searchEngine; +- final AstProvider astProvider; +- final CompilationUnit unit; +- final int selectionOffset; +- final int selectionLength; +- AnalysisSession session; +- CompilationUnitElement unitElement; +- LibraryElement libraryElement; +- SourceRange selectionRange; +- CorrectionUtils utils; +- Set librariesToImport = new Set(); +- +- String returnType = ''; +- String variableType; +- String name; +- bool extractAll = true; +- bool canCreateGetter = false; +- bool createGetter = false; +- final List names = []; +- final List offsets = []; +- final List lengths = []; +- +- /** +- * The map of local names to their visibility ranges. +- */ +- Map> _localNames = >{}; +- +- /** +- * The set of names that are referenced without any qualifier. +- */ +- Set _unqualifiedNames = new Set(); +- +- Set _excludedNames = new Set(); +- List _parameters = []; +- Map _parametersMap = +- {}; +- Map> _parameterReferencesMap = +- >{}; +- bool _hasAwait = false; +- DartType _returnType; +- String _returnVariableName; +- AstNode _parentMember; +- Expression _selectionExpression; +- FunctionExpression _selectionFunctionExpression; +- List _selectionStatements; +- List<_Occurrence> _occurrences = []; +- bool _staticContext = false; +- +- ExtractMethodRefactoringImpl(this.searchEngine, this.astProvider, this.unit, +- this.selectionOffset, this.selectionLength) { +- unitElement = unit.element; +- libraryElement = unitElement.library; +- session = astProvider.driver.currentSession; +- selectionRange = new SourceRange(selectionOffset, selectionLength); +- utils = new CorrectionUtils(unit); +- } +- +- @override +- List get parameters => _parameters; +- +- @override +- void set parameters(List parameters) { +- _parameters = parameters.toList(); +- } +- +- @override +- String get refactoringName { +- AstNode node = new NodeLocator(selectionOffset).searchWithin(unit); +- if (node != null && +- node.getAncestor((node) => node is ClassDeclaration) != null) { +- return 'Extract Method'; +- } +- return 'Extract Function'; +- } +- +- String get signature { +- StringBuffer sb = new StringBuffer(); +- if (createGetter) { +- sb.write('get '); +- sb.write(name); +- } else { +- sb.write(name); +- sb.write('('); +- // add all parameters +- bool firstParameter = true; +- for (RefactoringMethodParameter parameter in _parameters) { +- // may be comma +- if (firstParameter) { +- firstParameter = false; +- } else { +- sb.write(', '); +- } +- // type +- { +- String typeSource = parameter.type; +- if ('dynamic' != typeSource && '' != typeSource) { +- sb.write(typeSource); +- sb.write(' '); +- } +- } +- // name +- sb.write(parameter.name); +- // optional function-typed parameter parameters +- if (parameter.parameters != null) { +- sb.write(parameter.parameters); +- } +- } +- sb.write(')'); +- } +- // done +- return sb.toString(); +- } +- +- @override +- Future checkFinalConditions() async { +- RefactoringStatus result = new RefactoringStatus(); +- result.addStatus(validateMethodName(name)); +- result.addStatus(_checkParameterNames()); +- RefactoringStatus status = await _checkPossibleConflicts(); +- result.addStatus(status); +- return result; +- } +- +- @override +- Future checkInitialConditions() async { +- RefactoringStatus result = new RefactoringStatus(); +- // selection +- result.addStatus(_checkSelection()); +- if (result.hasFatalError) { +- return result; +- } +- // prepare parts +- RefactoringStatus status = await _initializeParameters(); +- result.addStatus(status); +- _initializeHasAwait(); +- await _initializeReturnType(); +- // occurrences +- _initializeOccurrences(); +- _prepareOffsetsLengths(); +- // getter +- canCreateGetter = _computeCanCreateGetter(); +- createGetter = +- canCreateGetter && _isExpressionForGetter(_selectionExpression); +- // names +- _prepareExcludedNames(); +- _prepareNames(); +- // closure cannot have parameters +- if (_selectionFunctionExpression != null && !_parameters.isEmpty) { +- String message = format( +- 'Cannot extract closure as method, it references {0} external variable(s).', +- _parameters.length); +- return new RefactoringStatus.fatal(message); +- } +- return result; +- } +- +- @override +- RefactoringStatus checkName() { +- return validateMethodName(name); +- } +- +- @override +- Future createChange() async { +- SourceChange change = new SourceChange(refactoringName); +- // replace occurrences with method invocation +- for (_Occurrence occurrence in _occurrences) { +- SourceRange range = occurrence.range; +- // may be replacement of duplicates disabled +- if (!extractAll && !occurrence.isSelection) { +- continue; +- } +- // prepare invocation source +- String invocationSource; +- if (_selectionFunctionExpression != null) { +- invocationSource = name; +- } else { +- StringBuffer sb = new StringBuffer(); +- // may be returns value +- if (_selectionStatements != null && variableType != null) { +- // single variable assignment / return statement +- if (_returnVariableName != null) { +- String occurrenceName = +- occurrence._parameterOldToOccurrenceName[_returnVariableName]; +- // may be declare variable +- if (!_parametersMap.containsKey(_returnVariableName)) { +- if (variableType.isEmpty) { +- sb.write('var '); +- } else { +- sb.write(variableType); +- sb.write(' '); +- } +- } +- // assign the return value +- sb.write(occurrenceName); +- sb.write(' = '); +- } else { +- sb.write('return '); +- } +- } +- // await +- if (_hasAwait) { +- sb.write('await '); +- } +- // invocation itself +- sb.write(name); +- if (!createGetter) { +- sb.write('('); +- bool firstParameter = true; +- for (RefactoringMethodParameter parameter in _parameters) { +- // may be comma +- if (firstParameter) { +- firstParameter = false; +- } else { +- sb.write(', '); +- } +- // argument name +- { +- String argumentName = +- occurrence._parameterOldToOccurrenceName[parameter.id]; +- sb.write(argumentName); +- } +- } +- sb.write(')'); +- } +- invocationSource = sb.toString(); +- // statements as extracted with their ";", so add new after invocation +- if (_selectionStatements != null) { +- invocationSource += ';'; +- } +- } +- // add replace edit +- SourceEdit edit = newSourceEdit_range(range, invocationSource); +- doSourceChange_addElementEdit(change, unitElement, edit); +- } +- // add method declaration +- { +- // prepare environment +- String prefix = utils.getNodePrefix(_parentMember); +- String eol = utils.endOfLine; +- // prepare annotations +- String annotations = ''; +- { +- // may be "static" +- if (_staticContext) { +- annotations = 'static '; +- } +- } +- // prepare declaration source +- String declarationSource = null; +- { +- String returnExpressionSource = _getMethodBodySource(); +- // closure +- if (_selectionFunctionExpression != null) { +- String returnTypeCode = _getExpectedClosureReturnTypeCode(); +- declarationSource = '$returnTypeCode$name$returnExpressionSource'; +- if (_selectionFunctionExpression.body is ExpressionFunctionBody) { +- declarationSource += ';'; +- } +- } +- // optional 'async' body modifier +- String asyncKeyword = _hasAwait ? ' async' : ''; +- // expression +- if (_selectionExpression != null) { +- bool isMultiLine = returnExpressionSource.contains(eol); +- +- // We generate the method body using the shorthand syntax if it fits +- // into a single line and use the regular method syntax otherwise. +- if (!isMultiLine) { +- // add return type +- if (returnType.isNotEmpty) { +- annotations += '$returnType '; +- } +- // just return expression +- declarationSource = '$annotations$signature$asyncKeyword => '; +- declarationSource += '$returnExpressionSource;'; +- } else { +- // Left indent once; returnExpressionSource was indented for method +- // shorthands. +- returnExpressionSource = utils +- .indentSourceLeftRight('${returnExpressionSource.trim()};') +- .trim(); +- +- // add return type +- if (returnType.isNotEmpty) { +- annotations += '$returnType '; +- } +- declarationSource = '$annotations$signature$asyncKeyword {$eol'; +- declarationSource += '$prefix '; +- if (returnType.isNotEmpty) { +- declarationSource += 'return '; +- } +- declarationSource += '$returnExpressionSource$eol$prefix}'; +- } +- } +- // statements +- if (_selectionStatements != null) { +- if (returnType.isNotEmpty) { +- annotations += returnType + ' '; +- } +- declarationSource = '$annotations$signature$asyncKeyword {$eol'; +- declarationSource += returnExpressionSource; +- if (_returnVariableName != null) { +- declarationSource += '$prefix return $_returnVariableName;$eol'; +- } +- declarationSource += '$prefix}'; +- } +- } +- // insert declaration +- if (declarationSource != null) { +- int offset = _parentMember.end; +- SourceEdit edit = +- new SourceEdit(offset, 0, '$eol$eol$prefix$declarationSource'); +- doSourceChange_addElementEdit(change, unitElement, edit); +- } +- } +- // done +- addLibraryImports(change, libraryElement, librariesToImport); +- return change; +- } +- +- @override +- bool requiresPreview() => false; +- +- /** +- * Adds a new reference to the parameter with the given name. +- */ +- void _addParameterReference(String name, SourceRange range) { +- List references = _parameterReferencesMap[name]; +- if (references == null) { +- references = []; +- _parameterReferencesMap[name] = references; +- } +- references.add(range); +- } +- +- RefactoringStatus _checkParameterNames() { +- RefactoringStatus result = new RefactoringStatus(); +- for (RefactoringMethodParameter parameter in _parameters) { +- result.addStatus(validateParameterName(parameter.name)); +- for (RefactoringMethodParameter other in _parameters) { +- if (!identical(parameter, other) && other.name == parameter.name) { +- result.addError( +- format("Parameter '{0}' already exists", parameter.name)); +- return result; +- } +- } +- if (_isParameterNameConflictWithBody(parameter)) { +- result.addError(format( +- "'{0}' is already used as a name in the selected code", +- parameter.name)); +- return result; +- } +- } +- return result; +- } +- +- /** +- * Checks if created method will shadow or will be shadowed by other elements. +- */ +- Future _checkPossibleConflicts() async { +- RefactoringStatus result = new RefactoringStatus(); +- AstNode parent = _parentMember.parent; +- // top-level function +- if (parent is CompilationUnit) { +- LibraryElement libraryElement = +- resolutionMap.elementDeclaredByCompilationUnit(parent).library; +- return validateCreateFunction(searchEngine, libraryElement, name); +- } +- // method of class +- if (parent is ClassDeclaration) { +- ClassElement classElement = parent.element; +- return validateCreateMethod( +- searchEngine, astProvider, classElement, name); +- } +- // OK +- return new Future.value(result); +- } +- +- /** +- * Checks if [selectionRange] selects [Expression] which can be extracted, and +- * location of this [DartExpression] in AST allows extracting. +- */ +- RefactoringStatus _checkSelection() { +- // Check for implicitly selected closure. +- { +- FunctionExpression function = _findFunctionExpression(); +- if (function != null) { +- _selectionFunctionExpression = function; +- selectionRange = range.node(function); +- _parentMember = getEnclosingClassOrUnitMember(function); +- return new RefactoringStatus(); +- } +- } +- +- _ExtractMethodAnalyzer selectionAnalyzer = +- new _ExtractMethodAnalyzer(unit, selectionRange); +- unit.accept(selectionAnalyzer); +- // May be a fatal error. +- { +- RefactoringStatus status = selectionAnalyzer.status; +- if (status.hasFatalError) { +- return status; +- } +- } +- List selectedNodes = selectionAnalyzer.selectedNodes; +- +- // Check selected nodes. +- if (!selectedNodes.isEmpty) { +- AstNode selectedNode = selectedNodes.first; +- _parentMember = getEnclosingClassOrUnitMember(selectedNode); +- // single expression selected +- if (selectedNodes.length == 1) { +- if (!utils.selectionIncludesNonWhitespaceOutsideNode( +- selectionRange, selectedNode)) { +- if (selectedNode is Expression) { +- _selectionExpression = selectedNode; +- // additional check for closure +- if (_selectionExpression is FunctionExpression) { +- _selectionFunctionExpression = +- _selectionExpression as FunctionExpression; +- _selectionExpression = null; +- } +- // OK +- return new RefactoringStatus(); +- } +- } +- } +- // statements selected +- { +- List selectedStatements = []; +- for (AstNode selectedNode in selectedNodes) { +- if (selectedNode is Statement) { +- selectedStatements.add(selectedNode); +- } +- } +- if (selectedStatements.length == selectedNodes.length) { +- _selectionStatements = selectedStatements; +- return new RefactoringStatus(); +- } +- } +- } +- // invalid selection +- return new RefactoringStatus.fatal( +- 'Can only extract a single expression or a set of statements.'); +- } +- +- /** +- * Initializes [canCreateGetter] flag. +- */ +- bool _computeCanCreateGetter() { +- // is a function expression +- if (_selectionFunctionExpression != null) { +- return false; +- } +- // has parameters +- if (!parameters.isEmpty) { +- return false; +- } +- // is assignment +- if (_selectionExpression != null) { +- if (_selectionExpression is AssignmentExpression) { +- return false; +- } +- } +- // doesn't return a value +- if (_selectionStatements != null) { +- return returnType != 'void'; +- } +- // OK +- return true; +- } +- +- /** +- * If the [selectionRange] is associated with a [FunctionExpression], return +- * this [FunctionExpression]. +- */ +- FunctionExpression _findFunctionExpression() { +- if (selectionRange.length != 0) { +- return null; +- } +- int offset = selectionRange.offset; +- AstNode node = new NodeLocator2(offset, offset).searchWithin(unit); +- +- // Check for the parameter list of a FunctionExpression. +- { +- FunctionExpression function = +- node?.getAncestor((n) => n is FunctionExpression); +- if (function != null && +- function.parameters != null && +- range.node(function.parameters).contains(offset)) { +- return function; +- } +- } +- +- // Check for the name of the named argument with the closure expression. +- if (node is SimpleIdentifier && +- node.parent is Label && +- node.parent.parent is NamedExpression) { +- NamedExpression namedExpression = node.parent.parent; +- Expression expression = namedExpression.expression; +- if (expression is FunctionExpression) { +- return expression; +- } +- } +- +- return null; +- } +- +- /** +- * If the selected closure (i.e. [_selectionFunctionExpression]) is an +- * argument for a function typed parameter (as it should be), and the +- * function type has the return type specified, return this return type's +- * code. Otherwise return the empty string. +- */ +- String _getExpectedClosureReturnTypeCode() { +- Expression argument = _selectionFunctionExpression; +- if (argument.parent is NamedExpression) { +- argument = argument.parent as NamedExpression; +- } +- ParameterElement parameter = argument.bestParameterElement; +- if (parameter != null) { +- DartType parameterType = parameter.type; +- if (parameterType is FunctionType) { +- String typeCode = _getTypeCode(parameterType.returnType); +- if (typeCode != 'dynamic') { +- return typeCode + ' '; +- } +- } +- } +- return ''; +- } +- +- /** +- * Returns the selected [Expression] source, with applying new parameter +- * names. +- */ +- String _getMethodBodySource() { +- String source = utils.getRangeText(selectionRange); +- // prepare operations to replace variables with parameters +- List replaceEdits = []; +- for (RefactoringMethodParameter parameter in _parameters) { +- List ranges = _parameterReferencesMap[parameter.id]; +- if (ranges != null) { +- for (SourceRange range in ranges) { +- replaceEdits.add(new SourceEdit(range.offset - selectionRange.offset, +- range.length, parameter.name)); +- } +- } +- } +- replaceEdits.sort((a, b) => b.offset - a.offset); +- // apply replacements +- source = SourceEdit.applySequence(source, replaceEdits); +- // change indentation +- if (_selectionFunctionExpression != null) { +- AstNode baseNode = +- _selectionFunctionExpression.getAncestor((node) => node is Statement); +- if (baseNode != null) { +- String baseIndent = utils.getNodePrefix(baseNode); +- String targetIndent = utils.getNodePrefix(_parentMember); +- source = utils.replaceSourceIndent(source, baseIndent, targetIndent); +- source = source.trim(); +- } +- } +- if (_selectionStatements != null) { +- String selectionIndent = utils.getNodePrefix(_selectionStatements[0]); +- String targetIndent = utils.getNodePrefix(_parentMember) + ' '; +- source = utils.replaceSourceIndent(source, selectionIndent, targetIndent); +- } +- // done +- return source; +- } +- +- _SourcePattern _getSourcePattern(SourceRange range) { +- String originalSource = utils.getText(range.offset, range.length); +- _SourcePattern pattern = new _SourcePattern(); +- List replaceEdits = []; +- unit.accept(new _GetSourcePatternVisitor(range, pattern, replaceEdits)); +- replaceEdits = replaceEdits.reversed.toList(); +- String source = SourceEdit.applySequence(originalSource, replaceEdits); +- pattern.normalizedSource = _getNormalizedSource(source); +- return pattern; +- } +- +- String _getTypeCode(DartType type) { +- return utils.getTypeSource(type, librariesToImport); +- } +- +- void _initializeHasAwait() { +- _HasAwaitVisitor visitor = new _HasAwaitVisitor(); +- if (_selectionExpression != null) { +- _selectionExpression.accept(visitor); +- } else if (_selectionStatements != null) { +- _selectionStatements.forEach((statement) { +- statement.accept(visitor); +- }); +- } +- _hasAwait = visitor.result; +- } +- +- /** +- * Fills [_occurrences] field. +- */ +- void _initializeOccurrences() { +- _occurrences.clear(); +- // prepare selection +- _SourcePattern selectionPattern = _getSourcePattern(selectionRange); +- Map patternToSelectionName = +- _inverseMap(selectionPattern.originalToPatternNames); +- // prepare an enclosing parent - class or unit +- AstNode enclosingMemberParent = _parentMember.parent; +- // visit nodes which will able to access extracted method +- enclosingMemberParent.accept(new _InitializeOccurrencesVisitor( +- this, selectionPattern, patternToSelectionName)); +- } +- +- /** +- * Prepares information about used variables, which should be turned into +- * parameters. +- */ +- Future _initializeParameters() async { +- _parameters.clear(); +- _parametersMap.clear(); +- _parameterReferencesMap.clear(); +- RefactoringStatus result = new RefactoringStatus(); +- List assignedUsedVariables = []; +- unit.accept(new _InitializeParametersVisitor(this, assignedUsedVariables)); +- // single expression +- if (_selectionExpression != null) { +- _returnType = _selectionExpression.bestType; +- } +- // verify that none or all execution flows end with a "return" +- if (_selectionStatements != null) { +- bool hasReturn = _selectionStatements.any(_mayEndWithReturnStatement); +- if (hasReturn && !ExitDetector.exits(_selectionStatements.last)) { +- result.addError(ERROR_EXITS); +- } +- } +- // maybe ends with "return" statement +- if (_selectionStatements != null) { +- TypeSystem typeSystem = await session.typeSystem; +- _ReturnTypeComputer returnTypeComputer = +- new _ReturnTypeComputer(typeSystem); +- _selectionStatements.forEach((statement) { +- statement.accept(returnTypeComputer); +- }); +- _returnType = returnTypeComputer.returnType; +- } +- // maybe single variable to return +- if (assignedUsedVariables.length == 1) { +- // we cannot both return variable and have explicit return statement +- if (_returnType != null) { +- result.addFatalError( +- 'Ambiguous return value: Selected block contains assignment(s) to ' +- 'local variables and return statement.'); +- return result; +- } +- // prepare to return an assigned variable +- VariableElement returnVariable = assignedUsedVariables[0]; +- _returnType = returnVariable.type; +- _returnVariableName = returnVariable.displayName; +- } +- // fatal, if multiple variables assigned and used after selection +- if (assignedUsedVariables.length > 1) { +- StringBuffer sb = new StringBuffer(); +- for (VariableElement variable in assignedUsedVariables) { +- sb.write(variable.displayName); +- sb.write('\n'); +- } +- result.addFatalError(format( +- 'Ambiguous return value: Selected block contains more than one ' +- 'assignment to local variables. Affected variables are:\n\n{0}', +- sb.toString().trim())); +- } +- // done +- return result; +- } +- +- Future _initializeReturnType() async { +- TypeProvider typeProvider = await session.typeProvider; +- InterfaceType futureType = typeProvider.futureType; +- if (_selectionFunctionExpression != null) { +- variableType = ''; +- returnType = ''; +- } else if (_returnType == null) { +- variableType = null; +- if (_hasAwait) { +- returnType = _getTypeCode(futureType); +- } else { +- returnType = 'void'; +- } +- } else if (_returnType.isDynamic) { +- variableType = ''; +- if (_hasAwait) { +- returnType = _getTypeCode(futureType); +- } else { +- returnType = ''; +- } +- } else { +- variableType = _getTypeCode(_returnType); +- if (_hasAwait) { +- if (_returnType.element != futureType.element) { +- returnType = _getTypeCode(futureType.instantiate([_returnType])); +- } +- } else { +- returnType = variableType; +- } +- } +- } +- +- /** +- * Checks if the given [element] is declared in [selectionRange]. +- */ +- bool _isDeclaredInSelection(Element element) { +- return selectionRange.contains(element.nameOffset); +- } +- +- /** +- * Checks if it is OK to extract the node with the given [SourceRange]. +- */ +- bool _isExtractable(SourceRange range) { +- _ExtractMethodAnalyzer analyzer = new _ExtractMethodAnalyzer(unit, range); +- utils.unit.accept(analyzer); +- return analyzer.status.isOK; +- } +- +- bool _isParameterNameConflictWithBody(RefactoringMethodParameter parameter) { +- String id = parameter.id; +- String name = parameter.name; +- List parameterRanges = _parameterReferencesMap[id]; +- List otherRanges = _localNames[name]; +- for (SourceRange parameterRange in parameterRanges) { +- if (otherRanges != null) { +- for (SourceRange otherRange in otherRanges) { +- if (parameterRange.intersects(otherRange)) { +- return true; +- } +- } +- } +- } +- if (_unqualifiedNames.contains(name)) { +- return true; +- } +- return false; +- } +- +- /** +- * Checks if [element] is referenced after [selectionRange]. +- */ +- bool _isUsedAfterSelection(Element element) { +- var visitor = new _IsUsedAfterSelectionVisitor(this, element); +- _parentMember.accept(visitor); +- return visitor.result; +- } +- +- /** +- * Prepare names that are used in the enclosing function, so should not be +- * proposed as names of the extracted method. +- */ +- void _prepareExcludedNames() { +- _excludedNames.clear(); +- List localElements = getDefinedLocalElements(_parentMember); +- _excludedNames.addAll(localElements.map((e) => e.name)); +- } +- +- void _prepareNames() { +- names.clear(); +- if (_selectionExpression != null) { +- names.addAll(getVariableNameSuggestionsForExpression( +- _selectionExpression.staticType, _selectionExpression, _excludedNames, +- isMethod: true)); +- } +- } +- +- void _prepareOffsetsLengths() { +- offsets.clear(); +- lengths.clear(); +- for (_Occurrence occurrence in _occurrences) { +- offsets.add(occurrence.range.offset); +- lengths.add(occurrence.range.length); +- } +- } +- +- /** +- * Checks if the given [expression] is reasonable to extract as a getter. +- */ +- static bool _isExpressionForGetter(Expression expression) { +- if (expression is BinaryExpression) { +- return _isExpressionForGetter(expression.leftOperand) && +- _isExpressionForGetter(expression.rightOperand); +- } +- if (expression is Literal) { +- return true; +- } +- if (expression is PrefixExpression) { +- return _isExpressionForGetter(expression.operand); +- } +- if (expression is PrefixedIdentifier) { +- return _isExpressionForGetter(expression.prefix); +- } +- if (expression is PropertyAccess) { +- return _isExpressionForGetter(expression.target); +- } +- if (expression is SimpleIdentifier) { +- return true; +- } +- return false; +- } +- +- /** +- * Returns `true` if the given [statement] may end with a [ReturnStatement]. +- */ +- static bool _mayEndWithReturnStatement(Statement statement) { +- _HasReturnStatementVisitor visitor = new _HasReturnStatementVisitor(); +- statement.accept(visitor); +- return visitor.hasReturn; +- } +-} +- +-/** +- * [SelectionAnalyzer] for [ExtractMethodRefactoringImpl]. +- */ +-class _ExtractMethodAnalyzer extends StatementAnalyzer { +- _ExtractMethodAnalyzer(CompilationUnit unit, SourceRange selection) +- : super(unit, selection); +- +- @override +- void handleNextSelectedNode(AstNode node) { +- super.handleNextSelectedNode(node); +- _checkParent(node); +- } +- +- @override +- void handleSelectionEndsIn(AstNode node) { +- super.handleSelectionEndsIn(node); +- invalidSelection( +- 'The selection does not cover a set of statements or an expression. ' +- 'Extend selection to a valid range.'); +- } +- +- @override +- Object visitAssignmentExpression(AssignmentExpression node) { +- super.visitAssignmentExpression(node); +- Expression lhs = node.leftHandSide; +- if (_isFirstSelectedNode(lhs)) { +- invalidSelection('Cannot extract the left-hand side of an assignment.', +- newLocation_fromNode(lhs)); +- } +- return null; +- } +- +- @override +- Object visitConstructorInitializer(ConstructorInitializer node) { +- super.visitConstructorInitializer(node); +- if (_isFirstSelectedNode(node)) { +- invalidSelection( +- 'Cannot extract a constructor initializer. ' +- 'Select expression part of initializer.', +- newLocation_fromNode(node)); +- } +- return null; +- } +- +- @override +- Object visitForStatement(ForStatement node) { +- super.visitForStatement(node); +- if (identical(node.variables, firstSelectedNode)) { +- invalidSelection( +- "Cannot extract initialization part of a 'for' statement."); +- } else if (node.updaters.contains(lastSelectedNode)) { +- invalidSelection("Cannot extract increment part of a 'for' statement."); +- } +- return null; +- } +- +- @override +- Object visitGenericFunctionType(GenericFunctionType node) { +- super.visitGenericFunctionType(node); +- if (_isFirstSelectedNode(node)) { +- invalidSelection('Cannot extract a single type reference.'); +- } +- return null; +- } +- +- @override +- Object visitSimpleIdentifier(SimpleIdentifier node) { +- super.visitSimpleIdentifier(node); +- if (_isFirstSelectedNode(node)) { +- // name of declaration +- if (node.inDeclarationContext()) { +- invalidSelection('Cannot extract the name part of a declaration.'); +- } +- // method name +- Element element = node.bestElement; +- if (element is FunctionElement || element is MethodElement) { +- invalidSelection('Cannot extract a single method name.'); +- } +- // name in property access +- if (node.parent is PrefixedIdentifier && +- (node.parent as PrefixedIdentifier).identifier == node) { +- invalidSelection('Can not extract name part of a property access.'); +- } +- } +- return null; +- } +- +- @override +- Object visitTypeName(TypeName node) { +- super.visitTypeName(node); +- if (_isFirstSelectedNode(node)) { +- invalidSelection('Cannot extract a single type reference.'); +- } +- return null; +- } +- +- @override +- Object visitVariableDeclaration(VariableDeclaration node) { +- super.visitVariableDeclaration(node); +- if (_isFirstSelectedNode(node)) { +- invalidSelection( +- 'Cannot extract a variable declaration fragment. ' +- 'Select whole declaration statement.', +- newLocation_fromNode(node)); +- } +- return null; +- } +- +- void _checkParent(AstNode node) { +- AstNode firstParent = firstSelectedNode.parent; +- do { +- node = node.parent; +- if (identical(node, firstParent)) { +- return; +- } +- } while (node != null); +- invalidSelection( +- 'Not all selected statements are enclosed by the same parent statement.'); +- } +- +- bool _isFirstSelectedNode(AstNode node) => identical(firstSelectedNode, node); +-} +- +-class _GetSourcePatternVisitor extends GeneralizingAstVisitor { +- final SourceRange partRange; +- final _SourcePattern pattern; +- final List replaceEdits; +- +- _GetSourcePatternVisitor(this.partRange, this.pattern, this.replaceEdits); +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- SourceRange nodeRange = range.node(node); +- if (partRange.covers(nodeRange)) { +- Element element = _getLocalElement(node); +- if (element != null) { +- // name of a named expression +- if (isNamedExpressionName(node)) { +- return; +- } +- // continue +- String originalName = element.displayName; +- String patternName = pattern.originalToPatternNames[originalName]; +- if (patternName == null) { +- DartType parameterType = _getElementType(element); +- pattern.parameterTypes.add(parameterType); +- patternName = '__refVar${pattern.originalToPatternNames.length}'; +- pattern.originalToPatternNames[originalName] = patternName; +- } +- replaceEdits.add(new SourceEdit(nodeRange.offset - partRange.offset, +- nodeRange.length, patternName)); +- } +- } +- } +- +- DartType _getElementType(Element element) { +- if (element is VariableElement) { +- return element.type; +- } +- if (element is FunctionElement) { +- return element.type; +- } +- throw new StateError('Unknown element type: ${element?.runtimeType}'); +- } +-} +- +-class _HasAwaitVisitor extends GeneralizingAstVisitor { +- bool result = false; +- +- @override +- visitAwaitExpression(AwaitExpression node) { +- result = true; +- } +- +- @override +- visitForEachStatement(ForEachStatement node) { +- if (node.awaitKeyword != null) { +- result = true; +- } +- super.visitForEachStatement(node); +- } +-} +- +-class _HasReturnStatementVisitor extends RecursiveAstVisitor { +- bool hasReturn = false; +- +- @override +- visitBlockFunctionBody(BlockFunctionBody node) {} +- +- @override +- visitReturnStatement(ReturnStatement node) { +- hasReturn = true; +- } +-} +- +-class _InitializeOccurrencesVisitor extends GeneralizingAstVisitor { +- final ExtractMethodRefactoringImpl ref; +- final _SourcePattern selectionPattern; +- final Map patternToSelectionName; +- +- bool forceStatic = false; +- +- _InitializeOccurrencesVisitor( +- this.ref, this.selectionPattern, this.patternToSelectionName); +- +- @override +- Object visitBlock(Block node) { +- if (ref._selectionStatements != null) { +- _visitStatements(node.statements); +- } +- return super.visitBlock(node); +- } +- +- @override +- Object visitConstructorInitializer(ConstructorInitializer node) { +- forceStatic = true; +- try { +- return super.visitConstructorInitializer(node); +- } finally { +- forceStatic = false; +- } +- } +- +- @override +- Object visitExpression(Expression node) { +- if (ref._selectionFunctionExpression != null || +- ref._selectionExpression != null && +- node.runtimeType == ref._selectionExpression.runtimeType) { +- SourceRange nodeRange = range.node(node); +- _tryToFindOccurrence(nodeRange); +- } +- return super.visitExpression(node); +- } +- +- @override +- Object visitMethodDeclaration(MethodDeclaration node) { +- forceStatic = node.isStatic; +- try { +- return super.visitMethodDeclaration(node); +- } finally { +- forceStatic = false; +- } +- } +- +- @override +- Object visitSwitchMember(SwitchMember node) { +- if (ref._selectionStatements != null) { +- _visitStatements(node.statements); +- } +- return super.visitSwitchMember(node); +- } +- +- /** +- * Checks if given [SourceRange] matched selection source and adds [_Occurrence]. +- */ +- bool _tryToFindOccurrence(SourceRange nodeRange) { +- // check if can be extracted +- if (!ref._isExtractable(nodeRange)) { +- return false; +- } +- // prepare node source +- _SourcePattern nodePattern = ref._getSourcePattern(nodeRange); +- // if matches normalized node source, then add as occurrence +- if (selectionPattern.isCompatible(nodePattern)) { +- _Occurrence occurrence = +- new _Occurrence(nodeRange, ref.selectionRange.intersects(nodeRange)); +- ref._occurrences.add(occurrence); +- // prepare mapping of parameter names to the occurrence variables +- nodePattern.originalToPatternNames +- .forEach((String originalName, String patternName) { +- String selectionName = patternToSelectionName[patternName]; +- occurrence._parameterOldToOccurrenceName[selectionName] = originalName; +- }); +- // update static +- if (forceStatic) { +- ref._staticContext = true; +- } +- // we have match +- return true; +- } +- // no match +- return false; +- } +- +- void _visitStatements(List statements) { +- int beginStatementIndex = 0; +- int selectionCount = ref._selectionStatements.length; +- while (beginStatementIndex + selectionCount <= statements.length) { +- SourceRange nodeRange = range.startEnd(statements[beginStatementIndex], +- statements[beginStatementIndex + selectionCount - 1]); +- bool found = _tryToFindOccurrence(nodeRange); +- // next statement +- if (found) { +- beginStatementIndex += selectionCount; +- } else { +- beginStatementIndex++; +- } +- } +- } +-} +- +-class _InitializeParametersVisitor extends GeneralizingAstVisitor { +- final ExtractMethodRefactoringImpl ref; +- final List assignedUsedVariables; +- +- _InitializeParametersVisitor(this.ref, this.assignedUsedVariables); +- +- @override +- void visitSimpleIdentifier(SimpleIdentifier node) { +- SourceRange nodeRange = range.node(node); +- if (!ref.selectionRange.covers(nodeRange)) { +- return; +- } +- String name = node.name; +- // analyze local element +- Element element = _getLocalElement(node); +- if (element != null) { +- // name of the named expression +- if (isNamedExpressionName(node)) { +- return; +- } +- // if declared outside, add parameter +- if (!ref._isDeclaredInSelection(element)) { +- // add parameter +- RefactoringMethodParameter parameter = ref._parametersMap[name]; +- if (parameter == null) { +- DartType parameterType = node.bestType; +- StringBuffer parametersBuffer = new StringBuffer(); +- String parameterTypeCode = ref.utils.getTypeSource( +- parameterType, ref.librariesToImport, +- parametersBuffer: parametersBuffer); +- String parametersCode = +- parametersBuffer.isNotEmpty ? parametersBuffer.toString() : null; +- parameter = new RefactoringMethodParameter( +- RefactoringMethodParameterKind.REQUIRED, parameterTypeCode, name, +- parameters: parametersCode, id: name); +- ref._parameters.add(parameter); +- ref._parametersMap[name] = parameter; +- } +- // add reference to parameter +- ref._addParameterReference(name, nodeRange); +- } +- // remember, if assigned and used after selection +- if (isLeftHandOfAssignment(node) && ref._isUsedAfterSelection(element)) { +- if (!assignedUsedVariables.contains(element)) { +- assignedUsedVariables.add(element); +- } +- } +- } +- // remember information for conflicts checking +- if (element is LocalElement) { +- // declared local elements +- if (node.inDeclarationContext()) { +- ref._localNames.putIfAbsent(name, () => []); +- ref._localNames[name].add(element.visibleRange); +- } +- } else { +- // unqualified non-local names +- if (!node.isQualified) { +- ref._unqualifiedNames.add(name); +- } +- } +- } +-} +- +-class _IsUsedAfterSelectionVisitor extends GeneralizingAstVisitor { +- final ExtractMethodRefactoringImpl ref; +- final Element element; +- bool result = false; +- +- _IsUsedAfterSelectionVisitor(this.ref, this.element); +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- Element nodeElement = node.staticElement; +- if (identical(nodeElement, element)) { +- int nodeOffset = node.offset; +- if (nodeOffset > ref.selectionRange.end) { +- result = true; +- } +- } +- } +-} +- +-/** +- * Description of a single occurrence of the selected expression or set of +- * statements. +- */ +-class _Occurrence { +- final SourceRange range; +- final bool isSelection; +- +- Map _parameterOldToOccurrenceName = {}; +- +- _Occurrence(this.range, this.isSelection); +-} +- +-class _ReturnTypeComputer extends RecursiveAstVisitor { +- final TypeSystem typeSystem; +- +- DartType returnType; +- +- _ReturnTypeComputer(this.typeSystem); +- +- @override +- visitBlockFunctionBody(BlockFunctionBody node) {} +- +- @override +- visitReturnStatement(ReturnStatement node) { +- // prepare expression +- Expression expression = node.expression; +- if (expression == null) { +- return; +- } +- // prepare type +- DartType type = expression.bestType; +- if (type.isBottom) { +- return; +- } +- // combine types +- if (returnType == null) { +- returnType = type; +- } else { +- if (returnType is InterfaceType && type is InterfaceType) { +- returnType = InterfaceType.getSmartLeastUpperBound(returnType, type); +- } else { +- returnType = typeSystem.getLeastUpperBound(returnType, type); +- } +- } +- } +-} +- +-/** +- * Generalized version of some source, in which references to the specific +- * variables are replaced with pattern variables, with back mapping from the +- * pattern to the original variable names. +- */ +-class _SourcePattern { +- final List parameterTypes = []; +- String normalizedSource; +- Map originalToPatternNames = {}; +- +- bool isCompatible(_SourcePattern other) { +- if (other.normalizedSource != normalizedSource) { +- return false; +- } +- if (other.parameterTypes.length != parameterTypes.length) { +- return false; +- } +- for (int i = 0; i < parameterTypes.length; i++) { +- if (other.parameterTypes[i] != parameterTypes[i]) { +- return false; +- } +- } +- return true; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart +deleted file mode 100644 +index 586080a3afa..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart ++++ /dev/null +@@ -1,213 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * [InlineLocalRefactoring] implementation. +- */ +-class InlineLocalRefactoringImpl extends RefactoringImpl +- implements InlineLocalRefactoring { +- final SearchEngine searchEngine; +- final AstProvider astProvider; +- final CompilationUnit unit; +- final int offset; +- CompilationUnitElement unitElement; +- CorrectionUtils utils; +- +- Element _variableElement; +- VariableDeclaration _variableNode; +- List _references; +- +- InlineLocalRefactoringImpl( +- this.searchEngine, this.astProvider, this.unit, this.offset) { +- unitElement = unit.element; +- utils = new CorrectionUtils(unit); +- } +- +- @override +- String get refactoringName => 'Inline Local Variable'; +- +- @override +- int get referenceCount { +- if (_references == null) { +- return 0; +- } +- return _references.length; +- } +- +- @override +- String get variableName { +- if (_variableElement == null) { +- return null; +- } +- return _variableElement.name; +- } +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- Future checkInitialConditions() async { +- RefactoringStatus result = new RefactoringStatus(); +- // prepare variable +- { +- AstNode offsetNode = new NodeLocator(offset).searchWithin(unit); +- if (offsetNode is SimpleIdentifier) { +- Element element = offsetNode.staticElement; +- if (element is LocalVariableElement) { +- _variableElement = element; +- AstNode name = await astProvider.getResolvedNameForElement(element); +- _variableNode = name.parent as VariableDeclaration; +- } +- } +- } +- // validate node declaration +- if (!_isVariableDeclaredInStatement()) { +- result = new RefactoringStatus.fatal( +- 'Local variable declaration or reference must be selected ' +- 'to activate this refactoring.'); +- return new Future.value(result); +- } +- // should have initializer at declaration +- if (_variableNode.initializer == null) { +- String message = format( +- "Local variable '{0}' is not initialized at declaration.", +- _variableElement.displayName); +- result = new RefactoringStatus.fatal( +- message, newLocation_fromNode(_variableNode)); +- return new Future.value(result); +- } +- // prepare references +- _references = await searchEngine.searchReferences(_variableElement); +- // should not have assignments +- for (SearchMatch reference in _references) { +- if (reference.kind != MatchKind.READ) { +- String message = format( +- "Local variable '{0}' is assigned more than once.", +- [_variableElement.displayName]); +- return new RefactoringStatus.fatal( +- message, newLocation_fromMatch(reference)); +- } +- } +- // done +- return result; +- } +- +- @override +- Future createChange() { +- SourceChange change = new SourceChange(refactoringName); +- // remove declaration +- { +- Statement declarationStatement = _variableNode +- .getAncestor((node) => node is VariableDeclarationStatement); +- SourceRange range = utils.getLinesRangeStatements([declarationStatement]); +- doSourceChange_addElementEdit( +- change, unitElement, newSourceEdit_range(range, '')); +- } +- // prepare initializer +- Expression initializer = _variableNode.initializer; +- String initializerCode = utils.getNodeText(initializer); +- // replace references +- for (SearchMatch reference in _references) { +- SourceRange editRange = reference.sourceRange; +- // prepare context +- int offset = editRange.offset; +- AstNode node = utils.findNode(offset); +- AstNode parent = node.parent; +- // prepare code +- String codeForReference; +- if (parent is InterpolationExpression) { +- StringInterpolation target = parent.parent; +- if (initializer is SingleStringLiteral && +- !initializer.isRaw && +- initializer.isSingleQuoted == target.isSingleQuoted && +- (!initializer.isMultiline || target.isMultiline)) { +- editRange = range.node(parent); +- // unwrap the literal being inlined +- int initOffset = initializer.contentsOffset; +- int initLength = initializer.contentsEnd - initOffset; +- codeForReference = utils.getText(initOffset, initLength); +- } else if (_shouldBeExpressionInterpolation(parent, initializer)) { +- codeForReference = '{$initializerCode}'; +- } else { +- codeForReference = initializerCode; +- } +- } else if (_shouldUseParenthesis(initializer, node)) { +- codeForReference = '($initializerCode)'; +- } else { +- codeForReference = initializerCode; +- } +- // do replace +- doSourceChange_addElementEdit(change, unitElement, +- newSourceEdit_range(editRange, codeForReference)); +- } +- // done +- return new Future.value(change); +- } +- +- @override +- bool requiresPreview() => false; +- +- bool _isVariableDeclaredInStatement() { +- if (_variableNode == null) { +- return false; +- } +- AstNode parent = _variableNode.parent; +- if (parent is VariableDeclarationList) { +- parent = parent.parent; +- if (parent is VariableDeclarationStatement) { +- parent = parent.parent; +- return parent is Block || parent is SwitchCase; +- } +- } +- return false; +- } +- +- static bool _shouldBeExpressionInterpolation( +- InterpolationExpression target, Expression expression) { +- TokenType targetType = target.beginToken.type; +- return targetType == TokenType.STRING_INTERPOLATION_IDENTIFIER && +- expression is! SimpleIdentifier; +- } +- +- static bool _shouldUseParenthesis(Expression init, AstNode node) { +- // check precedence +- int initPrecedence = getExpressionPrecedence(init); +- if (initPrecedence < getExpressionParentPrecedence(node)) { +- return true; +- } +- // special case for '-' +- AstNode parent = node.parent; +- if (init is PrefixExpression && parent is PrefixExpression) { +- if (parent.operator.type == TokenType.MINUS) { +- TokenType initializerOperator = init.operator.type; +- if (initializerOperator == TokenType.MINUS || +- initializerOperator == TokenType.MINUS_MINUS) { +- return true; +- } +- } +- } +- // no () is needed +- return false; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart +deleted file mode 100644 +index caf7a35f521..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart ++++ /dev/null +@@ -1,880 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/utilities_dart.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * Returns the [SourceRange] to find conflicting locals in. +- */ +-SourceRange _getLocalsConflictingRange(AstNode node) { +- // maybe Block +- Block block = node.getAncestor((node) => node is Block); +- if (block != null) { +- return range.startEnd(node, block); +- } +- // maybe whole executable +- AstNode executableNode = getEnclosingExecutableNode(node); +- if (executableNode != null) { +- return range.node(executableNode); +- } +- // not a part of a declaration with locals +- return SourceRange.EMPTY; +-} +- +-/** +- * Returns the source which should replace given invocation with given +- * arguments. +- */ +-String _getMethodSourceForInvocation( +- RefactoringStatus status, +- _SourcePart part, +- CorrectionUtils utils, +- AstNode contextNode, +- Expression targetExpression, +- List arguments) { +- // prepare edits to replace parameters with arguments +- List edits = []; +- part._parameters.forEach( +- (ParameterElement parameter, List<_ParameterOccurrence> occurrences) { +- // prepare argument +- Expression argument = null; +- for (Expression arg in arguments) { +- if (arg.bestParameterElement == parameter) { +- argument = arg; +- break; +- } +- } +- if (argument is NamedExpression) { +- argument = (argument as NamedExpression).expression; +- } +- // prepare argument properties +- int argumentPrecedence; +- String argumentSource; +- if (argument != null) { +- argumentPrecedence = getExpressionPrecedence(argument); +- argumentSource = utils.getNodeText(argument); +- } else { +- // report about a missing required parameter +- if (parameter.parameterKind == ParameterKind.REQUIRED) { +- status.addError('No argument for the parameter "${parameter.name}".', +- newLocation_fromNode(contextNode)); +- return; +- } +- // an optional parameter +- argumentPrecedence = -1000; +- argumentSource = parameter.defaultValueCode; +- if (argumentSource == null) { +- argumentSource = 'null'; +- } +- } +- // replace all occurrences of this parameter +- for (_ParameterOccurrence occurrence in occurrences) { +- SourceRange range = occurrence.range; +- // prepare argument source to apply at this occurrence +- String occurrenceArgumentSource; +- if (argumentPrecedence < occurrence.parentPrecedence) { +- occurrenceArgumentSource = "($argumentSource)"; +- } else { +- occurrenceArgumentSource = argumentSource; +- } +- // do replace +- edits.add(newSourceEdit_range(range, occurrenceArgumentSource)); +- } +- }); +- // replace static field "qualifier" with invocation target +- part._implicitClassNameOffsets.forEach((String className, List offsets) { +- for (int offset in offsets) { +-// edits.add(newSourceEdit_range(range, className + '.')); +- edits.add(new SourceEdit(offset, 0, className + '.')); +- } +- }); +- // replace "this" references with invocation target +- if (targetExpression != null) { +- String targetSource = utils.getNodeText(targetExpression); +- // explicit "this" references +- for (int offset in part._explicitThisOffsets) { +- edits.add(new SourceEdit(offset, 4, targetSource)); +- } +- // implicit "this" references +- targetSource += '.'; +- for (int offset in part._implicitThisOffsets) { +- edits.add(new SourceEdit(offset, 0, targetSource)); +- } +- } +- // prepare edits to replace conflicting variables +- Set conflictingNames = _getNamesConflictingAt(contextNode); +- part._variables.forEach((VariableElement variable, List ranges) { +- String originalName = variable.displayName; +- // prepare unique name +- String uniqueName; +- { +- uniqueName = originalName; +- int uniqueIndex = 2; +- while (conflictingNames.contains(uniqueName)) { +- uniqueName = originalName + uniqueIndex.toString(); +- uniqueIndex++; +- } +- } +- // update references, if name was change +- if (uniqueName != originalName) { +- for (SourceRange range in ranges) { +- edits.add(newSourceEdit_range(range, uniqueName)); +- } +- } +- }); +- // prepare source with applied arguments +- edits.sort((SourceEdit a, SourceEdit b) => b.offset - a.offset); +- return SourceEdit.applySequence(part._source, edits); +-} +- +-/** +- * Returns the names which will shadow or will be shadowed by any declaration +- * at [node]. +- */ +-Set _getNamesConflictingAt(AstNode node) { +- Set result = new Set(); +- // local variables and functions +- { +- SourceRange localsRange = _getLocalsConflictingRange(node); +- AstNode enclosingExecutable = getEnclosingExecutableNode(node); +- List elements = getDefinedLocalElements(enclosingExecutable); +- for (LocalElement element in elements) { +- SourceRange elementRange = element.visibleRange; +- if (elementRange != null && elementRange.intersects(localsRange)) { +- result.add(element.displayName); +- } +- } +- } +- // fields +- { +- ClassElement enclosingClassElement = getEnclosingClassElement(node); +- if (enclosingClassElement != null) { +- Set elements = new Set(); +- elements.add(enclosingClassElement); +- elements.addAll(getSuperClasses(enclosingClassElement)); +- for (ClassElement classElement in elements) { +- List classMembers = getChildren(classElement); +- for (Element classMemberElement in classMembers) { +- result.add(classMemberElement.displayName); +- } +- } +- } +- } +- // done +- return result; +-} +- +-/** +- * [InlineMethodRefactoring] implementation. +- */ +-class InlineMethodRefactoringImpl extends RefactoringImpl +- implements InlineMethodRefactoring { +- final SearchEngine searchEngine; +- final AstProvider astProvider; +- final CompilationUnit unit; +- final int offset; +- ResolvedUnitCache _unitCache; +- CorrectionUtils utils; +- SourceChange change; +- +- bool isDeclaration = false; +- bool deleteSource = false; +- bool inlineAll = true; +- +- ExecutableElement _methodElement; +- bool _isAccessor; +- CompilationUnit _methodUnit; +- CorrectionUtils _methodUtils; +- AstNode _methodNode; +- FormalParameterList _methodParameters; +- FunctionBody _methodBody; +- Expression _methodExpression; +- _SourcePart _methodExpressionPart; +- _SourcePart _methodStatementsPart; +- List<_ReferenceProcessor> _referenceProcessors = []; +- Set _alreadyMadeAsync = new Set(); +- +- InlineMethodRefactoringImpl( +- this.searchEngine, this.astProvider, this.unit, this.offset) { +- _unitCache = new ResolvedUnitCache(astProvider, unit); +- utils = new CorrectionUtils(unit); +- } +- +- @override +- String get className { +- if (_methodElement == null) { +- return null; +- } +- Element classElement = _methodElement.enclosingElement; +- if (classElement is ClassElement) { +- return classElement.displayName; +- } +- return null; +- } +- +- @override +- String get methodName { +- if (_methodElement == null) { +- return null; +- } +- return _methodElement.displayName; +- } +- +- @override +- String get refactoringName { +- if (_methodElement is MethodElement) { +- return "Inline Method"; +- } else { +- return "Inline Function"; +- } +- } +- +- @override +- Future checkFinalConditions() { +- change = new SourceChange(refactoringName); +- RefactoringStatus result = new RefactoringStatus(); +- // check for compatibility of "deleteSource" and "inlineAll" +- if (deleteSource && !inlineAll) { +- result.addError('All references must be inlined to remove the source.'); +- } +- // prepare changes +- for (_ReferenceProcessor processor in _referenceProcessors) { +- processor._process(result); +- } +- // delete method +- if (deleteSource && inlineAll) { +- SourceRange methodRange = range.node(_methodNode); +- SourceRange linesRange = +- _methodUtils.getLinesRange(methodRange, skipLeadingEmptyLines: true); +- doSourceChange_addElementEdit( +- change, _methodElement, newSourceEdit_range(linesRange, '')); +- } +- // done +- return new Future.value(result); +- } +- +- @override +- Future checkInitialConditions() async { +- RefactoringStatus result = new RefactoringStatus(); +- // prepare method information +- result.addStatus(await _prepareMethod()); +- if (result.hasFatalError) { +- return new Future.value(result); +- } +- // maybe operator +- if (_methodElement.isOperator) { +- result = new RefactoringStatus.fatal('Cannot inline operator.'); +- return new Future.value(result); +- } +- // maybe [a]sync* +- if (_methodElement.isGenerator) { +- result = new RefactoringStatus.fatal('Cannot inline a generator.'); +- return new Future.value(result); +- } +- // analyze method body +- result.addStatus(_prepareMethodParts()); +- // process references +- List references = +- await searchEngine.searchReferences(_methodElement); +- _referenceProcessors.clear(); +- for (SearchMatch reference in references) { +- _ReferenceProcessor processor = new _ReferenceProcessor(this, reference); +- await processor.init(); +- _referenceProcessors.add(processor); +- } +- return result; +- } +- +- @override +- Future createChange() { +- return new Future.value(change); +- } +- +- @override +- bool requiresPreview() => false; +- +- Future _computeFunctionDeclaration() async { +- CompilationUnit unit = await _unitCache.getUnit(_methodElement); +- return new NodeLocator(_methodElement.nameOffset) +- .searchWithin(unit) +- .getAncestor((n) => n is FunctionDeclaration) as FunctionDeclaration; +- } +- +- Future _computeMethodDeclaration() async { +- CompilationUnit unit = await _unitCache.getUnit(_methodElement); +- return new NodeLocator(_methodElement.nameOffset) +- .searchWithin(unit) +- .getAncestor((n) => n is MethodDeclaration) as MethodDeclaration; +- } +- +- _SourcePart _createSourcePart(SourceRange range) { +- String source = _methodUtils.getRangeText(range); +- String prefix = getLinePrefix(source); +- _SourcePart result = new _SourcePart(range.offset, source, prefix); +- // remember parameters and variables occurrences +- _methodUnit.accept(new _VariablesVisitor(_methodElement, range, result)); +- // done +- return result; +- } +- +- /** +- * Initializes [_methodElement] and related fields. +- */ +- Future _prepareMethod() async { +- _methodElement = null; +- _methodParameters = null; +- _methodBody = null; +- deleteSource = false; +- inlineAll = false; +- // prepare for failure +- RefactoringStatus fatalStatus = new RefactoringStatus.fatal( +- 'Method declaration or reference must be selected to activate this refactoring.'); +- // prepare selected SimpleIdentifier +- AstNode node = new NodeLocator(offset).searchWithin(unit); +- if (node is! SimpleIdentifier) { +- return fatalStatus; +- } +- SimpleIdentifier identifier = node as SimpleIdentifier; +- // prepare selected ExecutableElement +- Element element = identifier.bestElement; +- if (element is! ExecutableElement) { +- return fatalStatus; +- } +- if (element.isSynthetic) { +- return fatalStatus; +- } +- _methodElement = element as ExecutableElement; +- _isAccessor = element is PropertyAccessorElement; +- _methodUnit = await _unitCache.getUnit(element); +- _methodUtils = new CorrectionUtils(_methodUnit); +- // class member +- bool isClassMember = element.enclosingElement is ClassElement; +- if (element is MethodElement || _isAccessor && isClassMember) { +- MethodDeclaration methodDeclaration = await _computeMethodDeclaration(); +- _methodNode = methodDeclaration; +- _methodParameters = methodDeclaration.parameters; +- _methodBody = methodDeclaration.body; +- // prepare mode +- isDeclaration = node == methodDeclaration.name; +- deleteSource = isDeclaration; +- inlineAll = deleteSource; +- return new RefactoringStatus(); +- } +- // unit member +- bool isUnitMember = element.enclosingElement is CompilationUnitElement; +- if (element is FunctionElement || _isAccessor && isUnitMember) { +- FunctionDeclaration functionDeclaration = +- await _computeFunctionDeclaration(); +- _methodNode = functionDeclaration; +- _methodParameters = functionDeclaration.functionExpression.parameters; +- _methodBody = functionDeclaration.functionExpression.body; +- // prepare mode +- isDeclaration = node == functionDeclaration.name; +- deleteSource = isDeclaration; +- inlineAll = deleteSource; +- return new RefactoringStatus(); +- } +- // OK +- return fatalStatus; +- } +- +- /** +- * Analyze [_methodBody] to fill [_methodExpressionPart] and +- * [_methodStatementsPart]. +- */ +- RefactoringStatus _prepareMethodParts() { +- RefactoringStatus result = new RefactoringStatus(); +- if (_methodBody is ExpressionFunctionBody) { +- ExpressionFunctionBody body = _methodBody as ExpressionFunctionBody; +- _methodExpression = body.expression; +- SourceRange methodExpressionRange = range.node(_methodExpression); +- _methodExpressionPart = _createSourcePart(methodExpressionRange); +- } else if (_methodBody is BlockFunctionBody) { +- Block body = (_methodBody as BlockFunctionBody).block; +- List statements = body.statements; +- if (statements.length >= 1) { +- Statement lastStatement = statements[statements.length - 1]; +- // "return" statement requires special handling +- if (lastStatement is ReturnStatement) { +- _methodExpression = lastStatement.expression; +- SourceRange methodExpressionRange = range.node(_methodExpression); +- _methodExpressionPart = _createSourcePart(methodExpressionRange); +- // exclude "return" statement from statements +- statements = statements.sublist(0, statements.length - 1); +- } +- // if there are statements, process them +- if (!statements.isEmpty) { +- SourceRange statementsRange = +- _methodUtils.getLinesRangeStatements(statements); +- _methodStatementsPart = _createSourcePart(statementsRange); +- } +- } +- // check if more than one return +- body.accept(new _ReturnsValidatorVisitor(result)); +- } else { +- return new RefactoringStatus.fatal('Cannot inline method without body.'); +- } +- return result; +- } +-} +- +-class _ParameterOccurrence { +- final int parentPrecedence; +- final SourceRange range; +- _ParameterOccurrence(this.parentPrecedence, this.range); +-} +- +-/** +- * Processor for single [SearchMatch] reference to [methodElement]. +- */ +-class _ReferenceProcessor { +- final InlineMethodRefactoringImpl ref; +- final SearchMatch reference; +- +- Element refElement; +- CorrectionUtils _refUtils; +- SimpleIdentifier _node; +- SourceRange _refLineRange; +- String _refPrefix; +- +- _ReferenceProcessor(this.ref, this.reference); +- +- Future init() async { +- refElement = reference.element; +- // prepare CorrectionUtils +- CompilationUnit refUnit = await ref._unitCache.getUnit(refElement); +- _refUtils = new CorrectionUtils(refUnit); +- // prepare node and environment +- _node = _refUtils.findNode(reference.sourceRange.offset); +- Statement refStatement = _node.getAncestor((node) => node is Statement); +- if (refStatement != null) { +- _refLineRange = _refUtils.getLinesRangeStatements([refStatement]); +- _refPrefix = _refUtils.getNodePrefix(refStatement); +- } else { +- _refLineRange = null; +- _refPrefix = _refUtils.getLinePrefix(_node.offset); +- } +- } +- +- void _addRefEdit(SourceEdit edit) { +- doSourceChange_addElementEdit(ref.change, refElement, edit); +- } +- +- bool _canInlineBody(AstNode usage) { +- // no statements, usually just expression +- if (ref._methodStatementsPart == null) { +- // empty method, inline as closure +- if (ref._methodExpressionPart == null) { +- return false; +- } +- // OK, just expression +- return true; +- } +- // analyze point of invocation +- AstNode parent = usage.parent; +- AstNode parent2 = parent.parent; +- // OK, if statement in block +- if (parent is Statement) { +- return parent2 is Block; +- } +- // maybe assignment, in block +- if (parent is AssignmentExpression) { +- AssignmentExpression assignment = parent; +- // inlining setter +- if (assignment.leftHandSide == usage) { +- return parent2 is Statement && parent2.parent is Block; +- } +- // inlining initializer +- return ref._methodExpressionPart != null; +- } +- // maybe value for variable initializer, in block +- if (ref._methodExpressionPart != null) { +- if (parent is VariableDeclaration) { +- if (parent2 is VariableDeclarationList) { +- AstNode parent3 = parent2.parent; +- return parent3 is VariableDeclarationStatement && +- parent3.parent is Block; +- } +- } +- } +- // not in block, cannot inline body +- return false; +- } +- +- void _inlineMethodInvocation(RefactoringStatus status, Expression usage, +- bool cascaded, Expression target, List arguments) { +- // we don't support cascade +- if (cascaded) { +- status.addError( +- 'Cannot inline cascade invocation.', newLocation_fromNode(usage)); +- } +- // can we inline method body into "methodUsage" block? +- if (_canInlineBody(usage)) { +- // insert non-return statements +- if (ref._methodStatementsPart != null) { +- // prepare statements source for invocation +- String source = _getMethodSourceForInvocation(status, +- ref._methodStatementsPart, _refUtils, usage, target, arguments); +- source = _refUtils.replaceSourceIndent( +- source, ref._methodStatementsPart._prefix, _refPrefix); +- // do insert +- SourceEdit edit = newSourceEdit_range( +- new SourceRange(_refLineRange.offset, 0), source); +- _addRefEdit(edit); +- } +- // replace invocation with return expression +- if (ref._methodExpressionPart != null) { +- // prepare expression source for invocation +- String source = _getMethodSourceForInvocation(status, +- ref._methodExpressionPart, _refUtils, usage, target, arguments); +- if (getExpressionPrecedence(ref._methodExpression) < +- getExpressionParentPrecedence(usage)) { +- source = "($source)"; +- } +- // do replace +- SourceRange methodUsageRange = range.node(usage); +- SourceEdit edit = newSourceEdit_range(methodUsageRange, source); +- _addRefEdit(edit); +- } else { +- SourceEdit edit = newSourceEdit_range(_refLineRange, ""); +- _addRefEdit(edit); +- } +- return; +- } +- // inline as closure invocation +- String source; +- { +- source = ref._methodUtils.getRangeText(range.startEnd( +- ref._methodParameters.leftParenthesis, ref._methodNode)); +- String methodPrefix = +- ref._methodUtils.getLinePrefix(ref._methodNode.offset); +- source = _refUtils.replaceSourceIndent(source, methodPrefix, _refPrefix); +- source = source.trim(); +- } +- // do insert +- SourceEdit edit = newSourceEdit_range(range.node(_node), source); +- _addRefEdit(edit); +- } +- +- void _process(RefactoringStatus status) { +- AstNode nodeParent = _node.parent; +- // may be only single place should be inlined +- if (!_shouldProcess()) { +- return; +- } +- // If the element being inlined is async, ensure that the function +- // body that encloses the method is also async. +- if (ref._methodElement.isAsynchronous) { +- FunctionBody body = _node.getAncestor((n) => n is FunctionBody); +- if (body != null) { +- if (body.isSynchronous) { +- if (body.isGenerator) { +- status.addFatalError( +- 'Cannot inline async into sync*.', newLocation_fromNode(_node)); +- return; +- } +- if (refElement is ExecutableElement) { +- var executable = refElement as ExecutableElement; +- if (!executable.returnType.isDartAsyncFuture) { +- status.addFatalError( +- 'Cannot inline async into a function that does not return a Future.', +- newLocation_fromNode(_node)); +- return; +- } +- } +- if (ref._alreadyMadeAsync.add(body)) { +- SourceRange bodyStart = range.startLength(body, 0); +- _addRefEdit(newSourceEdit_range(bodyStart, 'async ')); +- } +- } +- } +- } +- // may be invocation of inline method +- if (nodeParent is MethodInvocation) { +- MethodInvocation invocation = nodeParent; +- Expression target = invocation.target; +- List arguments = invocation.argumentList.arguments; +- _inlineMethodInvocation( +- status, invocation, invocation.isCascaded, target, arguments); +- } else { +- // cannot inline reference to method: var v = new A().method; +- if (ref._methodElement is MethodElement) { +- status.addFatalError('Cannot inline class method reference.', +- newLocation_fromNode(_node)); +- return; +- } +- // PropertyAccessorElement +- if (ref._methodElement is PropertyAccessorElement) { +- Expression usage = _node; +- Expression target = null; +- bool cascade = false; +- if (nodeParent is PrefixedIdentifier) { +- PrefixedIdentifier propertyAccess = nodeParent; +- usage = propertyAccess; +- target = propertyAccess.prefix; +- cascade = false; +- } +- if (nodeParent is PropertyAccess) { +- PropertyAccess propertyAccess = nodeParent; +- usage = propertyAccess; +- target = propertyAccess.realTarget; +- cascade = propertyAccess.isCascaded; +- } +- // prepare arguments +- List arguments = []; +- if (_node.inSetterContext()) { +- AssignmentExpression assignment = +- _node.getAncestor((node) => node is AssignmentExpression); +- arguments.add(assignment.rightHandSide); +- } +- // inline body +- _inlineMethodInvocation(status, usage, cascade, target, arguments); +- return; +- } +- // not invocation, just reference to function +- String source; +- { +- source = ref._methodUtils.getRangeText(range.startEnd( +- ref._methodParameters.leftParenthesis, ref._methodNode)); +- String methodPrefix = +- ref._methodUtils.getLinePrefix(ref._methodNode.offset); +- source = +- _refUtils.replaceSourceIndent(source, methodPrefix, _refPrefix); +- source = source.trim(); +- source = removeEnd(source, ';'); +- } +- // do insert +- SourceEdit edit = newSourceEdit_range(range.node(_node), source); +- _addRefEdit(edit); +- } +- } +- +- bool _shouldProcess() { +- if (!ref.inlineAll) { +- SourceRange parentRange = range.node(_node); +- return parentRange.contains(ref.offset); +- } +- return true; +- } +-} +- +-class _ReturnsValidatorVisitor extends RecursiveAstVisitor { +- final RefactoringStatus result; +- int _numReturns = 0; +- +- _ReturnsValidatorVisitor(this.result); +- +- @override +- visitReturnStatement(ReturnStatement node) { +- _numReturns++; +- if (_numReturns == 2) { +- result.addError('Ambiguous return value.', newLocation_fromNode(node)); +- } +- } +-} +- +-/** +- * Information about the source of a method being inlined. +- */ +-class _SourcePart { +- /** +- * The base for all [SourceRange]s. +- */ +- final int _base; +- +- /** +- * The source of the method. +- */ +- final String _source; +- +- /** +- * The original prefix of the method. +- */ +- final String _prefix; +- +- /** +- * The occurrences of the method parameters. +- */ +- final Map> _parameters = {}; +- +- /** +- * The occurrences of the method local variables. +- */ +- final Map> _variables = {}; +- +- /** +- * The offsets of explicit `this` expression references. +- */ +- final List _explicitThisOffsets = []; +- +- /** +- * The offsets of implicit `this` expression references. +- */ +- final List _implicitThisOffsets = []; +- +- /** +- * The offsets of the implicit class references in static member references. +- */ +- final Map> _implicitClassNameOffsets = {}; +- +- _SourcePart(this._base, this._source, this._prefix); +- +- void addExplicitThisOffset(int offset) { +- _explicitThisOffsets.add(offset - _base); +- } +- +- void addImplicitClassNameOffset(String className, int offset) { +- List offsets = _implicitClassNameOffsets[className]; +- if (offsets == null) { +- offsets = []; +- _implicitClassNameOffsets[className] = offsets; +- } +- offsets.add(offset - _base); +- } +- +- void addImplicitThisOffset(int offset) { +- _implicitThisOffsets.add(offset - _base); +- } +- +- void addParameterOccurrence( +- ParameterElement parameter, SourceRange identifierRange, int precedence) { +- if (parameter != null) { +- List<_ParameterOccurrence> occurrences = _parameters[parameter]; +- if (occurrences == null) { +- occurrences = []; +- _parameters[parameter] = occurrences; +- } +- identifierRange = range.offsetBy(identifierRange, -_base); +- occurrences.add(new _ParameterOccurrence(precedence, identifierRange)); +- } +- } +- +- void addVariable(VariableElement element, SourceRange identifierRange) { +- List ranges = _variables[element]; +- if (ranges == null) { +- ranges = []; +- _variables[element] = ranges; +- } +- identifierRange = range.offsetBy(identifierRange, -_base); +- ranges.add(identifierRange); +- } +-} +- +-/** +- * A visitor that fills [_SourcePart] with fields, parameters and variables. +- */ +-class _VariablesVisitor extends GeneralizingAstVisitor { +- /** +- * The [ExecutableElement] being inlined. +- */ +- final ExecutableElement methodElement; +- +- /** +- * The [SourceRange] of the element body. +- */ +- SourceRange bodyRange; +- +- /** +- * The [_SourcePart] to record reference into. +- */ +- _SourcePart result; +- +- int offset; +- +- _VariablesVisitor(this.methodElement, this.bodyRange, this.result); +- +- @override +- visitNode(AstNode node) { +- SourceRange nodeRange = range.node(node); +- if (!bodyRange.intersects(nodeRange)) { +- return null; +- } +- super.visitNode(node); +- } +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- SourceRange nodeRange = range.node(node); +- if (bodyRange.covers(nodeRange)) { +- _addMemberQualifier(node); +- _addParameter(node); +- _addVariable(node); +- } +- } +- +- @override +- visitThisExpression(ThisExpression node) { +- int offset = node.offset; +- if (bodyRange.contains(offset)) { +- result.addExplicitThisOffset(offset); +- } +- } +- +- void _addMemberQualifier(SimpleIdentifier node) { +- // should be unqualified +- AstNode qualifier = getNodeQualifier(node); +- if (qualifier != null) { +- return; +- } +- // should be a method or field reference +- Element element = node.staticElement; +- if (!(element is MethodElement || element is PropertyAccessorElement)) { +- return; +- } +- if (element.enclosingElement is! ClassElement) { +- return; +- } +- // record the implicit static or instance reference +- ExecutableElement member = element; +- int offset = node.offset; +- if (member.isStatic) { +- String className = member.enclosingElement.displayName; +- result.addImplicitClassNameOffset(className, offset); +- } else { +- result.addImplicitThisOffset(offset); +- } +- } +- +- void _addParameter(SimpleIdentifier node) { +- ParameterElement parameterElement = getParameterElement(node); +- // not a parameter +- if (parameterElement == null) { +- return; +- } +- // not a parameter of the function being inlined +- if (!methodElement.parameters.contains(parameterElement)) { +- return; +- } +- // OK, add occurrence +- SourceRange nodeRange = range.node(node); +- int parentPrecedence = getExpressionParentPrecedence(node); +- result.addParameterOccurrence( +- parameterElement, nodeRange, parentPrecedence); +- } +- +- void _addVariable(SimpleIdentifier node) { +- VariableElement variableElement = getLocalVariableElement(node); +- if (variableElement != null) { +- SourceRange nodeRange = range.node(node); +- result.addVariable(variableElement, nodeRange); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart +deleted file mode 100644 +index 7691fbb32fe..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart ++++ /dev/null +@@ -1,263 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +-import 'package:front_end/src/scanner/token.dart' show Keyword; +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateClassName(String name) { +- return _validateUpperCamelCase(name, "Class"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateConstructorName(String name) { +- if (name != null && name.isEmpty) { +- return new RefactoringStatus(); +- } +- return _validateLowerCamelCase(name, "Constructor"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateFieldName(String name) { +- return _validateLowerCamelCase(name, "Field"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateFunctionName(String name) { +- return _validateLowerCamelCase(name, "Function"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateFunctionTypeAliasName(String name) { +- return _validateUpperCamelCase(name, "Function type alias"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateImportPrefixName(String name) { +- if (name != null && name.isEmpty) { +- return new RefactoringStatus(); +- } +- return _validateLowerCamelCase(name, "Import prefix"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateLabelName(String name) { +- return _validateLowerCamelCase(name, "Label"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateLibraryName(String name) { +- // null +- if (name == null) { +- return new RefactoringStatus.fatal("Library name must not be null."); +- } +- // blank +- if (isBlank(name)) { +- return new RefactoringStatus.fatal("Library name must not be blank."); +- } +- // check identifiers +- List identifiers = name.split('.'); +- for (String identifier in identifiers) { +- RefactoringStatus status = _validateIdentifier(identifier, +- "Library name identifier", "a lowercase letter or underscore"); +- if (!status.isOK) { +- return status; +- } +- } +- // should not have upper-case letters +- for (String identifier in identifiers) { +- for (int c in identifier.codeUnits) { +- if (isUpperCase(c)) { +- return new RefactoringStatus.warning( +- "Library name should consist of lowercase identifier separated by dots."); +- } +- } +- } +- // OK +- return new RefactoringStatus(); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateMethodName(String name) { +- return _validateLowerCamelCase(name, "Method"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateParameterName(String name) { +- return _validateLowerCamelCase(name, "Parameter"); +-} +- +-/** +- * Returns the [RefactoringStatus] with severity: +- * OK if the name is valid; +- * WARNING if the name is discouraged; +- * FATAL if the name is illegal. +- */ +-RefactoringStatus validateVariableName(String name) { +- return _validateLowerCamelCase(name, "Variable"); +-} +- +-RefactoringStatus _validateIdentifier( +- String identifier, String desc, String beginDesc) { +- // has leading/trailing spaces +- String trimmed = identifier.trim(); +- if (identifier != trimmed) { +- String message = "$desc must not start or end with a blank."; +- return new RefactoringStatus.fatal(message); +- } +- // empty +- int length = identifier.length; +- if (length == 0) { +- String message = "$desc must not be empty."; +- return new RefactoringStatus.fatal(message); +- } +- // keyword +- { +- Keyword keyword = Keyword.keywords[identifier]; +- if (keyword != null) { +- String message = "$desc must not be a keyword."; +- return new RefactoringStatus.fatal(message); +- } +- } +- // first character +- int currentChar = identifier.codeUnitAt(0); +- if (!isLetter(currentChar) && +- currentChar != CHAR_UNDERSCORE && +- currentChar != CHAR_DOLLAR) { +- String message = "$desc must begin with $beginDesc."; +- return new RefactoringStatus.fatal(message); +- } +- // other characters +- for (int i = 1; i < length; i++) { +- currentChar = identifier.codeUnitAt(i); +- if (!isLetterOrDigit(currentChar) && +- currentChar != CHAR_UNDERSCORE && +- currentChar != CHAR_DOLLAR) { +- String charStr = new String.fromCharCode(currentChar); +- String message = "$desc must not contain '$charStr'."; +- return new RefactoringStatus.fatal(message); +- } +- } +- // OK +- return new RefactoringStatus(); +-} +- +-/** +- * Validates [identifier], should be lower camel case. +- */ +-RefactoringStatus _validateLowerCamelCase(String identifier, String desc) { +- desc += ' name'; +- // null +- if (identifier == null) { +- String message = "$desc must not be null."; +- return new RefactoringStatus.fatal(message); +- } +- // is not identifier +- RefactoringStatus status = +- _validateIdentifier(identifier, desc, "a lowercase letter or underscore"); +- if (!status.isOK) { +- return status; +- } +- // is private, OK +- if (identifier.codeUnitAt(0) == CHAR_UNDERSCORE) { +- return new RefactoringStatus(); +- } +- // leading $, OK +- if (identifier.codeUnitAt(0) == CHAR_DOLLAR) { +- return new RefactoringStatus(); +- } +- // does not start with lower case +- if (!isLowerCase(identifier.codeUnitAt(0))) { +- String message = "$desc should start with a lowercase letter."; +- return new RefactoringStatus.warning(message); +- } +- // OK +- return new RefactoringStatus(); +-} +- +-/** +- * Validate the given identifier, which should be upper camel case. +- */ +-RefactoringStatus _validateUpperCamelCase(String identifier, String desc) { +- desc += ' name'; +- // null +- if (identifier == null) { +- String message = "$desc must not be null."; +- return new RefactoringStatus.fatal(message); +- } +- // is not identifier +- RefactoringStatus status = _validateIdentifier( +- identifier, desc, "an uppercase letter or underscore"); +- if (!status.isOK) { +- return status; +- } +- // is private, OK +- if (identifier.codeUnitAt(0) == CHAR_UNDERSCORE) { +- return new RefactoringStatus(); +- } +- // leading $, OK +- if (identifier.codeUnitAt(0) == CHAR_DOLLAR) { +- return new RefactoringStatus(); +- } +- // does not start with upper case +- if (!isUpperCase(identifier.codeUnitAt(0))) { +- // By convention, class names usually start with an uppercase letter +- String message = "$desc should start with an uppercase letter."; +- return new RefactoringStatus.warning(message); +- } +- // OK +- return new RefactoringStatus(); +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart +deleted file mode 100644 +index 1e51c6fd526..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart ++++ /dev/null +@@ -1,444 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/convert_getter_to_method.dart'; +-import 'package:analysis_server/src/services/refactoring/convert_method_to_getter.dart'; +-import 'package:analysis_server/src/services/refactoring/extract_local.dart'; +-import 'package:analysis_server/src/services/refactoring/extract_method.dart'; +-import 'package:analysis_server/src/services/refactoring/inline_local.dart'; +-import 'package:analysis_server/src/services/refactoring/inline_method.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_class_member.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_constructor.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_import.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_label.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_library.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_local.dart'; +-import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show RefactoringMethodParameter, SourceChange; +- +-/** +- * [Refactoring] to convert getters into normal [MethodDeclaration]s. +- */ +-abstract class ConvertGetterToMethodRefactoring implements Refactoring { +- /** +- * Returns a new [ConvertMethodToGetterRefactoring] instance for converting +- * [element] and all the corresponding hierarchy elements. +- */ +- factory ConvertGetterToMethodRefactoring(SearchEngine searchEngine, +- AstProvider astProvider, PropertyAccessorElement element) { +- return new ConvertGetterToMethodRefactoringImpl( +- searchEngine, astProvider, element); +- } +-} +- +-/** +- * [Refactoring] to convert normal [MethodDeclaration]s into getters. +- */ +-abstract class ConvertMethodToGetterRefactoring implements Refactoring { +- /** +- * Returns a new [ConvertMethodToGetterRefactoring] instance for converting +- * [element] and all the corresponding hierarchy elements. +- */ +- factory ConvertMethodToGetterRefactoring(SearchEngine searchEngine, +- AstProvider astProvider, ExecutableElement element) { +- return new ConvertMethodToGetterRefactoringImpl( +- searchEngine, astProvider, element); +- } +-} +- +-/** +- * [Refactoring] to extract an expression into a local variable declaration. +- */ +-abstract class ExtractLocalRefactoring implements Refactoring { +- /** +- * Returns a new [ExtractLocalRefactoring] instance. +- */ +- factory ExtractLocalRefactoring( +- CompilationUnit unit, int selectionOffset, int selectionLength) { +- return new ExtractLocalRefactoringImpl( +- unit, selectionOffset, selectionLength); +- } +- +- /** +- * The lengths of the expressions that cover the specified selection, +- * from the down most to the up most. +- */ +- List get coveringExpressionLengths; +- +- /** +- * The offsets of the expressions that cover the specified selection, +- * from the down most to the up most. +- */ +- List get coveringExpressionOffsets; +- +- /** +- * True if all occurrences of the expression within the scope in which the +- * variable will be defined should be replaced by a reference to the local +- * variable. The expression used to initiate the refactoring will always be +- * replaced. +- */ +- void set extractAll(bool extractAll); +- +- /** +- * The lengths of the expressions that would be replaced by a reference to the +- * variable. The lengths correspond to the offsets. In other words, for a +- * given expression, if the offset of that expression is offsets[i], then the +- * length of that expression is lengths[i]. +- */ +- List get lengths; +- +- /** +- * The name that the local variable should be given. +- */ +- void set name(String name); +- +- /** +- * The proposed names for the local variable. +- * +- * The first proposal should be used as the "best guess" (if it exists). +- */ +- List get names; +- +- /** +- * The offsets of the expressions that would be replaced by a reference to +- * the variable. +- */ +- List get offsets; +- +- /** +- * Validates that the [name] is a valid identifier and is appropriate for +- * local variable. +- * +- * It does not perform all the checks (such as checking for conflicts with any +- * existing names in any of the scopes containing the current name), as many +- * of these checks require search engine. Use [checkFinalConditions] for this +- * level of checking. +- */ +- RefactoringStatus checkName(); +-} +- +-/** +- * [Refactoring] to extract an [Expression] or [Statement]s into a new method. +- */ +-abstract class ExtractMethodRefactoring implements Refactoring { +- /** +- * Returns a new [ExtractMethodRefactoring] instance. +- */ +- factory ExtractMethodRefactoring( +- SearchEngine searchEngine, +- AstProvider astProvider, +- CompilationUnit unit, +- int selectionOffset, +- int selectionLength) { +- return new ExtractMethodRefactoringImpl( +- searchEngine, astProvider, unit, selectionOffset, selectionLength); +- } +- +- /** +- * True if a getter could be created rather than a method. +- */ +- bool get canCreateGetter; +- +- /** +- * True if a getter should be created rather than a method. +- */ +- void set createGetter(bool createGetter); +- +- /** +- * True if all occurrences of the expression or statements should be replaced +- * by an invocation of the method. The expression or statements used to +- * initiate the refactoring will always be replaced. +- */ +- void set extractAll(bool extractAll); +- +- /** +- * The lengths of the expressions or statements that would be replaced by an +- * invocation of the method. The lengths correspond to the offsets. +- * In other words, for a given expression (or block of statements), if the +- * offset of that expression is offsets[i], then the length of that expression +- * is lengths[i]. +- */ +- List get lengths; +- +- /** +- * The name that the method should be given. +- */ +- void set name(String name); +- +- /** +- * The proposed names for the method. +- * +- * The first proposal should be used as the "best guess" (if it exists). +- */ +- List get names; +- +- /** +- * The offsets of the expressions or statements that would be replaced by an +- * invocation of the method. +- */ +- List get offsets; +- +- /** +- * The proposed parameters for the method. +- */ +- List get parameters; +- +- /** +- * The parameters that should be defined for the method. +- */ +- void set parameters(List parameters); +- +- /** +- * The proposed return type for the method. +- */ +- String get returnType; +- +- /** +- * The return type that should be defined for the method. +- */ +- void set returnType(String returnType); +- +- /** +- * Validates that the [name] is a valid identifier and is appropriate for a +- * method. +- * +- * It does not perform all the checks (such as checking for conflicts with any +- * existing names in any of the scopes containing the current name), as many +- * of these checks require search engine. Use [checkFinalConditions] for this +- * level of checking. +- */ +- RefactoringStatus checkName(); +-} +- +-/** +- * [Refactoring] to inline a local [VariableElement]. +- */ +-abstract class InlineLocalRefactoring implements Refactoring { +- /** +- * Returns a new [InlineLocalRefactoring] instance. +- */ +- factory InlineLocalRefactoring(SearchEngine searchEngine, +- AstProvider astProvider, CompilationUnit unit, int offset) { +- return new InlineLocalRefactoringImpl( +- searchEngine, astProvider, unit, offset); +- } +- +- /** +- * Returns the number of references to the [VariableElement]. +- */ +- int get referenceCount; +- +- /** +- * Returns the name of the variable being inlined. +- */ +- String get variableName; +-} +- +-/** +- * [Refactoring] to inline an [ExecutableElement]. +- */ +-abstract class InlineMethodRefactoring implements Refactoring { +- /** +- * Returns a new [InlineMethodRefactoring] instance. +- */ +- factory InlineMethodRefactoring(SearchEngine searchEngine, +- AstProvider astProvider, CompilationUnit unit, int offset) { +- return new InlineMethodRefactoringImpl( +- searchEngine, astProvider, unit, offset); +- } +- +- /** +- * The name of the class enclosing the method being inlined. +- * If not a class member is being inlined, then `null`. +- */ +- String get className; +- +- /** +- * True if the method being inlined should be removed. +- * It is an error if this field is `true` and [inlineAll] is `false`. +- */ +- void set deleteSource(bool deleteSource); +- +- /** +- * True if all invocations of the method should be inlined, or false if only +- * the invocation site used to create this refactoring should be inlined. +- */ +- void set inlineAll(bool inlineAll); +- +- /** +- * True if the declaration of the method is selected. +- * So, all references should be inlined. +- */ +- bool get isDeclaration; +- +- /** +- * The name of the method (or function) being inlined. +- */ +- String get methodName; +-} +- +-/** +- * Abstract interface for all refactorings. +- */ +-abstract class Refactoring { +- /** +- * The ids of source edits that are not known to be valid. +- * +- * An edit is not known to be valid if there was insufficient type information +- * for the server to be able to determine whether or not the code needs to be +- * modified, such as when a member is being renamed and there is a reference +- * to a member from an unknown type. This field will be omitted if the change +- * field is omitted or if there are no potential edits for the refactoring. +- */ +- List get potentialEditIds; +- +- /** +- * Returns the human readable name of this [Refactoring]. +- */ +- String get refactoringName; +- +- /** +- * Checks all conditions - [checkInitialConditions] and +- * [checkFinalConditions] to decide if refactoring can be performed. +- */ +- Future checkAllConditions(); +- +- /** +- * Validates environment to check if this refactoring can be performed. +- * +- * This check may be slow, because many refactorings use search engine. +- */ +- Future checkFinalConditions(); +- +- /** +- * Validates arguments to check if this refactoring can be performed. +- * +- * This check should be quick because it is used often as arguments change. +- */ +- Future checkInitialConditions(); +- +- /** +- * Returns the [Change] to apply to perform this refactoring. +- */ +- Future createChange(); +- +- /** +- * Returs `true` if the [Change] created by refactoring may be unsafe, +- * so we want user to review the [Change] to ensure that he understands it. +- */ +- bool requiresPreview(); +-} +- +-/** +- * Abstract [Refactoring] for renaming some [Element]. +- */ +-abstract class RenameRefactoring implements Refactoring { +- /** +- * Returns a new [RenameRefactoring] instance for renaming [element], +- * maybe `null` if there is no support for renaming [Element]s of the given +- * type. +- */ +- factory RenameRefactoring( +- SearchEngine searchEngine, AstProvider astProvider, Element element) { +- if (element == null) { +- return null; +- } +- if (element is PropertyAccessorElement) { +- element = (element as PropertyAccessorElement).variable; +- } +- if (element.enclosingElement is CompilationUnitElement) { +- return new RenameUnitMemberRefactoringImpl(searchEngine, element); +- } +- if (element is ConstructorElement) { +- return new RenameConstructorRefactoringImpl( +- searchEngine, astProvider, element); +- } +- if (element is ImportElement) { +- return new RenameImportRefactoringImpl( +- searchEngine, astProvider, element); +- } +- if (element is LabelElement) { +- return new RenameLabelRefactoringImpl(searchEngine, element); +- } +- if (element is LibraryElement) { +- return new RenameLibraryRefactoringImpl(searchEngine, element); +- } +- if (element is LocalElement) { +- return new RenameLocalRefactoringImpl(searchEngine, astProvider, element); +- } +- if (element.enclosingElement is ClassElement) { +- return new RenameClassMemberRefactoringImpl( +- searchEngine, astProvider, element); +- } +- return null; +- } +- +- /** +- * Returns the human-readable description of the kind of element being renamed +- * (such as “class” or “function type alias”). +- */ +- String get elementKindName; +- +- /** +- * Sets the new name for the [Element]. +- */ +- void set newName(String newName); +- +- /** +- * Returns the old name of the [Element] being renamed. +- */ +- String get oldName; +- +- /** +- * Validates that the [newName] is a valid identifier and is appropriate for +- * the type of the [Element] being renamed. +- * +- * It does not perform all the checks (such as checking for conflicts with any +- * existing names in any of the scopes containing the current name), as many +- * of these checks require search engine. Use [checkFinalConditions] for this +- * level of checking. +- */ +- RefactoringStatus checkNewName(); +-} +- +-/** +- * Cache for accessing resolved [CompilationUnit]s by [Element]s. +- * +- * Must by short-lived. +- * +- * TODO(scheglov) consider moving to request-bound object. +- */ +-class ResolvedUnitCache { +- final AstProvider _astProvider; +- final Map _map = {}; +- +- ResolvedUnitCache(this._astProvider, [CompilationUnit unit]) { +- if (unit != null) { +- _map[unit.element] = unit; +- } +- } +- +- Future getUnit(Element element) async { +- CompilationUnitElement unitElement = getUnitElement(element); +- CompilationUnit unit = _map[unitElement]; +- if (unit == null) { +- unit = await _astProvider.getResolvedUnitForElement(element); +- _map[unitElement] = unit; +- } +- return unit; +- } +- +- CompilationUnitElement getUnitElement(Element element) { +- return element.getAncestor((e) => e is CompilationUnitElement) +- as CompilationUnitElement; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart +deleted file mode 100644 +index eebc587e59a..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart ++++ /dev/null +@@ -1,116 +0,0 @@ +-// Copyright (c) 2014, 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:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * Return a new [SourceReference] instance for the given [match]. +- */ +-SourceReference getSourceReference(SearchMatch match) { +- return new SourceReference(match); +-} +- +-/** +- * When a [Source] (a file) is used in more than one context, [SearchEngine] +- * will return separate [SearchMatch]s for each context. But in rename +- * refactorings we want to update each [Source] only once. +- */ +-List getSourceReferences(List matches) { +- var uniqueReferences = new HashMap(); +- for (SearchMatch match in matches) { +- SourceReference newReference = getSourceReference(match); +- SourceReference oldReference = uniqueReferences[newReference]; +- if (oldReference == null) { +- uniqueReferences[newReference] = newReference; +- oldReference = newReference; +- } +- } +- return uniqueReferences.keys.toList(); +-} +- +-/** +- * Abstract implementation of [Refactoring]. +- */ +-abstract class RefactoringImpl implements Refactoring { +- final List potentialEditIds = []; +- +- @override +- Future checkAllConditions() async { +- RefactoringStatus result = new RefactoringStatus(); +- result.addStatus(await checkInitialConditions()); +- if (result.hasFatalError) { +- return result; +- } +- result.addStatus(await checkFinalConditions()); +- return result; +- } +-} +- +-/** +- * The [SourceRange] in some [Source]. +- * +- * TODO(scheglov) inline this class as SearchMatch +- */ +-class SourceReference { +- final SearchMatch _match; +- +- SourceReference(this._match); +- +- Element get element => _match.element; +- +- /** +- * The full path of the file containing the match. +- */ +- String get file => _match.file; +- +- @override +- int get hashCode { +- int hash = file.hashCode; +- hash = ((hash << 16) & 0xFFFFFFFF) + range.hashCode; +- return hash; +- } +- +- bool get isResolved => _match.isResolved; +- +- SourceRange get range => _match.sourceRange; +- +- Source get unitSource => _match.unitSource; +- +- @override +- bool operator ==(Object other) { +- if (identical(other, this)) { +- return true; +- } +- if (other is SourceReference) { +- return other.file == file && other.range == range; +- } +- return false; +- } +- +- /** +- * Adds the [SourceEdit] to replace this reference. +- */ +- void addEdit(SourceChange change, String newText, {String id}) { +- SourceEdit edit = createEdit(newText, id: id); +- doSourceChange_addSourceEdit(change, unitSource, edit); +- } +- +- /** +- * Returns the [SourceEdit] to replace this reference. +- */ +- SourceEdit createEdit(String newText, {String id}) { +- return newSourceEdit_range(range, newText, id: id); +- } +- +- @override +- String toString() => '$file@$range'; +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart +deleted file mode 100644 +index db79f492bae..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart ++++ /dev/null +@@ -1,148 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +-import 'package:path/path.dart' as pathos; +- +-bool isElementInPubCache(Element element) { +- Source source = element.source; +- String path = source.fullName; +- return isPathInPubCache(path); +-} +- +-bool isElementInSdkOrPubCache(Element element) { +- Source source = element.source; +- String path = source.fullName; +- return source.isInSystemLibrary || isPathInPubCache(path); +-} +- +-bool isPathInPubCache(String path) { +- List parts = pathos.split(path); +- if (parts.contains('.pub-cache')) { +- return true; +- } +- for (int i = 0; i < parts.length - 1; i++) { +- if (parts[i] == 'Pub' && parts[i + 1] == 'Cache') { +- return true; +- } +- if (parts[i] == 'third_party' && +- (parts[i + 1] == 'pkg' || parts[i + 1] == 'pkg_tested')) { +- return true; +- } +- } +- return false; +-} +- +-/** +- * An abstract implementation of [RenameRefactoring]. +- */ +-abstract class RenameRefactoringImpl extends RefactoringImpl +- implements RenameRefactoring { +- final SearchEngine searchEngine; +- final Element _element; +- final String elementKindName; +- final String oldName; +- SourceChange change; +- +- String newName; +- +- RenameRefactoringImpl(SearchEngine searchEngine, Element element) +- : searchEngine = searchEngine, +- _element = element, +- elementKindName = element.kind.displayName, +- oldName = _getDisplayName(element); +- +- Element get element => _element; +- +- /** +- * Adds a [SourceEdit] to update [element] name to [change]. +- */ +- void addDeclarationEdit(Element element) { +- if (element != null) { +- SourceEdit edit = +- newSourceEdit_range(range.elementName(element), newName); +- doSourceChange_addElementEdit(change, element, edit); +- } +- } +- +- /** +- * Adds [SourceEdit]s to update [matches] to [change]. +- */ +- void addReferenceEdits(List matches) { +- List references = getSourceReferences(matches); +- for (SourceReference reference in references) { +- reference.addEdit(change, newName); +- } +- } +- +- @override +- Future checkInitialConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- if (element.source.isInSystemLibrary) { +- String message = format( +- "The {0} '{1}' is defined in the SDK, so cannot be renamed.", +- getElementKindName(element), +- getElementQualifiedName(element)); +- result.addFatalError(message); +- } +- if (isElementInPubCache(element)) { +- String message = format( +- "The {0} '{1}' is defined in a pub package, so cannot be renamed.", +- getElementKindName(element), +- getElementQualifiedName(element)); +- result.addFatalError(message); +- } +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = new RefactoringStatus(); +- if (newName == oldName) { +- result.addFatalError( +- "The new name must be different than the current name."); +- } +- return result; +- } +- +- @override +- Future createChange() async { +- String changeName = "$refactoringName '$oldName' to '$newName'"; +- change = new SourceChange(changeName); +- await fillChange(); +- return change; +- } +- +- /** +- * Adds individual edits to [change]. +- */ +- Future fillChange(); +- +- @override +- bool requiresPreview() { +- return false; +- } +- +- static String _getDisplayName(Element element) { +- if (element is ImportElement) { +- PrefixElement prefix = element.prefix; +- if (prefix != null) { +- return prefix.displayName; +- } +- return ''; +- } +- return element.displayName; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart +deleted file mode 100644 +index 22aa8eeb4ab..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart ++++ /dev/null +@@ -1,345 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- hide Element, ElementKind; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +- +-/** +- * Checks if creating a method with the given [name] in [classElement] will +- * cause any conflicts. +- */ +-Future validateCreateMethod(SearchEngine searchEngine, +- AstProvider astProvider, ClassElement classElement, String name) { +- return new _ClassMemberValidator.forCreate( +- searchEngine, astProvider, classElement, name) +- .validate(); +-} +- +-/** +- * A [Refactoring] for renaming class member [Element]s. +- */ +-class RenameClassMemberRefactoringImpl extends RenameRefactoringImpl { +- final AstProvider astProvider; +- +- _ClassMemberValidator _validator; +- +- RenameClassMemberRefactoringImpl( +- SearchEngine searchEngine, this.astProvider, Element element) +- : super(searchEngine, element); +- +- @override +- String get refactoringName { +- if (element is TypeParameterElement) { +- return "Rename Type Parameter"; +- } +- if (element is FieldElement) { +- return "Rename Field"; +- } +- return "Rename Method"; +- } +- +- @override +- Future checkFinalConditions() { +- _validator = new _ClassMemberValidator.forRename( +- searchEngine, astProvider, element, newName); +- return _validator.validate(); +- } +- +- @override +- Future checkInitialConditions() async { +- RefactoringStatus result = await super.checkInitialConditions(); +- if (element is MethodElement && (element as MethodElement).isOperator) { +- result.addFatalError('Cannot rename operator.'); +- } +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- if (element is FieldElement) { +- result.addStatus(validateFieldName(newName)); +- } +- if (element is MethodElement) { +- result.addStatus(validateMethodName(newName)); +- } +- return result; +- } +- +- @override +- Future fillChange() async { +- // update declarations +- for (Element renameElement in _validator.elements) { +- if (renameElement.isSynthetic && renameElement is FieldElement) { +- addDeclarationEdit(renameElement.getter); +- addDeclarationEdit(renameElement.setter); +- } else { +- addDeclarationEdit(renameElement); +- } +- } +- // update references +- addReferenceEdits(_validator.references); +- // potential matches +- List nameMatches = +- await searchEngine.searchMemberReferences(oldName); +- List nameRefs = getSourceReferences(nameMatches); +- for (SourceReference reference in nameRefs) { +- // ignore references from SDK and pub cache +- if (isElementInSdkOrPubCache(reference.element)) { +- continue; +- } +- // check the element being renamed is accessible +- { +- LibraryElement whereLibrary = reference.element.library; +- if (!element.isAccessibleIn(whereLibrary)) { +- continue; +- } +- } +- // add edit +- reference.addEdit(change, newName, id: _newPotentialId()); +- } +- } +- +- String _newPotentialId() { +- String id = potentialEditIds.length.toString(); +- potentialEditIds.add(id); +- return id; +- } +-} +- +-/** +- * Helper to check if the created or renamed [Element] will cause any conflicts. +- */ +-class _ClassMemberValidator { +- final SearchEngine searchEngine; +- final ResolvedUnitCache unitCache; +- final LibraryElement library; +- final Element element; +- final ClassElement elementClass; +- final ElementKind elementKind; +- final String name; +- final bool isRename; +- +- final RefactoringStatus result = new RefactoringStatus(); +- Set elements = new Set(); +- List references = []; +- +- _ClassMemberValidator.forCreate( +- this.searchEngine, AstProvider astProvider, this.elementClass, this.name) +- : unitCache = new ResolvedUnitCache(astProvider), +- isRename = false, +- library = null, +- element = null, +- elementKind = ElementKind.METHOD; +- +- _ClassMemberValidator.forRename( +- this.searchEngine, AstProvider astProvider, Element element, this.name) +- : unitCache = new ResolvedUnitCache(astProvider), +- isRename = true, +- library = element.library, +- element = element, +- elementClass = element.enclosingElement, +- elementKind = element.kind; +- +- Future validate() async { +- // check if there is a member with "newName" in the same ClassElement +- for (Element newNameMember in getChildren(elementClass, name)) { +- result.addError( +- format( +- "Class '{0}' already declares {1} with name '{2}'.", +- elementClass.displayName, +- getElementKindName(newNameMember), +- name), +- newLocation_fromElement(newNameMember)); +- } +- // do chained computations +- Set superClasses = getSuperClasses(elementClass); +- await _prepareReferences(); +- Set subClasses = +- await searchEngine.searchAllSubtypes(elementClass); +- // check shadowing of class names +- if (element != null) { +- for (Element element in elements) { +- ClassElement clazz = element.enclosingElement; +- if (clazz.name == name) { +- result.addError( +- format( +- "Renamed {0} has the same name as the declaring class '{1}'.", +- elementKind.displayName, +- name), +- newLocation_fromElement(element)); +- } +- } +- } else { +- if (elementClass.name == name) { +- result.addError( +- format( +- "Created {0} has the same name as the declaring class '{1}'.", +- elementKind.displayName, +- name), +- newLocation_fromElement(elementClass)); +- } +- } +- // usage of the renamed Element is shadowed by a local element +- { +- _MatchShadowedByLocal conflict = await _getShadowingLocalElement(); +- if (conflict != null) { +- LocalElement localElement = conflict.localElement; +- result.addError( +- format( +- "Usage of renamed {0} will be shadowed by {1} '{2}'.", +- elementKind.displayName, +- getElementKindName(localElement), +- localElement.displayName), +- newLocation_fromMatch(conflict.match)); +- } +- } +- // check shadowing in the hierarchy +- List declarations = +- await searchEngine.searchMemberDeclarations(name); +- for (SearchMatch declaration in declarations) { +- Element nameElement = getSyntheticAccessorVariable(declaration.element); +- Element nameClass = nameElement.enclosingElement; +- // the renamed Element shadows a member of a superclass +- if (superClasses.contains(nameClass)) { +- result.addError( +- format( +- isRename +- ? "Renamed {0} will shadow {1} '{2}'." +- : "Created {0} will shadow {1} '{2}'.", +- elementKind.displayName, +- getElementKindName(nameElement), +- getElementQualifiedName(nameElement)), +- newLocation_fromElement(nameElement)); +- } +- // the renamed Element is shadowed by a member of a subclass +- if (isRename && subClasses.contains(nameClass)) { +- result.addError( +- format( +- "Renamed {0} will be shadowed by {1} '{2}'.", +- elementKind.displayName, +- getElementKindName(nameElement), +- getElementQualifiedName(nameElement)), +- newLocation_fromElement(nameElement)); +- } +- } +- // visibility +- if (isRename) { +- _validateWillBeInvisible(); +- } +- // done +- return result; +- } +- +- Future<_MatchShadowedByLocal> _getShadowingLocalElement() async { +- var localElementMap = >{}; +- Future> getLocalElements(Element element) async { +- var unitElement = unitCache.getUnitElement(element); +- var localElements = localElementMap[unitElement]; +- if (localElements == null) { +- var unit = await unitCache.getUnit(unitElement); +- var collector = new _LocalElementsCollector(name); +- unit.accept(collector); +- localElements = collector.elements; +- localElementMap[unitElement] = localElements; +- } +- return localElements; +- } +- +- for (SearchMatch match in references) { +- // Qualified reference cannot be shadowed by local elements. +- if (match.isQualified) { +- continue; +- } +- // Check local elements that might shadow the reference. +- var localElements = await getLocalElements(match.element); +- for (LocalElement localElement in localElements) { +- if (localElement.visibleRange.intersects(match.sourceRange)) { +- return new _MatchShadowedByLocal(match, localElement); +- } +- } +- } +- return null; +- } +- +- /** +- * Fills [elements] with [Element]s to rename. +- */ +- Future _prepareElements() async { +- if (element is ClassMemberElement) { +- elements = await getHierarchyMembers(searchEngine, element); +- } else { +- elements = new Set.from([element]); +- } +- } +- +- /** +- * Fills [references] with all references to [elements]. +- */ +- Future _prepareReferences() async { +- if (!isRename) { +- return new Future.value(); +- } +- await _prepareElements(); +- await Future.forEach(elements, (Element element) async { +- List elementReferences = +- await searchEngine.searchReferences(element); +- references.addAll(elementReferences); +- }); +- } +- +- /** +- * Validates if any usage of [element] renamed to [name] will be invisible. +- */ +- void _validateWillBeInvisible() { +- if (!Identifier.isPrivateName(name)) { +- return; +- } +- for (SearchMatch reference in references) { +- Element refElement = reference.element; +- LibraryElement refLibrary = refElement.library; +- if (refLibrary != library) { +- String message = format("Renamed {0} will be invisible in '{1}'.", +- getElementKindName(element), getElementQualifiedName(refLibrary)); +- result.addError(message, newLocation_fromMatch(reference)); +- } +- } +- } +-} +- +-class _LocalElementsCollector extends GeneralizingAstVisitor { +- final String name; +- final List elements = []; +- +- _LocalElementsCollector(this.name); +- +- visitSimpleIdentifier(SimpleIdentifier node) { +- Element element = node.staticElement; +- if (element is LocalElement && element.name == name) { +- elements.add(element); +- } +- } +-} +- +-class _MatchShadowedByLocal { +- final SearchMatch match; +- final LocalElement localElement; +- +- _MatchShadowedByLocal(this.match, this.localElement); +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart +deleted file mode 100644 +index e079875f2f6..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart ++++ /dev/null +@@ -1,131 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * A [Refactoring] for renaming [ConstructorElement]s. +- */ +-class RenameConstructorRefactoringImpl extends RenameRefactoringImpl { +- final AstProvider astProvider; +- +- RenameConstructorRefactoringImpl( +- SearchEngine searchEngine, this.astProvider, ConstructorElement element) +- : super(searchEngine, element); +- +- @override +- ConstructorElement get element => super.element as ConstructorElement; +- +- @override +- String get refactoringName { +- return "Rename Constructor"; +- } +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- result.addStatus(validateConstructorName(newName)); +- if (newName != null) { +- _analyzePossibleConflicts(result); +- } +- return result; +- } +- +- @override +- Future fillChange() async { +- // prepare references +- List matches = await searchEngine.searchReferences(element); +- List references = getSourceReferences(matches); +- // append declaration +- if (element.isSynthetic) { +- await _replaceSynthetic(); +- } else { +- references.add(_createDeclarationReference()); +- } +- // update references +- String replacement = newName.isEmpty ? '' : '.$newName'; +- for (SourceReference reference in references) { +- reference.addEdit(change, replacement); +- } +- } +- +- void _analyzePossibleConflicts(RefactoringStatus result) { +- ClassElement parentClass = element.enclosingElement; +- // Check if the "newName" is the name of the enclosing class. +- if (parentClass.name == newName) { +- result.addError('The constructor should not have the same name ' +- 'as the name of the enclosing class.'); +- } +- // check if there are members with "newName" in the same ClassElement +- for (Element newNameMember in getChildren(parentClass, newName)) { +- String message = format( +- "Class '{0}' already declares {1} with name '{2}'.", +- parentClass.displayName, +- getElementKindName(newNameMember), +- newName); +- result.addError(message, newLocation_fromElement(newNameMember)); +- } +- } +- +- SourceReference _createDeclarationReference() { +- SourceRange sourceRange; +- int offset = element.periodOffset; +- if (offset != null) { +- sourceRange = range.startOffsetEndOffset(offset, element.nameEnd); +- } else { +- sourceRange = new SourceRange(element.nameEnd, 0); +- } +- return new SourceReference(new SearchMatchImpl( +- element.source.fullName, +- element.library.source, +- element.source, +- element.library, +- element, +- true, +- true, +- MatchKind.DECLARATION, +- sourceRange)); +- } +- +- Future _replaceSynthetic() async { +- ClassElement classElement = element.enclosingElement; +- AstNode name = await astProvider.getResolvedNameForElement(classElement); +- ClassDeclaration classNode = name.parent as ClassDeclaration; +- CorrectionUtils utils = new CorrectionUtils(classNode.parent); +- ClassMemberLocation location = +- utils.prepareNewConstructorLocation(classNode); +- doSourceChange_addElementEdit( +- change, +- classElement, +- new SourceEdit( +- location.offset, +- 0, +- location.prefix + +- '${classElement.name}.$newName();' + +- location.suffix)); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart +deleted file mode 100644 +index 2adca4d232f..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart ++++ /dev/null +@@ -1,137 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/analysis/results.dart'; +-import 'package:analyzer/dart/analysis/session.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +- +-/** +- * A [Refactoring] for renaming [ImportElement]s. +- */ +-class RenameImportRefactoringImpl extends RenameRefactoringImpl { +- final AstProvider astProvider; +- +- RenameImportRefactoringImpl( +- SearchEngine searchEngine, this.astProvider, ImportElement element) +- : super(searchEngine, element); +- +- @override +- ImportElement get element => super.element as ImportElement; +- +- @override +- String get refactoringName { +- return "Rename Import Prefix"; +- } +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- result.addStatus(validateImportPrefixName(newName)); +- return result; +- } +- +- @override +- Future fillChange() async { +- // update declaration +- { +- PrefixElement prefix = element.prefix; +- SourceEdit edit = null; +- if (newName.isEmpty) { +- ImportDirective node = await _findNode(); +- int uriEnd = node.uri.end; +- int prefixEnd = element.prefixOffset + prefix.nameLength; +- edit = newSourceEdit_range( +- range.startOffsetEndOffset(uriEnd, prefixEnd), ""); +- } else { +- if (prefix == null) { +- ImportDirective node = await _findNode(); +- int uriEnd = node.uri.end; +- edit = +- newSourceEdit_range(new SourceRange(uriEnd, 0), " as $newName"); +- } else { +- int offset = element.prefixOffset; +- int length = prefix.nameLength; +- edit = newSourceEdit_range(new SourceRange(offset, length), newName); +- } +- } +- if (edit != null) { +- doSourceChange_addElementEdit(change, element, edit); +- } +- } +- // update references +- List matches = await searchEngine.searchReferences(element); +- List references = getSourceReferences(matches); +- for (SourceReference reference in references) { +- if (newName.isEmpty) { +- reference.addEdit(change, ''); +- } else { +- SimpleIdentifier interpolationIdentifier = +- await _getInterpolationIdentifier(reference); +- if (interpolationIdentifier != null) { +- doSourceChange_addElementEdit( +- change, +- reference.element, +- new SourceEdit( +- interpolationIdentifier.offset, +- interpolationIdentifier.length, +- '{$newName.${interpolationIdentifier.name}}')); +- } else { +- reference.addEdit(change, '$newName.'); +- } +- } +- } +- } +- +- /** +- * Return the [ImportDirective] node that corresponds to the [element]. +- */ +- Future _findNode() async { +- LibraryElement library = element.library; +- CompilationUnit unit = await astProvider.getParsedUnitForElement(library); +- int index = library.imports.indexOf(element); +- return unit.directives.where((d) => d is ImportDirective).toList()[index]; +- } +- +- /** +- * If the given [reference] is before an interpolated [SimpleIdentifier] in +- * an [InterpolationExpression] without surrounding curly brackets, return it. +- * Otherwise return `null`. +- */ +- Future _getInterpolationIdentifier( +- SourceReference reference) async { +- Source source = reference.element.source; +- AnalysisSession currentSession = astProvider.driver.currentSession; +- ParseResult result = await currentSession.getParsedAst(source.fullName); +- CompilationUnit unit = result.unit; +- NodeLocator nodeLocator = new NodeLocator(reference.range.offset); +- AstNode node = nodeLocator.searchWithin(unit); +- if (node is SimpleIdentifier) { +- AstNode parent = node.parent; +- if (parent is InterpolationExpression && parent.rightBracket == null) { +- return node; +- } +- } +- return null; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart +deleted file mode 100644 +index 651fc7ac095..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart ++++ /dev/null +@@ -1,45 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-/** +- * A [Refactoring] for renaming [LabelElement]s. +- */ +-class RenameLabelRefactoringImpl extends RenameRefactoringImpl { +- RenameLabelRefactoringImpl(SearchEngine searchEngine, LabelElement element) +- : super(searchEngine, element); +- +- @override +- LabelElement get element => super.element as LabelElement; +- +- @override +- String get refactoringName => "Rename Label"; +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- result.addStatus(validateLabelName(newName)); +- return result; +- } +- +- @override +- Future fillChange() { +- addDeclarationEdit(element); +- return searchEngine.searchReferences(element).then(addReferenceEdits); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart +deleted file mode 100644 +index 1c72c892c77..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart ++++ /dev/null +@@ -1,48 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +- +-/** +- * A [Refactoring] for renaming [LibraryElement]s. +- */ +-class RenameLibraryRefactoringImpl extends RenameRefactoringImpl { +- RenameLibraryRefactoringImpl( +- SearchEngine searchEngine, LibraryElement element) +- : super(searchEngine, element); +- +- @override +- LibraryElement get element => super.element as LibraryElement; +- +- @override +- String get refactoringName { +- return "Rename Library"; +- } +- +- @override +- Future checkFinalConditions() { +- RefactoringStatus result = new RefactoringStatus(); +- return new Future.value(result); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- result.addStatus(validateLibraryName(newName)); +- return result; +- } +- +- @override +- Future fillChange() { +- addDeclarationEdit(element); +- return searchEngine.searchReferences(element).then(addReferenceEdits); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart +deleted file mode 100644 +index 85f86e4aa83..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart ++++ /dev/null +@@ -1,171 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- hide Element, ElementKind; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/utilities_dart.dart'; +- +-/** +- * A [Refactoring] for renaming [LocalElement]s. +- */ +-class RenameLocalRefactoringImpl extends RenameRefactoringImpl { +- final AstProvider astProvider; +- final ResolvedUnitCache unitCache; +- +- Set elements = new Set(); +- +- RenameLocalRefactoringImpl( +- SearchEngine searchEngine, this.astProvider, LocalElement element) +- : unitCache = new ResolvedUnitCache(astProvider), +- super(searchEngine, element); +- +- @override +- LocalElement get element => super.element as LocalElement; +- +- @override +- String get refactoringName { +- if (element is ParameterElement) { +- return "Rename Parameter"; +- } +- if (element is FunctionElement) { +- return "Rename Local Function"; +- } +- return "Rename Local Variable"; +- } +- +- @override +- Future checkFinalConditions() async { +- RefactoringStatus result = new RefactoringStatus(); +- await _prepareElements(); +- for (LocalElement element in elements) { +- CompilationUnit unit = await unitCache.getUnit(element); +- if (unit != null) { +- unit.accept(new _ConflictValidatorVisitor(result, newName, element)); +- } +- } +- return result; +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- if (element is LocalVariableElement) { +- result.addStatus(validateVariableName(newName)); +- } else if (element is ParameterElement) { +- result.addStatus(validateParameterName(newName)); +- } else if (element is FunctionElement) { +- result.addStatus(validateFunctionName(newName)); +- } +- return result; +- } +- +- @override +- Future fillChange() async { +- for (Element element in elements) { +- addDeclarationEdit(element); +- await searchEngine.searchReferences(element).then(addReferenceEdits); +- } +- } +- +- /** +- * Fills [elements] with [Element]s to rename. +- */ +- Future _prepareElements() async { +- Element enclosing = element.enclosingElement; +- if (enclosing is MethodElement && +- element is ParameterElement && +- (element as ParameterElement).parameterKind == ParameterKind.NAMED) { +- // prepare hierarchy methods +- Set methods = +- await getHierarchyMembers(searchEngine, enclosing); +- // add named parameter from each method +- for (ClassMemberElement method in methods) { +- if (method is MethodElement) { +- for (ParameterElement parameter in method.parameters) { +- if (parameter.parameterKind == ParameterKind.NAMED && +- parameter.name == element.name) { +- elements.add(parameter); +- } +- } +- } +- } +- } else { +- elements = new Set.from([element]); +- } +- } +-} +- +-class _ConflictValidatorVisitor extends RecursiveAstVisitor { +- final RefactoringStatus result; +- final String newName; +- final LocalElement target; +- final Set conflictingLocals = new Set(); +- +- _ConflictValidatorVisitor(this.result, this.newName, this.target); +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- Element nodeElement = node.bestElement; +- if (nodeElement != null && nodeElement.name == newName) { +- // Duplicate declaration. +- if (node.inDeclarationContext() && _isVisibleWithTarget(nodeElement)) { +- conflictingLocals.add(nodeElement); +- String nodeKind = nodeElement.kind.displayName; +- String message = "Duplicate $nodeKind '$newName'."; +- result.addError(message, newLocation_fromElement(nodeElement)); +- return; +- } +- if (conflictingLocals.contains(nodeElement)) { +- return; +- } +- // Shadowing by the target element. +- SourceRange targetRange = target.visibleRange; +- if (targetRange != null && +- targetRange.contains(node.offset) && +- !node.isQualified && +- !_isNamedExpressionName(node)) { +- nodeElement = getSyntheticAccessorVariable(nodeElement); +- String nodeKind = nodeElement.kind.displayName; +- String nodeName = getElementQualifiedName(nodeElement); +- String nameElementSourceName = nodeElement.source.shortName; +- String refKind = target.kind.displayName; +- String message = 'Usage of $nodeKind "$nodeName" declared in ' +- '"$nameElementSourceName" will be shadowed by renamed $refKind.'; +- result.addError(message, newLocation_fromNode(node)); +- } +- } +- } +- +- /** +- * Returns whether [element] and [target] are visible together. +- */ +- bool _isVisibleWithTarget(Element element) { +- if (element is LocalElement) { +- SourceRange targetRange = target.visibleRange; +- SourceRange elementRange = element.visibleRange; +- return targetRange != null && +- elementRange != null && +- elementRange.intersects(targetRange); +- } +- return false; +- } +- +- static bool _isNamedExpressionName(SimpleIdentifier node) { +- return node.parent is Label && node.parent.parent is NamedExpression; +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart +deleted file mode 100644 +index fea2831d608..00000000000 +--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart ++++ /dev/null +@@ -1,263 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/protocol_server.dart' +- show newLocation_fromElement, newLocation_fromMatch; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/refactoring/rename.dart'; +-import 'package:analysis_server/src/services/search/element_visitors.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart' show Identifier; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/java_core.dart'; +- +-/** +- * Checks if creating a top-level function with the given [name] in [library] +- * will cause any conflicts. +- */ +-Future validateCreateFunction( +- SearchEngine searchEngine, LibraryElement library, String name) { +- return new _RenameUnitMemberValidator.forCreate( +- searchEngine, library, ElementKind.FUNCTION, name) +- .validate(); +-} +- +-/** +- * Checks if creating a top-level function with the given [name] in [element] +- * will cause any conflicts. +- */ +-Future validateRenameTopLevel( +- SearchEngine searchEngine, Element element, String name) { +- return new _RenameUnitMemberValidator.forRename(searchEngine, element, name) +- .validate(); +-} +- +-/** +- * A [Refactoring] for renaming compilation unit member [Element]s. +- */ +-class RenameUnitMemberRefactoringImpl extends RenameRefactoringImpl { +- RenameUnitMemberRefactoringImpl(SearchEngine searchEngine, Element element) +- : super(searchEngine, element); +- +- @override +- String get refactoringName { +- if (element is FunctionElement) { +- return "Rename Top-Level Function"; +- } +- if (element is FunctionTypeAliasElement) { +- return "Rename Function Type Alias"; +- } +- if (element is TopLevelVariableElement) { +- return "Rename Top-Level Variable"; +- } +- return "Rename Class"; +- } +- +- @override +- Future checkFinalConditions() { +- return validateRenameTopLevel(searchEngine, element, newName); +- } +- +- @override +- RefactoringStatus checkNewName() { +- RefactoringStatus result = super.checkNewName(); +- if (element is TopLevelVariableElement) { +- result.addStatus(validateVariableName(newName)); +- } +- if (element is FunctionElement) { +- result.addStatus(validateFunctionName(newName)); +- } +- if (element is FunctionTypeAliasElement) { +- result.addStatus(validateFunctionTypeAliasName(newName)); +- } +- if (element is ClassElement) { +- result.addStatus(validateClassName(newName)); +- } +- return result; +- } +- +- @override +- Future fillChange() { +- // prepare elements +- List elements = []; +- if (element is PropertyInducingElement && element.isSynthetic) { +- PropertyInducingElement property = element as PropertyInducingElement; +- PropertyAccessorElement getter = property.getter; +- PropertyAccessorElement setter = property.setter; +- if (getter != null) { +- elements.add(getter); +- } +- if (setter != null) { +- elements.add(setter); +- } +- } else { +- elements.add(element); +- } +- // update each element +- return Future.forEach(elements, (Element element) { +- addDeclarationEdit(element); +- return searchEngine.searchReferences(element).then(addReferenceEdits); +- }); +- } +-} +- +-/** +- * Helper to check if the created or renamed [Element] will cause any conflicts. +- */ +-class _RenameUnitMemberValidator { +- final SearchEngine searchEngine; +- LibraryElement library; +- Element element; +- ElementKind elementKind; +- final String name; +- final bool isRename; +- List references = []; +- +- final RefactoringStatus result = new RefactoringStatus(); +- +- _RenameUnitMemberValidator.forCreate( +- this.searchEngine, this.library, this.elementKind, this.name) +- : isRename = false; +- +- _RenameUnitMemberValidator.forRename( +- this.searchEngine, this.element, this.name) +- : isRename = true { +- library = element.library; +- elementKind = element.kind; +- } +- +- Future validate() async { +- _validateWillConflict(); +- if (isRename) { +- references = await searchEngine.searchReferences(element); +- _validateWillBeInvisible(); +- _validateWillBeShadowed(); +- } +- await _validateWillShadow(); +- return result; +- } +- +- /** +- * Returns `true` if [element] is visible at the given [SearchMatch]. +- */ +- bool _isVisibleAt(Element element, SearchMatch at) { +- LibraryElement atLibrary = at.element.library; +- // may be the same library +- if (library == atLibrary) { +- return true; +- } +- // check imports +- for (ImportElement importElement in atLibrary.imports) { +- // ignore if imported with prefix +- if (importElement.prefix != null) { +- continue; +- } +- // check imported elements +- if (getImportNamespace(importElement).containsValue(element)) { +- return true; +- } +- } +- // no, it is not visible +- return false; +- } +- +- /** +- * Validates if any usage of [element] renamed to [name] will be invisible. +- */ +- void _validateWillBeInvisible() { +- if (!Identifier.isPrivateName(name)) { +- return; +- } +- for (SearchMatch reference in references) { +- Element refElement = reference.element; +- LibraryElement refLibrary = refElement.library; +- if (refLibrary != library) { +- String message = format("Renamed {0} will be invisible in '{1}'.", +- getElementKindName(element), getElementQualifiedName(refLibrary)); +- result.addError(message, newLocation_fromMatch(reference)); +- } +- } +- } +- +- /** +- * Validates if any usage of [element] renamed to [name] will be shadowed. +- */ +- void _validateWillBeShadowed() { +- for (SearchMatch reference in references) { +- Element refElement = reference.element; +- ClassElement refClass = refElement.getAncestor((e) => e is ClassElement); +- if (refClass != null) { +- visitChildren(refClass, (shadow) { +- if (hasDisplayName(shadow, name)) { +- String message = format( +- "Reference to renamed {0} will be shadowed by {1} '{2}'.", +- getElementKindName(element), +- getElementKindName(shadow), +- getElementQualifiedName(shadow)); +- result.addError(message, newLocation_fromElement(shadow)); +- } +- }); +- } +- } +- } +- +- /** +- * Validates if [element] renamed to [name] will conflict with another +- * top-level [Element] in the same library. +- */ +- void _validateWillConflict() { +- visitLibraryTopLevelElements(library, (element) { +- if (hasDisplayName(element, name)) { +- String message = format("Library already declares {0} with name '{1}'.", +- getElementKindName(element), name); +- result.addError(message, newLocation_fromElement(element)); +- } +- }); +- } +- +- /** +- * Validates if renamed [element] will shadow any [Element] named [name]. +- */ +- Future _validateWillShadow() async { +- List declarations = +- await searchEngine.searchMemberDeclarations(name); +- for (SearchMatch declaration in declarations) { +- Element member = declaration.element; +- ClassElement declaringClass = member.enclosingElement; +- List memberReferences = +- await searchEngine.searchReferences(member); +- for (SearchMatch memberReference in memberReferences) { +- Element refElement = memberReference.element; +- // cannot be shadowed if qualified +- if (memberReference.isQualified) { +- continue; +- } +- // cannot be shadowed if declared in the same class as reference +- ClassElement refClass = +- refElement.getAncestor((e) => e is ClassElement); +- if (refClass == declaringClass) { +- continue; +- } +- // ignore if not visible +- if (!_isVisibleAt(element, memberReference)) { +- continue; +- } +- // OK, reference will be shadowed be the element being renamed +- String message = format( +- isRename +- ? "Renamed {0} will shadow {1} '{2}'." +- : "Created {0} will shadow {1} '{2}'.", +- elementKind.displayName, +- getElementKindName(member), +- getElementQualifiedName(member)); +- result.addError(message, newLocation_fromMatch(memberReference)); +- } +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/search/element_visitors.dart b/pkg/analysis_server/lib/src/services/search/element_visitors.dart +deleted file mode 100644 +index 3297709905b..00000000000 +--- a/pkg/analysis_server/lib/src/services/search/element_visitors.dart ++++ /dev/null +@@ -1,63 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +- +-/** +- * Uses [processor] to visit all of the children of [element]. +- * If [processor] returns `true`, then children of a child are visited too. +- */ +-void visitChildren(Element element, ElementProcessor processor) { +- element.visitChildren(new _ElementVisitorAdapter(processor)); +-} +- +-/** +- * Uses [processor] to visit all of the top-level elements of [library]. +- */ +-void visitLibraryTopLevelElements( +- LibraryElement library, ElementProcessor processor) { +- library.visitChildren(new _TopLevelElementsVisitor(processor)); +-} +- +-/** +- * An [Element] processor function type. +- * If `true` is returned, children of [element] will be visited. +- */ +-typedef bool ElementProcessor(Element element); +- +-/** +- * A [GeneralizingElementVisitor] adapter for [ElementProcessor]. +- */ +-class _ElementVisitorAdapter extends GeneralizingElementVisitor { +- final ElementProcessor processor; +- +- _ElementVisitorAdapter(this.processor); +- +- @override +- void visitElement(Element element) { +- bool visitChildren = processor(element); +- if (visitChildren == true) { +- element.visitChildren(this); +- } +- } +-} +- +-/** +- * A [GeneralizingElementVisitor] for visiting top-level elements. +- */ +-class _TopLevelElementsVisitor extends GeneralizingElementVisitor { +- final ElementProcessor processor; +- +- _TopLevelElementsVisitor(this.processor); +- +- @override +- void visitElement(Element element) { +- if (element is CompilationUnitElement) { +- element.visitChildren(this); +- } else { +- processor(element); +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart +deleted file mode 100644 +index 93bb9a8166c..00000000000 +--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart ++++ /dev/null +@@ -1,162 +0,0 @@ +-// Copyright (c) 2014, 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:analysis_server/src/services/search/element_visitors.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +- +-/** +- * Returns direct children of [parent]. +- */ +-List getChildren(Element parent, [String name]) { +- List children = []; +- visitChildren(parent, (Element element) { +- if (name == null || element.displayName == name) { +- children.add(element); +- } +- }); +- return children; +-} +- +-/** +- * Returns direct non-synthetic children of the given [ClassElement]. +- * +- * Includes: fields, accessors and methods. +- * Excludes: constructors and synthetic elements. +- */ +-List getClassMembers(ClassElement clazz, [String name]) { +- List members = []; +- visitChildren(clazz, (Element element) { +- if (element.isSynthetic) { +- return false; +- } +- if (element is ConstructorElement) { +- return false; +- } +- if (name != null && element.displayName != name) { +- return false; +- } +- if (element is ExecutableElement) { +- members.add(element); +- } +- if (element is FieldElement) { +- members.add(element); +- } +- return false; +- }); +- return members; +-} +- +-/** +- * Returns a [Set] with direct subclasses of [seed]. +- */ +-Future> getDirectSubClasses( +- SearchEngine searchEngine, ClassElement seed) async { +- List matches = await searchEngine.searchSubtypes(seed); +- return matches.map((match) => match.element).toSet(); +-} +- +-/** +- * @return all implementations of the given {@link ClassMemberElement} is its superclasses and +- * their subclasses. +- */ +-Future> getHierarchyMembers( +- SearchEngine searchEngine, ClassMemberElement member) async { +- Set result = new HashSet(); +- // static elements +- if (member.isStatic || member is ConstructorElement) { +- result.add(member); +- return new Future.value(result); +- } +- // method, field, etc +- String name = member.displayName; +- ClassElement memberClass = member.enclosingElement; +- Set searchClasses = getSuperClasses(memberClass); +- searchClasses.add(memberClass); +- for (ClassElement superClass in searchClasses) { +- // ignore if super- class does not declare member +- if (getClassMembers(superClass, name).isEmpty) { +- continue; +- } +- // check all sub- classes +- Set subClasses = +- await searchEngine.searchAllSubtypes(superClass); +- subClasses.add(superClass); +- for (ClassElement subClass in subClasses) { +- List subClassMembers = getChildren(subClass, name); +- for (Element member in subClassMembers) { +- if (member is ClassMemberElement) { +- result.add(member); +- } +- } +- } +- } +- return result; +-} +- +-/** +- * Returns non-synthetic members of the given [ClassElement] and its super +- * classes. +- * +- * Includes: fields, accessors and methods. +- * Excludes: constructors and synthetic elements. +- */ +-List getMembers(ClassElement clazz) { +- List members = []; +- members.addAll(getClassMembers(clazz)); +- Set superClasses = getSuperClasses(clazz); +- for (ClassElement superClass in superClasses) { +- members.addAll(getClassMembers(superClass)); +- } +- return members; +-} +- +-/** +- * Returns a [Set] with all direct and indirect superclasses of [seed]. +- */ +-Set getSuperClasses(ClassElement seed) { +- Set result = new HashSet(); +- // prepare queue +- List queue = new List(); +- queue.add(seed); +- // process queue +- while (!queue.isEmpty) { +- ClassElement current = queue.removeLast(); +- // add if not checked already +- if (!result.add(current)) { +- continue; +- } +- // append supertype +- { +- InterfaceType superType = current.supertype; +- if (superType != null) { +- queue.add(superType.element); +- } +- } +- // append interfaces +- for (InterfaceType interface in current.interfaces) { +- queue.add(interface.element); +- } +- } +- // we don't need "seed" itself +- result.remove(seed); +- return result; +-} +- +-/** +- * If the given [element] is a synthetic [PropertyAccessorElement] returns +- * its variable, otherwise returns [element]. +- */ +-Element getSyntheticAccessorVariable(Element element) { +- if (element is PropertyAccessorElement) { +- if (element.isSynthetic) { +- return element.variable; +- } +- } +- return element; +-} +diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart +deleted file mode 100644 +index df6e31c4d72..00000000000 +--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart ++++ /dev/null +@@ -1,171 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * Instances of the enum [MatchKind] represent the kind of reference that was +- * found when a match represents a reference to an element. +- */ +-class MatchKind { +- /** +- * A declaration of an element. +- */ +- static const MatchKind DECLARATION = const MatchKind('DECLARATION'); +- +- /** +- * A reference to an element in which it is being read. +- */ +- static const MatchKind READ = const MatchKind('READ'); +- +- /** +- * A reference to an element in which it is being both read and written. +- */ +- static const MatchKind READ_WRITE = const MatchKind('READ_WRITE'); +- +- /** +- * A reference to an element in which it is being written. +- */ +- static const MatchKind WRITE = const MatchKind('WRITE'); +- +- /** +- * A reference to an element in which it is being invoked. +- */ +- static const MatchKind INVOCATION = const MatchKind('INVOCATION'); +- +- /** +- * A reference to an element in which it is referenced. +- */ +- static const MatchKind REFERENCE = const MatchKind('REFERENCE'); +- +- final String name; +- +- const MatchKind(this.name); +- +- @override +- String toString() => name; +-} +- +-/** +- * The interface [SearchEngine] defines the behavior of objects that can be used +- * to search for various pieces of information. +- */ +-abstract class SearchEngine { +- /** +- * If the [type] has subtypes, return the set of names of members which these +- * subtypes declare, possibly empty. If the [type] does not have subtypes, +- * return `null`. +- */ +- Future> membersOfSubtypes(ClassElement type); +- +- /** +- * Returns all subtypes of the given [type]. +- * +- * [type] - the [ClassElement] being subtyped by the found matches. +- */ +- Future> searchAllSubtypes(ClassElement type); +- +- /** +- * Returns declarations of class members with the given name. +- * +- * [name] - the name being declared by the found matches. +- */ +- Future> searchMemberDeclarations(String name); +- +- /** +- * Returns all resolved and unresolved qualified references to the class +- * members with given [name]. +- * +- * [name] - the name being referenced by the found matches. +- */ +- Future> searchMemberReferences(String name); +- +- /** +- * Returns references to the given [Element]. +- * +- * [element] - the [Element] being referenced by the found matches. +- */ +- Future> searchReferences(Element element); +- +- /** +- * Returns direct subtypes of the given [type]. +- * +- * [type] - the [ClassElement] being subtyped by the found matches. +- */ +- Future> searchSubtypes(ClassElement type); +- +- /** +- * Returns all the top-level declarations matching the given pattern. +- * +- * [pattern] the regular expression used to match the names of the +- * declarations to be found. +- */ +- Future> searchTopLevelDeclarations(String pattern); +-} +- +-/** +- * Instances of the class [SearchMatch] represent a match found by +- * [SearchEngine]. +- */ +-abstract class SearchMatch { +- /** +- * Return the [Element] containing the match. Can return `null` if the unit +- * does not exist, or its element was invalidated, or the element cannot be +- * found, etc. +- */ +- Element get element; +- +- /** +- * The absolute path of the file containing the match. +- */ +- String get file; +- +- /** +- * Is `true` if field or method access is done using qualifier. +- */ +- bool get isQualified; +- +- /** +- * Is `true` if the match is a resolved reference to some [Element]. +- */ +- bool get isResolved; +- +- /** +- * The kind of the match. +- */ +- MatchKind get kind; +- +- /** +- * Return the [LibraryElement] for the [libraryUri] in the [context]. +- */ +- LibraryElement get libraryElement; +- +- /** +- * The library [Source] of the reference. +- */ +- Source get librarySource; +- +- /** +- * The source range that was matched. +- */ +- SourceRange get sourceRange; +- +- /** +- * The unit [Source] of the reference. +- */ +- Source get unitSource; +- +- /** +- * Return elements of [matches] which has not-null elements. +- * +- * When [SearchMatch.element] is not `null` we cache its value, so it cannot +- * become `null` later. +- */ +- static List withNotNullElement(List matches) { +- return matches.where((match) => match.element != null).toList(); +- } +-} +diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart +deleted file mode 100644 +index 8e1519ed165..00000000000 +--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart ++++ /dev/null +@@ -1,238 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +- +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/search.dart'; +-import 'package:analyzer/src/generated/source.dart' show Source, SourceRange; +-import 'package:meta/meta.dart'; +- +-/** +- * A [SearchEngine] implementation. +- */ +-class SearchEngineImpl implements SearchEngine { +- final Iterable _drivers; +- +- SearchEngineImpl(this._drivers); +- +- @override +- Future> membersOfSubtypes(ClassElement type) async { +- List drivers = _drivers.toList(); +- +- String libraryUriStr = type.librarySource.uri.toString(); +- bool hasSubtypes = false; +- Set visitedIds = new Set(); +- Set members = new Set(); +- +- Future addMembers(ClassElement type, SubtypeResult subtype) async { +- if (subtype != null && !visitedIds.add(subtype.id)) { +- return; +- } +- for (AnalysisDriver driver in drivers) { +- List subtypes = +- await driver.search.subtypes(type: type, subtype: subtype); +- for (SubtypeResult subtype in subtypes) { +- hasSubtypes = true; +- members.addAll(subtype.libraryUri == libraryUriStr +- ? subtype.members +- : subtype.members.where((name) => !name.startsWith('_'))); +- await addMembers(null, subtype); +- } +- } +- } +- +- await addMembers(type, null); +- +- if (!hasSubtypes) { +- return null; +- } +- return members; +- } +- +- @override +- Future> searchAllSubtypes(ClassElement type) async { +- Set allSubtypes = new Set(); +- +- Future addSubtypes(ClassElement type) async { +- List directResults = await _searchDirectSubtypes(type); +- for (SearchResult directResult in directResults) { +- var directSubtype = directResult.enclosingElement as ClassElement; +- if (allSubtypes.add(directSubtype)) { +- await addSubtypes(directSubtype); +- } +- } +- } +- +- await addSubtypes(type); +- return allSubtypes; +- } +- +- @override +- Future> searchMemberDeclarations(String name) async { +- List allDeclarations = []; +- List drivers = _drivers.toList(); +- for (AnalysisDriver driver in drivers) { +- List elements = await driver.search.classMembers(name); +- allDeclarations.addAll(elements.map(SearchMatchImpl.forElement)); +- } +- return allDeclarations; +- } +- +- @override +- Future> searchMemberReferences(String name) async { +- List allResults = []; +- List drivers = _drivers.toList(); +- for (AnalysisDriver driver in drivers) { +- List results = +- await driver.search.unresolvedMemberReferences(name); +- allResults.addAll(results); +- } +- return allResults.map(SearchMatchImpl.forSearchResult).toList(); +- } +- +- @override +- Future> searchReferences(Element element) async { +- List allResults = []; +- List drivers = _drivers.toList(); +- for (AnalysisDriver driver in drivers) { +- List results = await driver.search.references(element); +- allResults.addAll(results); +- } +- return allResults.map(SearchMatchImpl.forSearchResult).toList(); +- } +- +- @override +- Future> searchSubtypes(ClassElement type) async { +- List results = await _searchDirectSubtypes(type); +- return results.map(SearchMatchImpl.forSearchResult).toList(); +- } +- +- @override +- Future> searchTopLevelDeclarations(String pattern) async { +- List allDeclarations = []; +- RegExp regExp = new RegExp(pattern); +- List drivers = _drivers.toList(); +- for (AnalysisDriver driver in drivers) { +- List elements = await driver.search.topLevelElements(regExp); +- allDeclarations.addAll(elements.map(SearchMatchImpl.forElement)); +- } +- return allDeclarations; +- } +- +- Future> _searchDirectSubtypes(ClassElement type) async { +- List allResults = []; +- List drivers = _drivers.toList(); +- for (AnalysisDriver driver in drivers) { +- List results = await driver.search.subTypes(type); +- allResults.addAll(results); +- } +- return allResults; +- } +-} +- +-@visibleForTesting +-class SearchMatchImpl implements SearchMatch { +- @override +- final String file; +- +- @override +- final Source librarySource; +- +- @override +- final Source unitSource; +- +- @override +- final LibraryElement libraryElement; +- +- @override +- final Element element; +- +- @override +- final bool isResolved; +- +- @override +- final bool isQualified; +- +- @override +- final MatchKind kind; +- +- @override +- final SourceRange sourceRange; +- +- SearchMatchImpl( +- this.file, +- this.librarySource, +- this.unitSource, +- this.libraryElement, +- this.element, +- this.isResolved, +- this.isQualified, +- this.kind, +- this.sourceRange); +- +- @override +- String toString() { +- StringBuffer buffer = new StringBuffer(); +- buffer.write("SearchMatch(kind="); +- buffer.write(kind); +- buffer.write(", libraryUri="); +- buffer.write(librarySource.uri); +- buffer.write(", unitUri="); +- buffer.write(unitSource.uri); +- buffer.write(", range="); +- buffer.write(sourceRange); +- buffer.write(", isResolved="); +- buffer.write(isResolved); +- buffer.write(", isQualified="); +- buffer.write(isQualified); +- buffer.write(")"); +- return buffer.toString(); +- } +- +- static SearchMatchImpl forElement(Element element) { +- return new SearchMatchImpl( +- element.source.fullName, +- element.librarySource, +- element.source, +- element.library, +- element, +- true, +- true, +- MatchKind.DECLARATION, +- new SourceRange(element.nameOffset, element.nameLength)); +- } +- +- static SearchMatchImpl forSearchResult(SearchResult result) { +- Element enclosingElement = result.enclosingElement; +- return new SearchMatchImpl( +- enclosingElement.source.fullName, +- enclosingElement.librarySource, +- enclosingElement.source, +- enclosingElement.library, +- enclosingElement, +- result.isResolved, +- result.isQualified, +- toMatchKind(result.kind), +- new SourceRange(result.offset, result.length)); +- } +- +- static MatchKind toMatchKind(SearchResultKind kind) { +- if (kind == SearchResultKind.READ) { +- return MatchKind.READ; +- } +- if (kind == SearchResultKind.READ_WRITE) { +- return MatchKind.READ_WRITE; +- } +- if (kind == SearchResultKind.WRITE) { +- return MatchKind.WRITE; +- } +- if (kind == SearchResultKind.INVOCATION) { +- return MatchKind.INVOCATION; +- } +- return MatchKind.REFERENCE; +- } +-} +diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart +deleted file mode 100644 +index 4676e0263ee..00000000000 +--- a/pkg/analysis_server/lib/src/socket_server.dart ++++ /dev/null +@@ -1,90 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/channel/channel.dart'; +-import 'package:analysis_server/src/server/diagnostic_server.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/plugin/resolver_provider.dart'; +-import 'package:analyzer/source/pub_package_map_provider.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +- +-/** +- * Instances of the class [SocketServer] implement the common parts of +- * http-based and stdio-based analysis servers. The primary responsibility of +- * the SocketServer is to manage the lifetime of the AnalysisServer and to +- * encode and decode the JSON messages exchanged with the client. +- */ +-class SocketServer { +- final AnalysisServerOptions analysisServerOptions; +- +- /** +- * The function used to create a new SDK using the default SDK. +- */ +- final DartSdkManager sdkManager; +- +- final DartSdk defaultSdk; +- final InstrumentationService instrumentationService; +- final DiagnosticServer diagnosticServer; +- final ResolverProvider fileResolverProvider; +- final ResolverProvider packageResolverProvider; +- +- /** +- * The analysis server that was created when a client established a +- * connection, or `null` if no such connection has yet been established. +- */ +- AnalysisServer analysisServer; +- +- SocketServer( +- this.analysisServerOptions, +- this.sdkManager, +- this.defaultSdk, +- this.instrumentationService, +- this.diagnosticServer, +- this.fileResolverProvider, +- this.packageResolverProvider); +- +- /** +- * Create an analysis server which will communicate with the client using the +- * given serverChannel. +- */ +- void createAnalysisServer(ServerCommunicationChannel serverChannel) { +- if (analysisServer != null) { +- RequestError error = new RequestError( +- RequestErrorCode.SERVER_ALREADY_STARTED, "Server already started"); +- serverChannel.sendResponse(new Response('', error: error)); +- serverChannel.listen((Request request) { +- serverChannel.sendResponse(new Response(request.id, error: error)); +- }); +- return; +- } +- +- PhysicalResourceProvider resourceProvider; +- if (analysisServerOptions.fileReadMode == 'as-is') { +- resourceProvider = new PhysicalResourceProvider(null, +- stateLocation: analysisServerOptions.cacheFolder); +- } else if (analysisServerOptions.fileReadMode == 'normalize-eol-always') { +- resourceProvider = new PhysicalResourceProvider( +- PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS, +- stateLocation: analysisServerOptions.cacheFolder); +- } else { +- throw new Exception( +- 'File read mode was set to the unknown mode: $analysisServerOptions.fileReadMode'); +- } +- +- analysisServer = new AnalysisServer( +- serverChannel, +- resourceProvider, +- new PubPackageMapProvider(resourceProvider, defaultSdk), +- analysisServerOptions, +- sdkManager, +- instrumentationService, +- diagnosticServer: diagnosticServer, +- fileResolverProvider: fileResolverProvider, +- packageResolverProvider: packageResolverProvider); +- } +-} +diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart +deleted file mode 100644 +index 908cb67c594..00000000000 +--- a/pkg/analysis_server/lib/src/status/ast_writer.dart ++++ /dev/null +@@ -1,243 +0,0 @@ +-// Copyright (c) 2015, 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:analysis_server/src/status/tree_writer.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/src/dart/ast/ast.dart'; +- +-/** +- * A visitor that will produce an HTML representation of an AST structure. +- */ +-class AstWriter extends UnifyingAstVisitor with TreeWriter { +- /** +- * Initialize a newly created element writer to write the HTML representation +- * of visited nodes on the given [buffer]. +- */ +- AstWriter(StringBuffer buffer) { +- this.buffer = buffer; +- } +- +- @override +- void visitNode(AstNode node) { +- _writeNode(node); +- writeProperties(_computeProperties(node)); +- indentLevel++; +- try { +- node.visitChildren(this); +- } finally { +- indentLevel--; +- } +- } +- +- /** +- * Write a representation of the properties of the given [node] to the buffer. +- */ +- Map _computeProperties(AstNode node) { +- Map properties = new HashMap(); +- +- properties['name'] = _getName(node); +- if (node is ArgumentListImpl) { +- properties['static parameter types'] = node.correspondingStaticParameters; +- properties['propagated parameter types'] = +- node.correspondingPropagatedParameters; +- } else if (node is Annotation) { +- properties['element'] = node.element; +- properties['element annotation'] = node.elementAnnotation; +- } else if (node is BinaryExpression) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated type'] = node.propagatedType; +- } else if (node is ClassDeclaration) { +- properties['element'] = node.element; +- properties['abstract keyword'] = node.abstractKeyword; +- } else if (node is ClassTypeAlias) { +- properties['element'] = node.element; +- properties['abstract keyword'] = node.abstractKeyword; +- } else if (node is CompilationUnit) { +- properties['element'] = node.element; +- } else if (node is Configuration) { +- properties['uriSource'] = node.uriSource; +- } else if (node is ConstructorName) { +- properties['static element'] = node.staticElement; +- } else if (node is DeclaredIdentifier) { +- properties['element'] = node.element; +- properties['keyword'] = node.keyword; +- } else if (node is ExportDirective) { +- properties['element'] = node.element; +- properties['selectedSource'] = node.selectedSource; +- properties['uriSource'] = node.uriSource; +- } else if (node is FieldDeclaration) { +- properties['static keyword'] = node.staticKeyword; +- } else if (node is FormalParameter) { +- properties['element'] = node.element; +- properties['kind'] = node.kind; +- } else if (node is FunctionDeclaration) { +- properties['element'] = node.element; +- properties['external keyword'] = node.externalKeyword; +- properties['property keyword'] = node.propertyKeyword; +- } else if (node is FunctionExpressionInvocation) { +- properties['static element'] = node.staticElement; +- properties['static invoke type'] = node.staticInvokeType; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated invoke type'] = node.propagatedInvokeType; +- properties['propagated type'] = node.propagatedType; +- } else if (node is GenericFunctionType) { +- properties['type'] = node.type; +- } else if (node is ImportDirective) { +- properties['element'] = node.element; +- properties['selectedSource'] = node.selectedSource; +- properties['uriSource'] = node.uriSource; +- } else if (node is IndexExpression) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated type'] = node.propagatedType; +- } else if (node is InstanceCreationExpression) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated type'] = node.propagatedType; +- } else if (node is LibraryDirective) { +- properties['element'] = node.element; +- } else if (node is MethodDeclaration) { +- properties['element'] = node.element; +- properties['external keyword'] = node.externalKeyword; +- properties['modifier keyword'] = node.modifierKeyword; +- properties['operator keyword'] = node.operatorKeyword; +- properties['property keyword'] = node.propertyKeyword; +- } else if (node is MethodInvocation) { +- properties['static invoke type'] = node.staticInvokeType; +- properties['static type'] = node.staticType; +- properties['propagated invoke type'] = node.propagatedInvokeType; +- properties['propagated type'] = node.propagatedType; +- } else if (node is PartDirective) { +- properties['element'] = node.element; +- properties['uriSource'] = node.uriSource; +- } else if (node is PartOfDirective) { +- properties['element'] = node.element; +- } else if (node is PostfixExpression) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated type'] = node.propagatedType; +- } else if (node is PrefixExpression) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated type'] = node.propagatedType; +- } else if (node is RedirectingConstructorInvocation) { +- properties['static element'] = node.staticElement; +- } else if (node is SimpleIdentifier) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated type'] = node.propagatedType; +- } else if (node is SimpleStringLiteral) { +- properties['value'] = node.value; +- } else if (node is SuperConstructorInvocation) { +- properties['static element'] = node.staticElement; +- } else if (node is TypeAnnotation) { +- properties['type'] = node.type; +- } else if (node is VariableDeclarationList) { +- properties['keyword'] = node.keyword; +- } else if (node is Declaration) { +- properties['element'] = node.element; +- } else if (node is Expression) { +- properties['static type'] = node.staticType; +- properties['propagated type'] = node.propagatedType; +- } else if (node is FunctionBody) { +- properties['isAsynchronous'] = node.isAsynchronous; +- properties['isGenerator'] = node.isGenerator; +- } else if (node is Identifier) { +- properties['static element'] = node.staticElement; +- properties['static type'] = node.staticType; +- properties['propagated element'] = node.propagatedElement; +- properties['propagated type'] = node.propagatedType; +- } +- +- return properties; +- } +- +- /** +- * Return the name of the given [node], or `null` if the given node is not a +- * declaration. +- */ +- String _getName(AstNode node) { +- if (node is ClassTypeAlias) { +- return node.name.name; +- } else if (node is ClassDeclaration) { +- return node.name.name; +- } else if (node is ConstructorDeclaration) { +- if (node.name == null) { +- return node.returnType.name; +- } else { +- return node.returnType.name + '.' + node.name.name; +- } +- } else if (node is ConstructorName) { +- return node.toSource(); +- } else if (node is FieldDeclaration) { +- return _getNames(node.fields); +- } else if (node is FunctionDeclaration) { +- SimpleIdentifier nameNode = node.name; +- if (nameNode != null) { +- return nameNode.name; +- } +- } else if (node is FunctionTypeAlias) { +- return node.name.name; +- } else if (node is Identifier) { +- return node.name; +- } else if (node is MethodDeclaration) { +- return node.name.name; +- } else if (node is TopLevelVariableDeclaration) { +- return _getNames(node.variables); +- } else if (node is TypeAnnotation) { +- return node.toSource(); +- } else if (node is TypeParameter) { +- return node.name.name; +- } else if (node is VariableDeclaration) { +- return node.name.name; +- } +- return null; +- } +- +- /** +- * Return a string containing a comma-separated list of the names of all of +- * the variables in the given list of [variables]. +- */ +- String _getNames(VariableDeclarationList variables) { +- StringBuffer buffer = new StringBuffer(); +- bool first = true; +- for (VariableDeclaration variable in variables.variables) { +- if (first) { +- first = false; +- } else { +- buffer.write(', '); +- } +- buffer.write(variable.name.name); +- } +- return buffer.toString(); +- } +- +- /** +- * Write a representation of the given [node] to the buffer. +- */ +- void _writeNode(AstNode node) { +- indent(); +- buffer.write(node.runtimeType); +- buffer.write(' ['); +- buffer.write(node.offset); +- buffer.write('..'); +- buffer.write(node.offset + node.length - 1); +- buffer.write(']'); +- if (node.isSynthetic) { +- buffer.write(' (synthetic)'); +- } +- buffer.write(''); +- buffer.write('
'); +- } +-} +diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart +deleted file mode 100644 +index 25902ead0f2..00000000000 +--- a/pkg/analysis_server/lib/src/status/diagnostics.dart ++++ /dev/null +@@ -1,1229 +0,0 @@ +-// 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:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/domain_completion.dart'; +-import 'package:analysis_server/src/domain_diagnostic.dart'; +-import 'package:analysis_server/src/domain_execution.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/server/http_server.dart'; +-import 'package:analysis_server/src/services/completion/completion_performance.dart'; +-import 'package:analysis_server/src/socket_server.dart'; +-import 'package:analysis_server/src/status/ast_writer.dart'; +-import 'package:analysis_server/src/status/element_writer.dart'; +-import 'package:analysis_server/src/status/pages.dart'; +-import 'package:analysis_server/src/utilities/profiling.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/source/sdk_ext.dart'; +-import 'package:analyzer/src/context/source.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/file_state.dart'; +-import 'package:analyzer/src/dart/sdk/sdk.dart'; +-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/utilities_general.dart'; +-import 'package:analyzer/src/lint/linter.dart'; +-import 'package:analyzer/src/lint/registry.dart'; +-import 'package:analyzer/src/services/lint.dart'; +-import 'package:path/path.dart' as pathPackage; +- +-final String kCustomCss = ''' +-.lead, .page-title+.markdown-body>p:first-child { +- margin-bottom: 30px; +- font-size: 20px; +- font-weight: 300; +- color: #555; +-} +- +-.container { +- width: 1160px; +-} +- +-.masthead { +- padding-top: 1rem; +- padding-bottom: 1rem; +- margin-bottom: 1.5rem; +- text-align: center; +- background-color: #4078c0; +-} +- +-.masthead .masthead-logo { +- display: inline-block; +- font-size: 1.5rem; +- color: #fff; +- float: left; +-} +- +-.masthead .mega-octicon { +- font-size: 1.5rem; +-} +- +-.masthead-nav { +- float: right; +- margin-top: .5rem; +-} +- +-.masthead-nav a:not(:last-child) { +- margin-right: 1.25rem; +-} +- +-.masthead a { +- color: rgba(255,255,255,0.5); +- font-size: 1rem; +-} +- +-.masthead a:hover { +- color: #fff; +- text-decoration: none; +-} +- +-.masthead-nav .active { +- color: #fff; +- font-weight: 500; +-} +- +-.counter { +- display: inline-block; +- padding: 2px 5px; +- font-size: 11px; +- font-weight: bold; +- line-height: 1; +- color: #666; +- background-color: #eee; +- border-radius: 20px; +-} +- +-.menu-item .counter { +- float: right; +- margin-left: 5px; +-} +- +-td.right { +- text-align: right; +-} +- +-table td { +- max-width: 600px; +- vertical-align: text-top; +-} +- +-td.pre { +- white-space: pre; +-} +- +-.nowrap { +- white-space: nowrap; +-} +- +-.scroll-table { +- max-height: 190px; +- overflow-x: auto; +-} +- +-.footer { +- padding-top: 3rem; +- padding-bottom: 3rem; +- margin-top: 3rem; +- line-height: 1.75; +- color: #7a7a7a; +- border-top: 1px solid #eee; +-} +- +-.footer strong { +- color: #333; +-} +-'''; +- +-final bool _showLints = false; +- +-String get _sdkVersion { +- String version = Platform.version; +- if (version.contains(' ')) { +- version = version.substring(0, version.indexOf(' ')); +- } +- return version; +-} +- +-String writeOption(String name, dynamic value) { +- return '$name: $value
'; +-} +- +-class AstPage extends DiagnosticPageWithNav { +- String _description; +- +- AstPage(DiagnosticsSite site) +- : super(site, 'ast', 'AST', description: 'The AST for a file.'); +- +- @override +- String get description => _description ?? super.description; +- +- @override +- bool get showInNav => false; +- +- @override +- Future generateContent(Map params) async { +- String path = params['file']; +- if (path == null) { +- p('No file path provided.'); +- return; +- } +- AnalysisDriver driver = server.getAnalysisDriver(path); +- if (driver == null) { +- p('The file ${escape(path)} is not being analyzed.', +- raw: true); +- return; +- } +- AnalysisResult result = await driver.getResult(path); +- if (result == null) { +- p( +- 'An AST could not be produced for the file ${escape( +- path)}.', +- raw: true); +- return; +- } +- +- AstWriter writer = new AstWriter(buf); +- result.unit.accept(writer); +- } +- +- @override +- Future generatePage(Map params) async { +- try { +- _description = params['file']; +- await super.generatePage(params); +- } finally { +- _description = null; +- } +- } +-} +- +-class CommunicationsPage extends DiagnosticPageWithNav { +- CommunicationsPage(DiagnosticsSite site) +- : super(site, 'communications', 'Communications', +- description: +- 'Latency statistics for analysis server communications.'); +- +- @override +- void generateContent(Map params) { +- void writeRow(List data, {List classes}) { +- buf.write(""); +- for (int i = 0; i < data.length; i++) { +- String c = classes == null ? null : classes[i]; +- if (c != null) { +- buf.write('${escape(data[i])}'); +- } else { +- buf.write('${escape(data[i])}'); +- } +- } +- buf.writeln(""); +- } +- +- buf.writeln('
'); +- +- ServerPerformance perf = server.performanceAfterStartup; +- if (perf != null) { +- buf.writeln('
'); +- h3('Current'); +- +- int requestCount = perf.requestCount; +- int averageLatency = +- requestCount > 0 ? (perf.requestLatency ~/ requestCount) : 0; +- int maximumLatency = perf.maxLatency; +- double slowRequestPercent = +- requestCount > 0 ? (perf.slowRequestCount / requestCount) : 0.0; +- +- buf.write(''); +- writeRow([printInteger(requestCount), 'requests'], +- classes: ["right", null]); +- writeRow([printMilliseconds(averageLatency), 'average latency'], +- classes: ["right", null]); +- writeRow([printMilliseconds(maximumLatency), 'maximum latency'], +- classes: ["right", null]); +- writeRow([printPercentage(slowRequestPercent), '> 150 ms latency'], +- classes: ["right", null]); +- buf.write('
'); +- +- String time = server.uptime.toString(); +- if (time.contains('.')) { +- time = time.substring(0, time.indexOf('.')); +- } +- buf.writeln(writeOption('Uptime', time)); +- +- buf.write('
'); +- } +- +- buf.writeln('
'); +- h3('Startup'); +- perf = server.performanceDuringStartup; +- +- int requestCount = perf.requestCount; +- int averageLatency = +- requestCount > 0 ? (perf.requestLatency ~/ requestCount) : 0; +- int maximumLatency = perf.maxLatency; +- double slowRequestPercent = +- requestCount > 0 ? (perf.slowRequestCount / requestCount) : 0.0; +- +- buf.write(''); +- writeRow([printInteger(requestCount), 'requests'], +- classes: ["right", null]); +- writeRow([printMilliseconds(averageLatency), 'average latency'], +- classes: ["right", null]); +- writeRow([printMilliseconds(maximumLatency), 'maximum latency'], +- classes: ["right", null]); +- writeRow([printPercentage(slowRequestPercent), '> 150 ms latency'], +- classes: ["right", null]); +- buf.write('
'); +- +- if (server.performanceAfterStartup != null) { +- int startupTime = +- server.performanceAfterStartup.startTime - perf.startTime; +- buf.writeln( +- writeOption('Initial analysis time', printMilliseconds(startupTime))); +- } +- buf.write('
'); +- +- buf.write('
'); +- } +-} +- +-class CompletionPage extends DiagnosticPageWithNav { +- CompletionPage(DiagnosticsSite site) +- : super(site, 'completion', 'Code Completion', +- description: 'Latency statistics for code completion.'); +- +- @override +- void generateContent(Map params) { +- CompletionDomainHandler completionDomain = server.handlers +- .firstWhere((handler) => handler is CompletionDomainHandler); +- +- List completions = +- completionDomain.performanceList.items.toList(); +- +- if (completions.isEmpty) { +- blankslate('No completions recorded.'); +- return; +- } +- +- int fastCount = +- completions.where((c) => c.elapsedInMilliseconds <= 100).length; +- p('${completions.length} results; ${printPercentage( +- fastCount / completions.length)} within 100ms.'); +- +- // draw a chart +- buf.writeln( +- '
'); +- StringBuffer rowData = new StringBuffer(); +- for (int i = completions.length - 1; i >= 0; i--) { +- // [' ', 101.5] +- if (rowData.isNotEmpty) { +- rowData.write(','); +- } +- rowData.write("[' ', ${completions[i].elapsedInMilliseconds}]"); +- } +- buf.writeln(''' +- +-'''); +- +- // emit the data as a table +- buf.writeln(''); +- buf.writeln( +- ''); +- for (CompletionPerformance completion in completions) { +- buf.writeln('' +- '' +- '' +- '' +- '' +- ''); +- } +- buf.writeln('
TimeResultsSourceSnippet
${printMilliseconds( +- completion.elapsedInMilliseconds)}${completion.suggestionCount}${escape(completion.source.shortName)}${escape(completion.snippet)}
'); +- } +-} +- +-class ContextsPage extends DiagnosticPageWithNav { +- ContextsPage(DiagnosticsSite site) +- : super(site, 'contexts', 'Contexts', +- description: +- 'An analysis context defines the options and the set of sources being analyzed.'); +- +- String get navDetail => printInteger(server.driverMap.length); +- +- String describe(AnalysisOptionsImpl options) { +- StringBuffer b = new StringBuffer(); +- +- b.write( +- writeOption('Analyze function bodies', options.analyzeFunctionBodies)); +- b.write(writeOption( +- 'Enable strict call checks', options.enableStrictCallChecks)); +- b.write(writeOption('Enable super mixins', options.enableSuperMixins)); +- b.write(writeOption('Generate dart2js hints', options.dart2jsHint)); +- b.write(writeOption( +- 'Generate errors in implicit files', options.generateImplicitErrors)); +- b.write( +- writeOption('Generate errors in SDK files', options.generateSdkErrors)); +- b.write(writeOption('Generate hints', options.hint)); +- b.write(writeOption('Preserve comments', options.preserveComments)); +- b.write(writeOption('Strong mode', options.strongMode)); +- b.write(writeOption('Strong mode hints', options.strongModeHints)); +- +- return b.toString(); +- } +- +- @override +- void generateContent(Map params) { +- Map driverMap = server.driverMap; +- if (driverMap.isEmpty) { +- blankslate('No contexts.'); +- return; +- } +- +- String contextPath = params['context']; +- List folders = driverMap.keys.toList(); +- folders +- .sort((first, second) => first.shortName.compareTo(second.shortName)); +- Folder folder = +- folders.firstWhere((f) => f.path == contextPath, orElse: () => null); +- +- if (folder == null) { +- folder = folders.first; +- contextPath = folder.path; +- } +- +- AnalysisDriver driver = driverMap[folder]; +- +- buf.writeln('
'); +- buf.writeln(''); +- buf.writeln('
'); +- +- buf.writeln(writeOption('Context location', escape(contextPath))); +- buf.writeln(writeOption('Analysis options path', +- escape(driver.contextRoot.optionsFilePath ?? 'none'))); +- +- buf.writeln('
'); +- +- buf.writeln('
'); +- h3('Analysis options'); +- p(describe(driver.analysisOptions), raw: true); +- buf.writeln( +- writeOption('Has .packages file', folder.getChild('.packages').exists)); +- buf.writeln(writeOption( +- 'Has pubspec.yaml file', folder.getChild('pubspec.yaml').exists)); +- buf.writeln('
'); +- +- buf.writeln('
'); +- DartSdk sdk = driver?.sourceFactory?.dartSdk; +- AnalysisOptionsImpl sdkOptions = sdk?.context?.analysisOptions; +- if (sdkOptions != null) { +- h3('SDK analysis options'); +- p(describe(sdkOptions), raw: true); +- +- if (sdk is FolderBasedDartSdk) { +- p(writeOption('Use summaries', sdk.useSummary), raw: true); +- } +- } +- buf.writeln('
'); +- +- buf.writeln('
'); +- +- h3('Lints'); +- p(driver.analysisOptions.lintRules.map((l) => l.name).join(', ')); +- +- h3('Error processors'); +- p(driver.analysisOptions.errorProcessors +- .map((e) => e.description) +- .join(', ')); +- +- h3('Plugins'); +- p(driver.analysisOptions.enabledPluginNames.join(', ')); +- +- List priorityFiles = driver.priorityFiles; +- List addedFiles = driver.addedFiles.toList(); +- List implicitFiles = +- driver.knownFiles.difference(driver.addedFiles).toList(); +- addedFiles.sort(); +- implicitFiles.sort(); +- +- String lenCounter(List list) { +- return '${list +- .length}'; +- } +- +- h3('Context files'); +- +- void writeFile(String file) { +- String astPath = '/ast?file=${Uri.encodeQueryComponent(file)}'; +- String elementPath = '/element?file=${Uri.encodeQueryComponent(file)}'; +- +- buf.write(file); +- buf.writeln(' ast'); +- buf.write(' '); +- buf.writeln('element'); +- } +- +- h4('Priority files ${lenCounter(priorityFiles)}', raw: true); +- ul(priorityFiles, writeFile, classes: 'scroll-table'); +- +- h4('Added files ${lenCounter(addedFiles)}', raw: true); +- ul(addedFiles, writeFile, classes: 'scroll-table'); +- +- h4('Implicit files ${lenCounter(implicitFiles)}', raw: true); +- ul(implicitFiles, writeFile, classes: 'scroll-table'); +- +- SourceFactory sourceFactory = driver.sourceFactory; +- if (sourceFactory is SourceFactoryImpl) { +- h3('Resolvers'); +- for (UriResolver resolver in sourceFactory.resolvers) { +- h4(resolver.runtimeType.toString()); +- buf.write('

'); +- if (resolver is DartUriResolver) { +- DartSdk sdk = resolver.dartSdk; +- buf.write(' (sdk = '); +- buf.write(sdk.runtimeType); +- if (sdk is FolderBasedDartSdk) { +- buf.write(' (path = '); +- buf.write(sdk.directory.path); +- buf.write(')'); +- } else if (sdk is EmbedderSdk) { +- buf.write(' (map = '); +- writeMap(sdk.urlMappings); +- buf.write(')'); +- } +- buf.write(')'); +- } else if (resolver is SdkExtUriResolver) { +- buf.write(' (map = '); +- writeMap(resolver.urlMappings); +- buf.write(')'); +- } else if (resolver is PackageMapUriResolver) { +- writeMap(resolver.packageMap); +- } +- buf.write('

'); +- } +- } +- } +- +- void writeList(List list) { +- buf.writeln('[${list.join(', ')}]'); +- } +- +- void writeMap(Map map) { +- List keys = map.keys.toList(); +- keys.sort(); +- int length = keys.length; +- buf.write('{'); +- for (int i = 0; i < length; i++) { +- buf.write('
'); +- String key = keys[i]; +- V value = map[key]; +- buf.write(key); +- buf.write(' = '); +- if (value is List) { +- writeList(value); +- } else { +- buf.write(value); +- } +- buf.write(','); +- } +- buf.write('
}'); +- } +-} +- +-/// A page with a proscriptive notion of layout. +-abstract class DiagnosticPage extends Page { +- final Site site; +- +- DiagnosticPage(this.site, String id, String title, {String description}) +- : super(id, title, description: description); +- +- bool get isNavPage => false; +- +- AnalysisServer get server => +- (site as DiagnosticsSite).socketServer.analysisServer; +- +- Future generateContainer(Map params) async { +- buf.writeln('
'); +- buf.writeln('
'); +- h1(title, classes: 'page-title'); +- await asyncDiv(() async { +- p(description); +- await generateContent(params); +- }, classes: 'markdown-body'); +- buf.writeln('
'); +- buf.writeln('
'); +- } +- +- void generateContent(Map params); +- +- void generateFooter() { +- buf.writeln(''' +-
+- Dart ${site.title} SDK $_sdkVersion +-
+-'''); +- } +- +- void generateHeader() { +- buf.writeln(''' +-
+-
+- +- +- +-
+-
+-'''); +- } +- +- Future generatePage(Map params) async { +- buf.writeln(''); +- buf.write(''); +- buf.write(''); +- buf.write(''); +- buf.writeln('${site.title}'); +- buf.writeln(''); +- buf.writeln(''); +- buf.writeln(''); +- buf.writeln(''); +- buf.writeln(''); +- +- buf.writeln(''); +- generateHeader(); +- buf.writeln('
'); +- await generateContainer(params); +- generateFooter(); +- buf.writeln('
'); // div.container +- buf.writeln(''); +- buf.writeln(''); +- } +-} +- +-abstract class DiagnosticPageWithNav extends DiagnosticPage { +- DiagnosticPageWithNav(Site site, String id, String title, +- {String description}) +- : super(site, id, title, description: description); +- +- bool get isNavPage => true; +- +- String get navDetail => null; +- +- bool get showInNav => true; +- +- Future generateContainer(Map params) async { +- buf.writeln('
'); +- +- bool shouldShowInNav(Page page) { +- return page is DiagnosticPageWithNav && page.showInNav; +- } +- +- buf.writeln('
'); +- buf.writeln(''); +- buf.writeln('
'); +- +- buf.writeln('
'); +- h1(title, classes: 'page-title'); +- await asyncDiv(() async { +- p(description); +- await generateContent(params); +- }, classes: 'markdown-body'); +- buf.writeln('
'); +- +- buf.writeln('
'); +- } +-} +- +-class DiagnosticsSite extends Site implements AbstractGetHandler { +- /// An object that can handle either a WebSocket connection or a connection +- /// to the client over stdio. +- SocketServer socketServer; +- +- /// The last few lines printed. +- List lastPrintedLines = []; +- +- DiagnosticsSite(this.socketServer, this.lastPrintedLines) +- : super('Analysis Server') { +- pages.add(new CompletionPage(this)); +- pages.add(new CommunicationsPage(this)); +- pages.add(new ContextsPage(this)); +- pages.add(new EnvironmentVariablesPage(this)); +- pages.add(new ExceptionsPage(this)); +- pages.add(new InstrumentationPage(this)); +- pages.add(new OverlaysPage(this)); +- pages.add(new PluginsPage(this)); +- pages.add(new ProfilePage(this)); +- pages.add(new SubscriptionsPage(this)); +- +- ProcessProfiler profiler = ProcessProfiler.getProfilerForPlatform(); +- if (profiler != null) { +- pages.add(new MemoryAndCpuPage(this, profiler)); +- } +- +- pages.sort(((Page a, Page b) => +- a.title.toLowerCase().compareTo(b.title.toLowerCase()))); +- +- // Add the status page at the beginning. +- pages.insert(0, new StatusPage(this)); +- +- // Add non-nav pages. +- pages.add(new FeedbackPage(this)); +- pages.add(new AstPage(this)); +- pages.add(new ElementModelPage(this)); +- } +- +- String get customCss => kCustomCss; +- +- Page createExceptionPage(String message, StackTrace trace) => +- new ExceptionPage(this, message, trace); +- +- Page createUnknownPage(String unknownPath) => +- new NotFoundPage(this, unknownPath); +-} +- +-class ElementModelPage extends DiagnosticPageWithNav { +- String _description; +- +- ElementModelPage(DiagnosticsSite site) +- : super(site, 'element', 'Element model', +- description: 'The element model for a file.'); +- +- @override +- String get description => _description ?? super.description; +- +- @override +- bool get showInNav => false; +- +- @override +- Future generateContent(Map params) async { +- String path = params['file']; +- if (path == null) { +- p('No file path provided.'); +- return; +- } +- AnalysisDriver driver = server.getAnalysisDriver(path); +- if (driver == null) { +- p('The file ${escape(path)} is not being analyzed.', +- raw: true); +- return; +- } +- AnalysisResult result = await driver.getResult(path); +- if (result == null) { +- p( +- 'An element model could not be produced for the file ${escape( +- path)}.', +- raw: true); +- return; +- } +- +- ElementWriter writer = new ElementWriter(buf); +- result.unit.element.accept(writer); +- } +- +- @override +- Future generatePage(Map params) async { +- try { +- _description = params['file']; +- await super.generatePage(params); +- } finally { +- _description = null; +- } +- } +-} +- +-class EnvironmentVariablesPage extends DiagnosticPageWithNav { +- EnvironmentVariablesPage(DiagnosticsSite site) +- : super(site, 'environment', 'Environment Variables', +- description: +- 'System environment variables as seen from the analysis server.'); +- +- @override +- void generateContent(Map params) { +- buf.writeln(''); +- buf.writeln(''); +- for (String key in Platform.environment.keys.toList()..sort()) { +- String value = Platform.environment[key]; +- buf.writeln(''); +- } +- buf.writeln('
VariableValue
${escape(key)}${escape(value)}
'); +- } +-} +- +-class ExceptionPage extends DiagnosticPage { +- final StackTrace trace; +- +- ExceptionPage(Site site, String message, this.trace) +- : super(site, '', '500 Oops', description: message); +- +- void generateContent(Map params) { +- p(trace.toString(), style: 'white-space: pre'); +- } +-} +- +-class ExceptionsPage extends DiagnosticPageWithNav { +- ExceptionsPage(DiagnosticsSite site) +- : super(site, 'exceptions', 'Exceptions', +- description: 'Exceptions from the analysis server.'); +- +- Iterable get exceptions => server.exceptions.items; +- +- String get navDetail => printInteger(exceptions.length); +- +- @override +- void generateContent(Map params) { +- if (exceptions.isEmpty) { +- blankslate('No exceptions encountered!'); +- } else { +- for (ServerException ex in exceptions) { +- h3('Exception ${ex.exception}'); +- p('${escape(ex.message)}
${writeOption('fatal', ex.fatal)}', +- raw: true); +- pre(() { +- buf.writeln('${escape(ex.stackTrace.toString())}'); +- }, classes: "scroll-table"); +- } +- } +- } +-} +- +-class FeedbackPage extends DiagnosticPage { +- FeedbackPage(DiagnosticsSite site) +- : super(site, 'feedback', 'Feedback', +- description: 'Providing feedback and filing issues.'); +- +- @override +- void generateContent(Map params) { +- final String issuesUrl = 'https://github.com/dart-lang/sdk/issues'; +- p( +- 'To file issues or feature requests, see our ' +- 'bug tracker. When filing an issue, please describe:', +- raw: true, +- ); +- ul([ +- 'what you were doing', +- 'what occured', +- 'what you think the expected behavior should have been', +- ], (line) => buf.writeln(line)); +- +- List ideInfo = []; +- if (server.options.clientId != null) { +- ideInfo.add(server.options.clientId); +- } +- if (server.options.clientVersion != null) { +- ideInfo.add(server.options.clientVersion); +- } +- String ideText = ideInfo.map((str) => '$str').join(', '); +- +- p('Other data to include:'); +- ul([ +- "the IDE you are using and it's version${ideText.isEmpty +- ? '' +- : ' ($ideText)'}", +- 'the Dart SDK version (${escape(_sdkVersion)})', +- 'your operating system (${escape( +- Platform.operatingSystem)})', +- ], (line) => buf.writeln(line)); +- +- p('Thanks!'); +- } +-} +- +-class InstrumentationPage extends DiagnosticPageWithNav { +- InstrumentationPage(DiagnosticsSite site) +- : super(site, 'instrumentation', 'Instrumentation', +- description: +- 'Verbose instrumentation data from the analysis server.'); +- +- @override +- void generateContent(Map params) { +- p( +- 'Instrumentation can be enabled by starting the analysis server with the ' +- '--instrumentation-log-file=path/to/file flag.', +- raw: true); +- +- if (!AnalysisEngine.instance.instrumentationService.isActive) { +- blankslate('Instrumentation not active.'); +- return; +- } +- +- h3('Instrumentation'); +- +- p('Instrumentation active.'); +- +- InstrumentationServer instrumentation = +- AnalysisEngine.instance.instrumentationService.instrumentationServer; +- String description = instrumentation.describe; +- HtmlEscape htmlEscape = new HtmlEscape(HtmlEscapeMode.ELEMENT); +- description = htmlEscape.convert(description); +- // Convert http(s): references to hyperlinks. +- final RegExp urlRegExp = new RegExp(r'[http|https]+:\/*(\S+)'); +- description = description.replaceAllMapped(urlRegExp, (Match match) { +- return '${match.group(1)}'; +- }); +- p(description.replaceAll('\n', '
'), raw: true); +- } +-} +- +-class MemoryAndCpuPage extends DiagnosticPageWithNav { +- final ProcessProfiler profiler; +- +- MemoryAndCpuPage(DiagnosticsSite site, this.profiler) +- : super(site, 'memory', 'Memory and CPU Usage', +- description: 'Memory and CPU usage for the analysis server.'); +- +- DiagnosticDomainHandler get diagnosticDomain { +- return server.handlers +- .firstWhere((handler) => handler is DiagnosticDomainHandler); +- } +- +- @override +- void generateContent(Map params) { +- UsageInfo usage = profiler.getProcessUsageSync(pid); +- if (usage != null) { +- buf.writeln( +- writeOption('CPU', printPercentage(usage.cpuPercentage / 100.0))); +- buf.writeln( +- writeOption('Memory', '${printInteger(usage.memoryMB.round())} MB')); +- } else { +- p('Error retreiving the memory and cpu usage information.'); +- } +- } +-} +- +-class NotFoundPage extends DiagnosticPage { +- final String path; +- +- NotFoundPage(Site site, this.path) +- : super(site, '', '404 Not found', description: "'$path' not found."); +- +- void generateContent(Map params) {} +-} +- +-class OverlaysPage extends DiagnosticPageWithNav { +- OverlaysPage(DiagnosticsSite site) +- : super(site, 'overlays', 'Overlays', +- description: 'Editing overlays - unsaved file changes.'); +- +- @override +- void generateContent(Map params) { +- FileContentOverlay overlays = server.fileContentOverlay; +- List paths = overlays.paths.toList()..sort(); +- +- String overlayPath = params['overlay']; +- if (overlayPath != null) { +- p(overlayPath); +- +- if (overlays[overlayPath] != null) { +- buf.write('
');
+-        buf.write(overlays[overlayPath]);
+-        buf.writeln('
'); +- } else { +- p('${escape(overlayPath)} not found.', raw: true); +- } +- +- return; +- } +- +- if (paths.isEmpty) { +- blankslate('No overlays.'); +- } else { +- String lenCounter(List list) { +- return '${list +- .length}'; +- } +- +- h3('Overlays ${lenCounter(paths)}', raw: true); +- ul(paths, (String overlayPath) { +- String uri = '$path?overlay=${Uri.encodeQueryComponent(overlayPath)}'; +- buf.writeln('${escape(overlayPath)}'); +- }); +- } +- } +-} +- +-// TODO(devoncarew): We're not currently tracking the time spent in specific +-// lints by default (analysisOptions / driverOptions enableTiming) +-class PluginsPage extends DiagnosticPageWithNav { +- PluginsPage(DiagnosticsSite site) +- : super(site, 'plugins', 'Plugins', description: 'Plugins in use.'); +- +- @override +- void generateContent(Map params) { +- h3('Analysis plugins'); +- List analysisPlugins = server.pluginManager.plugins; +- +- if (analysisPlugins.isEmpty) { +- blankslate('No known analysis plugins.'); +- } else { +- for (PluginInfo plugin in analysisPlugins) { +- // TODO(brianwilkerson) Sort the plugins by name. +- String id = plugin.pluginId; +- PluginData data = plugin.data; +- +- List components = pathPackage.split(id); +- int length = components.length; +- String name; +- if (length == 0) { +- name = 'unknown plugin'; +- } else if (length > 2) { +- name = components[length - 3]; +- } else { +- name = components[length - 1]; +- } +- h4(name); +- p('path: $id'); +- if (data.name == null) { +- if (plugin.exception != null) { +- p('not running'); +- pre(() { +- buf.write(plugin.exception); +- }); +- } else { +- p('not running for unknown reason'); +- } +- } else { +- p('name: ${data.name}'); +- p('version: ${data.version}'); +- p('Associated contexts:'); +- Set contexts = plugin.contextRoots; +- if (contexts.isEmpty) { +- blankslate('none'); +- } else { +- ul(contexts.toList(), (ContextRoot root) { +- buf.writeln(root.root); +- }); +- } +- } +- } +- } +- } +-} +- +-class ProfilePage extends DiagnosticPageWithNav { +- ProfilePage(DiagnosticsSite site) +- : super(site, 'profile', 'Profiling Info', +- description: 'Profiling performance tag data.'); +- +- @override +- void generateContent(Map params) { +- h3('Profiling performance tag data'); +- +- // prepare sorted tags +- List tags = PerformanceTag.all.toList(); +- tags.remove(ServerPerformanceStatistics.idle); +- tags.remove(PerformanceTag.unknown); +- tags.removeWhere((tag) => tag.elapsedMs == 0); +- tags.sort((a, b) => b.elapsedMs - a.elapsedMs); +- +- // print total time +- int totalTime = +- tags.fold(0, (int a, PerformanceTag tag) => a + tag.elapsedMs); +- p('Total measured time: ${printMilliseconds(totalTime)}'); +- +- // draw a pie chart +- String rowData = +- tags.map((tag) => "['${tag.label}', ${tag.elapsedMs}]").join(','); +- buf.writeln( +- '
'); +- buf.writeln(''' +- +-'''); +- +- // write out a table +- void _writeRow(List data, {bool header: false}) { +- buf.write(''); +- if (header) { +- for (String d in data) { +- buf.write('$d'); +- } +- } else { +- buf.write('${data[0]}'); +- +- for (String d in data.sublist(1)) { +- buf.write('$d'); +- } +- } +- buf.writeln(''); +- } +- +- buf.write(''); +- _writeRow(['Tag name', 'Time (in ms)', 'Percent'], header: true); +- void writeRow(PerformanceTag tag) { +- double percent = tag.elapsedMs / totalTime; +- _writeRow([ +- tag.label, +- printMilliseconds(tag.elapsedMs), +- printPercentage(percent) +- ]); +- } +- +- tags.forEach(writeRow); +- buf.write('
'); +- +- if (_showLints) { +- h3('Lint rule timings'); +- List rules = Registry.ruleRegistry.rules.toList(); +- int totalLintTime = rules.fold(0, +- (sum, rule) => sum + lintRegistry.getTimer(rule).elapsedMilliseconds); +- p('Total time spent in lints: ${printMilliseconds(totalLintTime)}'); +- +- rules.sort((first, second) { +- int firstTime = lintRegistry.getTimer(first).elapsedMilliseconds; +- int secondTime = lintRegistry.getTimer(second).elapsedMilliseconds; +- if (firstTime == secondTime) { +- return first.lintCode.name.compareTo(second.lintCode.name); +- } +- return secondTime - firstTime; +- }); +- buf.write(''); +- _writeRow(['Lint code', 'Time (in ms)'], header: true); +- for (var rule in rules) { +- int time = lintRegistry.getTimer(rule).elapsedMilliseconds; +- _writeRow([rule.lintCode.name, printMilliseconds(time)]); +- } +- buf.write('
'); +- } +- } +-} +- +-class StatusPage extends DiagnosticPageWithNav { +- StatusPage(DiagnosticsSite site) +- : super(site, 'status', 'Status', +- description: +- 'General status and diagnostics for the analysis server.'); +- +- @override +- void generateContent(Map params) { +- buf.writeln('
'); +- +- buf.writeln('
'); +- h3('Status'); +- buf.writeln(writeOption('Instrumentation enabled', +- AnalysisEngine.instance.instrumentationService.isActive)); +- buf.writeln(writeOption('Server process ID', pid)); +- buf.writeln('
'); +- +- buf.writeln('
'); +- h3('Versions'); +- buf.writeln(writeOption('Analysis server version', AnalysisServer.VERSION)); +- buf.writeln(writeOption('Dart SDK', Platform.version)); +- buf.writeln('
'); +- +- buf.writeln('
'); +- +- List lines = (site as DiagnosticsSite).lastPrintedLines; +- if (lines.isNotEmpty) { +- h3('Debug output'); +- p(lines.join('\n'), style: 'white-space: pre'); +- } +- } +-} +- +-class SubscriptionsPage extends DiagnosticPageWithNav { +- SubscriptionsPage(DiagnosticsSite site) +- : super(site, 'subscriptions', 'Subscriptions', +- description: 'Registered subscriptions to analysis server events.'); +- +- @override +- void generateContent(Map params) { +- // server domain +- h3('Server domain subscriptions'); +- ul(ServerService.VALUES, (item) { +- if (server.serverServices.contains(item)) { +- buf.write('$item (has subscriptions)'); +- } else { +- buf.write('$item (no subscriptions)'); +- } +- }); +- +- // analysis domain +- h3('Analysis domain subscriptions'); +- for (AnalysisService service in AnalysisService.VALUES) { +- buf.writeln('${service.name}
'); +- ul(server.analysisServices[service] ?? [], (item) { +- buf.write('$item'); +- }); +- } +- +- // execution domain +- ExecutionDomainHandler domain = server.handlers.firstWhere( +- (handler) => handler is ExecutionDomainHandler, +- orElse: () => null); +- +- h3('Execution domain'); +- ul(ExecutionService.VALUES, (item) { +- if (domain.onFileAnalyzed != null) { +- buf.write('$item (has subscriptions)'); +- } else { +- buf.write('$item (no subscriptions)'); +- } +- }); +- } +-} +diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart +deleted file mode 100644 +index 8299ef9d7a1..00000000000 +--- a/pkg/analysis_server/lib/src/status/element_writer.dart ++++ /dev/null +@@ -1,179 +0,0 @@ +-// Copyright (c) 2015, 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 'dart:convert'; +- +-import 'package:analysis_server/src/status/tree_writer.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +-import 'package:analyzer/src/dart/element/element.dart'; +- +-/** +- * A visitor that will produce an HTML representation of an element structure. +- */ +-class ElementWriter extends GeneralizingElementVisitor with TreeWriter { +- /** +- * Initialize a newly created element writer to write the HTML representation +- * of visited elements on the given [buffer]. +- */ +- ElementWriter(StringBuffer buffer) { +- this.buffer = buffer; +- } +- +- @override +- void visitElement(Element element) { +- _writeElement(element); +- writeProperties(_computeProperties(element)); +- indentLevel++; +- try { +- element.visitChildren(this); +- } finally { +- indentLevel--; +- } +- } +- +- /** +- * Write a representation of the properties of the given [node] to the buffer. +- */ +- Map _computeProperties(Element element) { +- Map properties = new HashMap(); +- +- properties['metadata'] = element.metadata; +- properties['nameOffset'] = element.nameOffset; +- if (element is ClassElement) { +- properties['hasNonFinalField'] = element.hasNonFinalField; +- properties['hasReferenceToSuper'] = element.hasReferenceToSuper; +- properties['hasStaticMember'] = element.hasStaticMember; +- properties['interfaces'] = element.interfaces; +- properties['isAbstract'] = element.isAbstract; +- properties['isEnum'] = element.isEnum; +- properties['isMixinApplication'] = element.isMixinApplication; +- properties['isOrInheritsProxy'] = element.isOrInheritsProxy; +- properties['isProxy'] = element.isProxy; +- properties['isValidMixin'] = element.isValidMixin; +- properties['mixins'] = element.mixins; +- properties['supertype'] = element.supertype; +- } +- if (element is ClassMemberElement) { +- properties['isStatic'] = element.isStatic; +- } +- if (element is CompilationUnitElement) { +- properties['hasLoadLibraryFunction'] = element.hasLoadLibraryFunction; +- properties['source'] = element.source; +- } +- if (element is ConstFieldElementImpl) { +- properties['evaluationResult'] = element.evaluationResult; +- } +- if (element is ConstLocalVariableElementImpl) { +- properties['evaluationResult'] = element.evaluationResult; +- } +- if (element is ConstTopLevelVariableElementImpl) { +- properties['evaluationResult'] = element.evaluationResult; +- } +- if (element is ConstructorElement) { +- properties['isConst'] = element.isConst; +- properties['isDefaultConstructor'] = element.isDefaultConstructor; +- properties['isFactory'] = element.isFactory; +- properties['redirectedConstructor'] = element.redirectedConstructor; +- } +- if (element is ExecutableElement) { +- properties['hasImplicitReturnType'] = element.hasImplicitReturnType; +- properties['isAbstract'] = element.isAbstract; +- properties['isAsynchronous'] = element.isAsynchronous; +- properties['isExternal'] = element.isExternal; +- properties['isGenerator'] = element.isGenerator; +- properties['isOperator'] = element.isOperator; +- properties['isStatic'] = element.isStatic; +- properties['isSynchronous'] = element.isSynchronous; +- properties['returnType'] = element.returnType; +- properties['type'] = element.type; +- } +- if (element is ExportElement) { +- properties['combinators'] = element.combinators; +- properties['library'] = element.library; +- } +- if (element is FieldElement) { +- properties['isEnumConstant'] = element.isEnumConstant; +- } +- if (element is FieldFormalParameterElement) { +- properties['field'] = element.field; +- } +- if (element is FunctionElement) { +- properties['isEntryPoint'] = element.isEntryPoint; +- } +- if (element is FunctionTypedElement) { +- properties['returnType'] = element.returnType; +- properties['type'] = element.type; +- } +- if (element is ImportElement) { +- properties['combinators'] = element.combinators; +- properties['isDeferred'] = element.isDeferred; +- properties['library'] = element.library; +- } +- if (element is LibraryElement) { +- properties['definingCompilationUnit'] = element.definingCompilationUnit; +- properties['entryPoint'] = element.entryPoint; +- properties['hasExtUri'] = element.hasExtUri; +- properties['hasLoadLibraryFunction'] = element.hasLoadLibraryFunction; +- properties['isBrowserApplication'] = element.isBrowserApplication; +- properties['isDartAsync'] = element.isDartAsync; +- properties['isDartCore'] = element.isDartCore; +- properties['isInSdk'] = element.isInSdk; +- } +- if (element is LocalElement) { +- properties['visibleRange'] = element.visibleRange; +- } +- if (element is ParameterElement) { +- properties['defaultValueCode'] = element.defaultValueCode; +- properties['isInitializingFormal'] = element.isInitializingFormal; +- properties['parameterKind'] = element.parameterKind; +- } +- if (element is PropertyAccessorElement) { +- properties['isGetter'] = element.isGetter; +- properties['isSetter'] = element.isSetter; +- } +- if (element is PropertyInducingElement) { +- properties['isStatic'] = element.isStatic; +- properties['propagatedType'] = element.propagatedType; +- } +- if (element is TypeDefiningElement) { +- properties['type'] = element.type; +- } +- if (element is TypeParameterElement) { +- properties['bound'] = element.bound; +- } +- if (element is TypeParameterizedElement) { +- properties['typeParameters'] = element.typeParameters; +- } +- if (element is VariableElement) { +- properties['constantValue'] = element.constantValue; +- properties['hasImplicitType'] = element.hasImplicitType; +- properties['isConst'] = element.isConst; +- properties['isFinal'] = element.isFinal; +- properties['isStatic'] = element.isStatic; +- properties['type'] = element.type; +- } +- +- return properties; +- } +- +- /** +- * Write a representation of the given [node] to the buffer. +- */ +- void _writeElement(Element element) { +- indent(); +- if (element.isSynthetic) { +- buffer.write(''); +- } +- buffer.write(HTML_ESCAPE.convert(element.toString())); +- if (element.isSynthetic) { +- buffer.write(''); +- } +- buffer.write(' ('); +- buffer.write(element.runtimeType); +- buffer.write(')'); +- buffer.write('
'); +- } +-} +diff --git a/pkg/analysis_server/lib/src/status/pages.dart b/pkg/analysis_server/lib/src/status/pages.dart +deleted file mode 100644 +index 1d85eccc9f4..00000000000 +--- a/pkg/analysis_server/lib/src/status/pages.dart ++++ /dev/null +@@ -1,189 +0,0 @@ +-// 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:convert'; +-import 'dart:io'; +- +-import 'package:intl/intl.dart'; +- +-final NumberFormat numberFormat = new NumberFormat.decimalPattern(); +- +-String escape(String text) => text == null ? '' : HTML_ESCAPE.convert(text); +- +-String printInteger(int value) => numberFormat.format(value); +- +-String printMilliseconds(num value) => '${numberFormat.format(value)} ms'; +- +-String printPercentage(num value) => '${(value * 100).toStringAsFixed(1)}%'; +- +-/// An entity that knows how to serve itself over http. +-abstract class Page { +- final StringBuffer buf = new StringBuffer(); +- +- final String id; +- final String title; +- final String description; +- +- Page(this.id, this.title, {this.description}); +- +- String get path => '/$id'; +- +- Future asyncDiv(void gen(), {String classes}) async { +- if (classes != null) { +- buf.writeln('
'); +- } else { +- buf.writeln('
'); +- } +- await gen(); +- buf.writeln('
'); +- } +- +- void blankslate(String str) { +- div(() => buf.writeln(str), classes: 'blankslate'); +- } +- +- void div(void gen(), {String classes}) { +- if (classes != null) { +- buf.writeln('
'); +- } else { +- buf.writeln('
'); +- } +- gen(); +- buf.writeln('
'); +- } +- +- Future generate(Map params) async { +- buf.clear(); +- await generatePage(params); +- return buf.toString(); +- } +- +- void generatePage(Map params); +- +- void h1(String text, {String classes}) { +- if (classes != null) { +- buf.writeln('

${escape(text)}

'); +- } else { +- buf.writeln('

${escape(text)}

'); +- } +- } +- +- void h2(String text) { +- buf.writeln('

${escape(text)}

'); +- } +- +- void h3(String text, {bool raw: false}) { +- buf.writeln('

${raw ? text : escape(text)}

'); +- } +- +- void h4(String text, {bool raw: false}) { +- buf.writeln('

${raw ? text : escape(text)}

'); +- } +- +- void inputList(Iterable items, void gen(T item)) { +- buf.writeln(''); +- } +- +- bool isCurrentPage(String pathToTest) => path == pathToTest; +- +- void p(String text, {String style, bool raw: false, String classes}) { +- String c = classes == null ? '' : ' class="$classes"'; +- +- if (style != null) { +- buf.writeln('${raw ? text : escape(text)}

'); +- } else { +- buf.writeln('${raw ? text : escape(text)}

'); +- } +- } +- +- void pre(void gen(), {String classes}) { +- if (classes != null) { +- buf.write('
');
+-    } else {
+-      buf.write('
');
+-    }
+-    gen();
+-    buf.writeln('
'); +- } +- +- void ul(Iterable items, void gen(T item), {String classes}) { +- buf.writeln(''); +- for (T item in items) { +- buf.write('
  • '); +- gen(item); +- buf.write('
  • '); +- } +- buf.writeln(''); +- } +-} +- +-/// Contains a collection of Pages. +-abstract class Site { +- final String title; +- List pages = []; +- +- Site(this.title); +- +- String get customCss => ''; +- +- Page createExceptionPage(String message, StackTrace trace); +- +- Page createUnknownPage(String unknownPath); +- +- Future handleGetRequest(HttpRequest request) async { +- try { +- String path = request.uri.path; +- +- if (path == '/') { +- respondRedirect(request, pages.first.path); +- return; +- } +- +- for (Page page in pages) { +- if (page.path == path) { +- HttpResponse response = request.response; +- response.headers.contentType = ContentType.HTML; +- response.write(await page.generate(request.uri.queryParameters)); +- response.close(); +- return; +- } +- } +- +- await respond(request, createUnknownPage(path), HttpStatus.NOT_FOUND); +- } catch (e, st) { +- try { +- await respond(request, createExceptionPage('$e', st), +- HttpStatus.INTERNAL_SERVER_ERROR); +- } catch (e, st) { +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR; +- response.headers.contentType = ContentType.TEXT; +- response.write('$e\n\n$st'); +- response.close(); +- } +- } +- } +- +- Future respond(HttpRequest request, Page page, +- [int code = HttpStatus.OK]) async { +- HttpResponse response = request.response; +- response.statusCode = code; +- response.headers.contentType = ContentType.HTML; +- response.write(await page.generate(request.uri.queryParameters)); +- response.close(); +- } +- +- void respondRedirect(HttpRequest request, String pathFragment) { +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.MOVED_TEMPORARILY; +- response.redirect(request.uri.resolve(pathFragment)); +- } +-} +diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart +deleted file mode 100644 +index e6b45709578..00000000000 +--- a/pkg/analysis_server/lib/src/status/tree_writer.dart ++++ /dev/null +@@ -1,123 +0,0 @@ +-// Copyright (c) 2015, 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:convert'; +- +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/src/dart/element/element.dart'; +-import 'package:analyzer/src/generated/constant.dart'; +-import 'package:analyzer/src/generated/source.dart'; +- +-/** +- * Utility methods that can be mixed in to classes that produce an HTML +- * representation of a tree structure. +- */ +-abstract class TreeWriter { +- /** +- * The buffer on which the HTML is to be written. +- */ +- StringBuffer buffer; +- +- /** +- * The current level of indentation. +- */ +- int indentLevel = 0; +- +- /** +- * A list containing the exceptions that were caught while attempting to write +- * out the tree structure. +- */ +- List exceptions = []; +- +- void indent([int extra = 0]) { +- for (int i = 0; i < indentLevel; i++) { +- buffer.write('┊   '); +- } +- if (extra > 0) { +- buffer.write('┊   '); +- for (int i = 1; i < extra; i++) { +- buffer.write('     '); +- } +- } +- } +- +- /** +- * Write a representation of the given [properties] to the buffer. +- */ +- void writeProperties(Map properties) { +- List propertyNames = properties.keys.toList(); +- propertyNames.sort(); +- for (String propertyName in propertyNames) { +- writeProperty(propertyName, properties[propertyName]); +- } +- } +- +- /** +- * Write the [value] of the property with the given [name]. +- */ +- void writeProperty(String name, Object value) { +- if (value != null) { +- indent(2); +- buffer.write('$name = '); +- _writePropertyValue(value, indentLevel); +- buffer.write('
    '); +- } +- } +- +- String _toString(Object value) { +- try { +- if (value is Source) { +- return 'Source (uri="${value.uri}", path="${value.fullName}")'; +- } else if (value is ElementAnnotationImpl) { +- StringBuffer buffer = new StringBuffer(); +- buffer.write(_toString(value.element)); +- EvaluationResultImpl result = value.evaluationResult; +- if (result == null) { +- buffer.write(': no result'); +- } else { +- buffer.write(': value = '); +- buffer.write(result.value); +- buffer.write('; errors = '); +- buffer.write(result.errors); +- } +- return buffer.toString(); +- } else { +- return value.toString(); +- } +- } catch (exception, stackTrace) { +- exceptions.add(new CaughtException(exception, stackTrace)); +- } +- return null; +- } +- +- /** +- * Write the [value] of the property with the given [name]. +- */ +- void _writePropertyValue(Object value, int baseIndent) { +- if (value is List) { +- if (value.isEmpty) { +- buffer.write('[]'); +- } else { +- int elementIndent = baseIndent + 2; +- buffer.write('[
    '); +- for (Object element in value) { +- indent(elementIndent); +- _writePropertyValue(element, elementIndent); +- buffer.write('
    '); +- } +- indent(baseIndent); +- buffer.write(']'); +- } +- } else { +- String valueString = _toString(value); +- if (valueString == null) { +- buffer.write(''); +- buffer.write(HTML_ESCAPE.convert(value.runtimeType.toString())); +- buffer.write(''); +- } else { +- buffer.write(HTML_ESCAPE.convert(valueString)); +- } +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/utilities/documentation.dart b/pkg/analysis_server/lib/src/utilities/documentation.dart +deleted file mode 100644 +index 2cc837e0b56..00000000000 +--- a/pkg/analysis_server/lib/src/utilities/documentation.dart ++++ /dev/null +@@ -1,67 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-String getDartDocSummary(String str) { +- if (str == null) { +- return null; +- } +- List lines = str.split('\n'); +- StringBuffer sb = new StringBuffer(); +- bool firstLine = true; +- for (String line in lines) { +- if (sb.length != 0 && line.isEmpty) { +- return sb.toString(); +- } +- if (!firstLine) { +- sb.write('\n'); +- } +- firstLine = false; +- sb.write(line); +- } +- return sb.toString(); +-} +- +-/** +- * Converts [str] from a Dart Doc string with slashes and stars to a plain text +- * representation of the comment. +- */ +-String removeDartDocDelimiters(String str) { +- if (str == null) { +- return null; +- } +- // remove /** */ +- if (str.startsWith('/**')) { +- str = str.substring(3); +- } +- if (str.endsWith("*/")) { +- str = str.substring(0, str.length - 2); +- } +- str = str.trim(); +- // remove leading '* ' and '/// ' +- List lines = str.split('\n'); +- StringBuffer sb = new StringBuffer(); +- bool firstLine = true; +- for (String line in lines) { +- line = line.trim(); +- if (line.startsWith("*")) { +- line = line.substring(1); +- if (line.startsWith(" ")) { +- line = line.substring(1); +- } +- } else if (line.startsWith("///")) { +- line = line.substring(3); +- if (line.startsWith(" ")) { +- line = line.substring(1); +- } +- } +- if (!firstLine) { +- sb.write('\n'); +- } +- firstLine = false; +- sb.write(line); +- } +- str = sb.toString(); +- // done +- return str; +-} +diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart +deleted file mode 100644 +index b49c372a7f6..00000000000 +--- a/pkg/analysis_server/lib/src/utilities/flutter.dart ++++ /dev/null +@@ -1,267 +0,0 @@ +-// 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 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; +- +-const _WIDGET_NAME = "Widget"; +-const _WIDGET_URI = "package:flutter/src/widgets/framework.dart"; +- +-void convertChildToChildren( +- InstanceCreationExpression childArg, +- NamedExpression namedExp, +- String eol, +- Function getNodeText, +- Function getLinePrefix, +- Function getIndent, +- Function getText, +- Function _addInsertEdit, +- Function _addRemoveEdit, +- Function _addReplaceEdit, +- Function rangeNode) { +- int childLoc = namedExp.offset + 'child'.length; +- _addInsertEdit(childLoc, 'ren'); +- int listLoc = childArg.offset; +- String childArgSrc = getNodeText(childArg); +- if (!childArgSrc.contains(eol)) { +- _addInsertEdit(listLoc, '['); +- _addInsertEdit(listLoc + childArg.length, ']'); +- } else { +- int newlineLoc = childArgSrc.lastIndexOf(eol); +- if (newlineLoc == childArgSrc.length) { +- newlineLoc -= 1; +- } +- String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc); +- String indentNew = '$indentOld${getIndent(1)}'; +- // The separator includes 'child:' but that has no newlines. +- String separator = +- getText(namedExp.offset, childArg.offset - namedExp.offset); +- String prefix = separator.contains(eol) ? "" : "$eol$indentNew"; +- if (prefix.isEmpty) { +- _addInsertEdit(namedExp.offset + 'child:'.length, ' ['); +- _addRemoveEdit(new SourceRange(childArg.offset - 2, 2)); +- } else { +- _addInsertEdit(listLoc, '['); +- } +- String newChildArgSrc = childArgSrc.replaceAll( +- new RegExp("^$indentOld", multiLine: true), "$indentNew"); +- newChildArgSrc = "$prefix$newChildArgSrc,$eol$indentOld]"; +- _addReplaceEdit(rangeNode(childArg), newChildArgSrc); +- } +-} +- +-void convertChildToChildren2( +- DartFileEditBuilder builder, +- InstanceCreationExpression childArg, +- NamedExpression namedExp, +- String eol, +- Function getNodeText, +- Function getLinePrefix, +- Function getIndent, +- Function getText, +- Function rangeNode) { +- int childLoc = namedExp.offset + 'child'.length; +- builder.addSimpleInsertion(childLoc, 'ren'); +- int listLoc = childArg.offset; +- String childArgSrc = getNodeText(childArg); +- if (!childArgSrc.contains(eol)) { +- builder.addSimpleInsertion(listLoc, '['); +- builder.addSimpleInsertion(listLoc + childArg.length, ']'); +- } else { +- int newlineLoc = childArgSrc.lastIndexOf(eol); +- if (newlineLoc == childArgSrc.length) { +- newlineLoc -= 1; +- } +- String indentOld = getLinePrefix(childArg.offset + 1 + newlineLoc); +- String indentNew = '$indentOld${getIndent(1)}'; +- // The separator includes 'child:' but that has no newlines. +- String separator = +- getText(namedExp.offset, childArg.offset - namedExp.offset); +- String prefix = separator.contains(eol) ? "" : "$eol$indentNew"; +- if (prefix.isEmpty) { +- builder.addSimpleInsertion( +- namedExp.offset + 'child:'.length, ' ['); +- builder.addDeletion(new SourceRange(childArg.offset - 2, 2)); +- } else { +- builder.addSimpleInsertion(listLoc, '['); +- } +- String newChildArgSrc = childArgSrc.replaceAll( +- new RegExp("^$indentOld", multiLine: true), "$indentNew"); +- newChildArgSrc = "$prefix$newChildArgSrc,$eol$indentOld]"; +- builder.addSimpleReplacement(rangeNode(childArg), newChildArgSrc); +- } +-} +- +-/** +- * Return the named expression representing the 'child' argument of the given +- * [newExpr], or null if none. +- */ +-NamedExpression findChildArgument(InstanceCreationExpression newExpr) => +- newExpr.argumentList.arguments.firstWhere( +- (arg) => arg is NamedExpression && arg.name.label.name == 'child', +- orElse: () => null); +- +-/** +- * Return the Flutter instance creation expression that is the value of the +- * 'child' argument of the given [newExpr], or null if none. +- */ +-InstanceCreationExpression findChildWidget(InstanceCreationExpression newExpr) { +- NamedExpression child = findChildArgument(newExpr); +- return getChildWidget(child); +-} +- +-/** +- * If the given [node] is a simple identifier, find the named expression whose +- * name is the given [name] that is an argument to a Flutter instance creation +- * expression. Return null if any condition cannot be satisfied. +- */ +-NamedExpression findNamedExpression(AstNode node, String name) { +- if (node is! SimpleIdentifier) { +- return null; +- } +- SimpleIdentifier namedArg = node; +- NamedExpression namedExp; +- if (namedArg.parent is Label && namedArg.parent.parent is NamedExpression) { +- namedExp = namedArg.parent.parent; +- if (namedArg.name != name || namedExp.expression == null) { +- return null; +- } +- } else { +- return null; +- } +- if (namedExp.parent?.parent is! InstanceCreationExpression) { +- return null; +- } +- InstanceCreationExpression newExpr = namedExp.parent.parent; +- if (newExpr == null || !isWidgetCreation(newExpr)) { +- return null; +- } +- return namedExp; +-} +- +-ListLiteral getChildList(NamedExpression child) { +- if (child.expression is ListLiteral) { +- ListLiteral list = child.expression; +- if (list.elements.isEmpty || +- list.elements.every((element) => +- element is InstanceCreationExpression && +- isWidgetCreation(element))) { +- return list; +- } +- } +- return null; +-} +- +-/** +- * Return the Flutter instance creation expression that is the value of the +- * given [child], or null if none. If [strict] is true, require the value to +- * also have a 'child' argument. +- */ +-InstanceCreationExpression getChildWidget(NamedExpression child, +- [bool strict = false]) { +- if (child?.expression is InstanceCreationExpression) { +- InstanceCreationExpression childNewExpr = child.expression; +- if (isWidgetCreation(childNewExpr)) { +- if (!strict || (findChildArgument(childNewExpr) != null)) { +- return childNewExpr; +- } +- } +- } +- return null; +-} +- +-/** +- * Return the presentation for the given Flutter `Widget` creation [node]. +- */ +-String getWidgetPresentationText(InstanceCreationExpression node) { +- ClassElement element = node.staticElement?.enclosingElement; +- if (!isWidget(element)) { +- return null; +- } +- List arguments = node.argumentList.arguments; +- if (_isExactWidget( +- element, 'Icon', 'package:flutter/src/widgets/icon.dart')) { +- if (arguments.isNotEmpty) { +- String text = arguments[0].toString(); +- String arg = shorten(text, 32); +- return 'Icon($arg)'; +- } else { +- return 'Icon'; +- } +- } +- if (_isExactWidget( +- element, 'Text', 'package:flutter/src/widgets/text.dart')) { +- if (arguments.isNotEmpty) { +- String text = arguments[0].toString(); +- String arg = shorten(text, 32); +- return 'Text($arg)'; +- } else { +- return 'Text'; +- } +- } +- return element.name; +-} +- +-/** +- * Return the instance creation expression that surrounds the given +- * [node], if any, else null. The [node] may be the instance creation +- * expression itself or the identifier that names the constructor. +- */ +-InstanceCreationExpression identifyNewExpression(AstNode node) { +- InstanceCreationExpression newExpr; +- if (node is SimpleIdentifier) { +- if (node.parent is ConstructorName && +- node.parent.parent is InstanceCreationExpression) { +- newExpr = node.parent.parent; +- } else if (node.parent?.parent is ConstructorName && +- node.parent.parent?.parent is InstanceCreationExpression) { +- newExpr = node.parent.parent.parent; +- } +- } else if (node is InstanceCreationExpression) { +- newExpr = node; +- } +- return newExpr; +-} +- +-/** +- * Return `true` if the given [element] has the Flutter class `Widget` as +- * a superclass. +- */ +-bool isWidget(ClassElement element) { +- if (element == null) { +- return false; +- } +- for (InterfaceType type in element.allSupertypes) { +- if (type.name == _WIDGET_NAME) { +- Uri uri = type.element.source.uri; +- if (uri.toString() == _WIDGET_URI) { +- return true; +- } +- } +- } +- return false; +-} +- +-/** +- * Return `true` if the given [expr] is a constructor invocation for a +- * class that has the Flutter class `Widget` as a superclass. +- */ +-bool isWidgetCreation(InstanceCreationExpression expr) { +- ClassElement element = expr.staticElement?.enclosingElement; +- return isWidget(element); +-} +- +-/** +- * Return `true` if the given [element] is the exact [type] defined in the +- * file with the given [uri]. +- */ +-bool _isExactWidget(ClassElement element, String type, String uri) { +- return element != null && +- element.name == type && +- element.source.uri.toString() == uri; +-} +diff --git a/pkg/analysis_server/lib/src/utilities/null_string_sink.dart b/pkg/analysis_server/lib/src/utilities/null_string_sink.dart +deleted file mode 100644 +index 27fef3a0682..00000000000 +--- a/pkg/analysis_server/lib/src/utilities/null_string_sink.dart ++++ /dev/null +@@ -1,13 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-/** +- * A string sink that ignores everything written to it. +- */ +-class NullStringSink implements StringSink { +- void write(Object obj) {} +- void writeAll(Iterable objects, [String separator = ""]) {} +- void writeCharCode(int charCode) {} +- void writeln([Object obj = ""]) {} +-} +diff --git a/pkg/analysis_server/lib/src/utilities/profiling.dart b/pkg/analysis_server/lib/src/utilities/profiling.dart +deleted file mode 100644 +index 7e2e49bc626..00000000000 +--- a/pkg/analysis_server/lib/src/utilities/profiling.dart ++++ /dev/null +@@ -1,89 +0,0 @@ +-// 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:io'; +- +-/// A class that can return memory and cpu usage information for a given +-/// process. +-abstract class ProcessProfiler { +- ProcessProfiler._(); +- +- Future getProcessUsage(int processId); +- +- UsageInfo getProcessUsageSync(int processId); +- +- /// Return a [ProcessProfiler] instance suitable for the current host +- /// platform. This can return `null` if we're not able to gather memory and +- /// cpu information for the current platform. +- static ProcessProfiler getProfilerForPlatform() { +- if (Platform.isLinux || Platform.isMacOS) { +- return new _PosixProcessProfiler(); +- } +- +- // Not a supported platform. +- return null; +- } +-} +- +-class UsageInfo { +- /// A number between 0.0 and 100.0 * the number of host CPUs (but typically +- /// never more than slightly above 100.0). +- final double cpuPercentage; +- +- /// The process memory usage in kilobytes. +- final int memoryKB; +- +- UsageInfo(this.cpuPercentage, this.memoryKB); +- +- double get memoryMB => memoryKB / 1024; +- +- String toString() => '$cpuPercentage% ${memoryMB.toStringAsFixed(1)}MB'; +-} +- +-class _PosixProcessProfiler extends ProcessProfiler { +- static final RegExp stringSplitRegExp = new RegExp(r'\s+'); +- +- _PosixProcessProfiler() : super._(); +- +- @override +- Future getProcessUsage(int processId) { +- try { +- // Execution time is typically 2-4ms. +- Future future = +- Process.run('ps', ['-o', '%cpu=,rss=', processId.toString()]); +- return future.then((ProcessResult result) { +- if (result.exitCode != 0) { +- return new Future.value(null); +- } +- +- return new Future.value(_parse(result.stdout)); +- }); +- } catch (e) { +- return new Future.error(e); +- } +- } +- +- UsageInfo getProcessUsageSync(int processId) { +- try { +- // Execution time is typically 2-4ms. +- ProcessResult result = +- Process.runSync('ps', ['-o', '%cpu=,rss=', processId.toString()]); +- return result.exitCode == 0 ? _parse(result.stdout) : null; +- } catch (e) { +- return null; +- } +- } +- +- UsageInfo _parse(String psResults) { +- try { +- // " 0.0 378940" +- String line = psResults.split('\n').first.trim(); +- List values = line.split(stringSplitRegExp); +- return new UsageInfo(double.parse(values[0]), int.parse(values[1])); +- } catch (e) { +- return null; +- } +- } +-} +diff --git a/pkg/analysis_server/lib/src/watch_manager.dart b/pkg/analysis_server/lib/src/watch_manager.dart +deleted file mode 100644 +index 8a3fc97d809..00000000000 +--- a/pkg/analysis_server/lib/src/watch_manager.dart ++++ /dev/null +@@ -1,285 +0,0 @@ +-// Copyright (c) 2015, 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 'dart:core'; +- +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:watcher/watcher.dart'; +- +-/** +- * A function called when a watch [event] associated with a watched resource is +- * received. The list of [tokens] will contain all of the tokens associated with +- * folders containing (or the same as) the watched resource. +- */ +-typedef void HandleWatchEvent(WatchEvent event, List tokens); +- +-/** +- * An object that manages a collections of folders that need to be watched in +- * order to ensure that we are watching the minimum number of folders. +- * +- * Each folder can be watched multiple times. In order to differentiate between +- * the watch requests, each watch request has a *token* associated with it. The +- * tokens that are used must correctly implement both [==] and [hashCode]. +- */ +-class WatchManager { +- /** +- * The resource provider used to convert paths to resources. +- */ +- final ResourceProvider provider; +- +- /** +- * The function that is invoked when a watch event is received. +- */ +- final HandleWatchEvent handleWatchEvent; +- +- /** +- * A node representing the (conceptual) root of all other folders. +- */ +- final WatchNode rootNode = new WatchNode(null); +- +- /** +- * A table mapping the folders that are being watched to the nodes +- * representing those folders. +- */ +- final Map> _watchedFolders = +- new HashMap>(); +- +- /** +- * Initialize a newly created watch manager to use the resource [provider] to +- * convert file paths to resources and to call the [handleWatchEvent] function +- * to notify the owner of the manager when resources have been changed. +- */ +- WatchManager(this.provider, this.handleWatchEvent); +- +- /** +- * Record the fact that we are now watching the given [folder], and associate +- * that folder with the given [token]. If the folder is already being watched +- * and is already associated with the token, then this request is effectively +- * ignored. +- */ +- void addFolder(Folder folder, T token) { +- WatchNode folderNode = _watchedFolders[folder]; +- // +- // If the folder was already being watched, just record the new token. +- // +- if (folderNode != null) { +- folderNode.tokens.add(token); +- return; +- } +- // +- // Otherwise, add the folder to the tree. +- // +- folderNode = new WatchNode(folder); +- _watchedFolders[folder] = folderNode; +- folderNode.tokens.add(token); +- WatchNode parentNode = rootNode.insert(folderNode); +- // +- // If we are not watching a folder that contains the folder, then create a +- // subscription for it. +- // +- if (parentNode == rootNode) { +- folderNode.subscription = folder.changes.listen(_handleWatchEvent); +- // +- // Any nodes that became children of the newly added folder would have +- // been top-level folders and would have been watched. We need to cancel +- // their subscriptions. +- // +- for (WatchNode childNode in folderNode.children) { +- assert(childNode.subscription != null); +- if (childNode.subscription != null) { +- childNode.subscription.cancel(); +- childNode.subscription = null; +- } +- } +- } +- } +- +- /** +- * Record that we are no longer watching the given [folder] with the given +- * [token]. +- * +- * Throws a [StateError] if the folder is not be watched or is not associated +- * with the given token. +- */ +- void removeFolder(Folder folder, T token) { +- WatchNode folderNode = _watchedFolders[folder]; +- if (folderNode == null) { +- assert(false); +- return; +- } +- Set tokens = folderNode.tokens; +- if (!tokens.remove(token)) { +- assert(false); +- } +- // +- // If this was the last token associated with this folder, then remove the +- // folder from the tree. +- // +- if (tokens.isEmpty) { +- // +- // If the folder was a top-level folder, then we need to create +- // subscriptions for all of its children and cancel its subscription. +- // +- if (folderNode.subscription != null) { +- for (WatchNode childNode in folderNode.children) { +- assert(childNode.subscription == null); +- childNode.subscription = +- childNode.folder.changes.listen(_handleWatchEvent); +- } +- folderNode.subscription.cancel(); +- folderNode.subscription = null; +- } +- folderNode.delete(); +- _watchedFolders.remove(folder); +- } +- } +- +- /** +- * Dispatch the given event by finding all of the tokens that contain the +- * resource and invoke the [handleWatchEvent] function. +- */ +- void _handleWatchEvent(WatchEvent event) { +- String path = event.path; +- List tokens = []; +- WatchNode parent = rootNode.findParent(path); +- while (parent != rootNode) { +- tokens.addAll(parent.tokens); +- parent = parent.parent; +- } +- if (tokens.isNotEmpty) { +- handleWatchEvent(event, tokens); +- } +- } +-} +- +-/** +- * The information kept by a [WatchManager] about a single folder that is being +- * watched. +- * +- * Watch nodes form a tree in which one node is a child of another node if the +- * child's folder is contained in the parent's folder and none of the folders +- * between the parent's folder and the child's folder are being watched. +- */ +-class WatchNode { +- /** +- * The folder for which information is being maintained. This is `null` for +- * the unique "root" node that maintains references to all of the top-level +- * folders being watched. +- */ +- final Folder folder; +- +- /** +- * The parent of this node. +- */ +- WatchNode parent; +- +- /** +- * The information for the children of this node. +- */ +- final List> _children = >[]; +- +- /** +- * The tokens that were used to register interest in watching this folder. +- */ +- final Set tokens = new HashSet(); +- +- /** +- * The subscription being used to watch the folder, or `null` if the folder +- * is being watched as part of a containing folder (in other words, if the +- * parent is not the special "root"). +- */ +- StreamSubscription subscription; +- +- /** +- * Initialize a newly created node to represent the given [folder]. +- */ +- WatchNode(this.folder); +- +- /** +- * Return a list containing the children of this node. +- */ +- Iterable> get children => _children; +- +- /** +- * Remove this node from the tree of watched folders. +- */ +- void delete() { +- if (parent != null) { +- parent._removeChild(this); +- parent = null; +- } +- } +- +- /** +- * Return the highest node reachable from this node that contains the given +- * [filePath]. If no other node is found, return this node, even if this node +- * does not contain the path. +- */ +- WatchNode findParent(String filePath) { +- if (_children == null) { +- return this; +- } +- for (WatchNode childNode in _children) { +- if (childNode.folder.isOrContains(filePath)) { +- return childNode.findParent(filePath); +- } +- } +- return this; +- } +- +- /** +- * Insert the given [node] into the tree of watched folders, either as a child +- * of this node or as a descendent of one of this node's children. Return the +- * immediate parent of the newly added node. +- */ +- WatchNode insert(WatchNode node) { +- WatchNode parentNode = findParent(node.folder.path); +- parentNode._addChild(node, true); +- return parentNode; +- } +- +- @override +- String toString() => 'WatchNode (' +- 'folder = ${folder == null ? '' : folder.path}, ' +- 'tokens = $tokens, ' +- 'subscription = ${subscription == null ? 'null' : 'non-null'})'; +- +- /** +- * Add the given [newChild] as an immediate child of this node. +- * +- * If [checkChildren] is `true`, check to see whether any of the previously +- * existing children of this node should now be children of the new child, and +- * if so, move them. +- */ +- void _addChild(WatchNode newChild, bool checkChildren) { +- if (checkChildren) { +- Folder folder = newChild.folder; +- for (int i = _children.length - 1; i >= 0; i--) { +- WatchNode existingChild = _children[i]; +- if (folder.contains(existingChild.folder.path)) { +- newChild._addChild(existingChild, false); +- _children.removeAt(i); +- } +- } +- } +- newChild.parent = this; +- _children.add(newChild); +- } +- +- /** +- * Remove the given [node] from the list of children of this node. Any +- * children of the [node] will become children of this node. +- */ +- void _removeChild(WatchNode child) { +- _children.remove(child); +- Iterable> grandchildren = child.children; +- for (WatchNode grandchild in grandchildren) { +- grandchild.parent = this; +- _children.add(grandchild); +- } +- child._children.clear(); +- } +-} +diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart +deleted file mode 100644 +index cca06dab3a8..00000000000 +--- a/pkg/analysis_server/lib/starter.dart ++++ /dev/null +@@ -1,49 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/server/driver.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/plugin/resolver_provider.dart'; +- +-/** +- * An object that can be used to start an analysis server. This class exists so +- * that clients can configure an analysis server before starting it. +- * +- * Clients may not extend, implement or mix-in this class. +- */ +-abstract class ServerStarter { +- /** +- * Initialize a newly created starter to start up an analysis server. +- */ +- factory ServerStarter() = Driver; +- +- /** +- * Set the file resolver provider used to override the way file URI's +- * are resolved in some contexts. The provider should return `null` if the +- * default file resolution scheme should be used instead. +- */ +- void set fileResolverProvider(ResolverProvider provider); +- +- /** +- * Set the instrumentation [server] that is to be used by the analysis server. +- */ +- void set instrumentationServer(InstrumentationServer server); +- +- /** +- * Set the package resolver provider used to override the way package URI's +- * are resolved in some contexts. The provider should return `null` if the +- * default package resolution scheme should be used instead. +- */ +- void set packageResolverProvider(ResolverProvider provider); +- +- /** +- * Use the given command-line [arguments] to start this server. +- * +- * At least temporarily returns AnalysisServer so that consumers of the +- * starter API can then use the server, this is done as a stopgap for the +- * angular plugin until the official plugin API is finished. +- */ +- AnalysisServer start(List arguments); +-} +diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml +deleted file mode 100644 +index 5a920345285..00000000000 +--- a/pkg/analysis_server/pubspec.yaml ++++ /dev/null +@@ -1,27 +0,0 @@ +-name: analysis_server +-version: 0.1.1-dev +-author: Dart Team +-description: A server that performs analysis of Dart code over character streams using JSON-RPC encoded information. +-homepage: http://www.dartlang.org +-environment: +- sdk: '>=1.12.0 <2.0.0' +-dependencies: +- analyzer: ^0.30.0 +- args: '>=0.13.0 <0.14.0' +- dart_style: '^1.0.6' +- intl: ^0.15.0 +- isolate: '>=0.2.2 <2.0.0' +- linter: ^0.1.16 +- logging: any +- package_config: '>=0.1.5 <2.0.0' +- path: any +- plugin: ^0.2.0 +- telemetry: ^0.0.1 +- usage: ^3.2.0+1 +- watcher: any +- yaml: any +-dev_dependencies: +- html: any +- test_reflective_loader: ^0.1.0 +- mockito: ^2.0.2 +- test: ^0.12.17 +diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart +deleted file mode 100644 +index 850f2ca7d1d..00000000000 +--- a/pkg/analysis_server/test/abstract_context.dart ++++ /dev/null +@@ -1,172 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/dart/element/visitor.dart'; +-import 'package:analyzer/exception/exception.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/file_state.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/engine.dart' as engine; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source_io.dart'; +-import 'package:front_end/byte_store.dart'; +-import 'package:front_end/src/base/performance_logger.dart'; +- +-import 'mock_sdk.dart'; +- +-/** +- * Finds an [Element] with the given [name]. +- */ +-Element findChildElement(Element root, String name, [ElementKind kind]) { +- Element result = null; +- root.accept(new _ElementVisitorFunctionWrapper((Element element) { +- if (element.name != name) { +- return; +- } +- if (kind != null && element.kind != kind) { +- return; +- } +- result = element; +- })); +- return result; +-} +- +-/** +- * A function to be called for every [Element]. +- */ +-typedef void _ElementVisitorFunction(Element element); +- +-class AbstractContextTest { +- MemoryResourceProvider provider; +- DartSdk sdk; +- Map> packageMap; +- UriResolver resourceResolver; +- +- StringBuffer _logBuffer = new StringBuffer(); +- FileContentOverlay _fileContentOverlay = new FileContentOverlay(); +- AnalysisDriver _driver; +- +- AnalysisDriver get driver => _driver; +- +- Source addMetaPackageSource() => addPackageSource('meta', 'meta.dart', r''' +-library meta; +- +-const Required required = const Required(); +- +-class Required { +- final String reason; +- const Required([this.reason]); +-} +-'''); +- +- Source addPackageSource(String packageName, String filePath, String content) { +- packageMap[packageName] = [(newFolder('/pubcache/$packageName/lib'))]; +- File file = newFile('/pubcache/$packageName/lib/$filePath', content); +- return file.createSource(); +- } +- +- Source addSource(String path, String content, [Uri uri]) { +- if (path.startsWith('/')) { +- path = provider.convertPath(path); +- } +- File file = newFile(path, content); +- Source source = file.createSource(uri); +- driver.addFile(path); +- driver.changeFile(path); +- _fileContentOverlay[path] = content; +- return source; +- } +- +- File newFile(String path, [String content]) => +- provider.newFile(provider.convertPath(path), content ?? ''); +- +- Folder newFolder(String path) => +- provider.newFolder(provider.convertPath(path)); +- +- void processRequiredPlugins() { +- AnalysisEngine.instance.processRequiredPlugins(); +- } +- +- Future resolveLibraryUnit(Source source) async { +- return (await driver.getResult(source.fullName))?.unit; +- } +- +- void setUp() { +- processRequiredPlugins(); +- setupResourceProvider(); +- sdk = new MockSdk(resourceProvider: provider); +- resourceResolver = new ResourceUriResolver(provider); +- packageMap = new Map>(); +- PackageMapUriResolver packageResolver = +- new PackageMapUriResolver(provider, packageMap); +- SourceFactory sourceFactory = new SourceFactory( +- [new DartUriResolver(sdk), packageResolver, resourceResolver]); +- PerformanceLog log = new PerformanceLog(_logBuffer); +- AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log); +- _driver = new AnalysisDriver( +- scheduler, +- log, +- provider, +- new MemoryByteStore(), +- _fileContentOverlay, +- null, +- sourceFactory, +- new AnalysisOptionsImpl()..strongMode = true); +- scheduler.start(); +- AnalysisEngine.instance.logger = PrintLogger.instance; +- } +- +- void setupResourceProvider() { +- provider = new MemoryResourceProvider(); +- } +- +- void tearDown() { +- provider = null; +- AnalysisEngine.instance.clearCaches(); +- AnalysisEngine.instance.logger = null; +- } +-} +- +-/** +- * Instances of the class [PrintLogger] print all of the errors. +- */ +-class PrintLogger implements Logger { +- static final Logger instance = new PrintLogger(); +- +- @override +- void logError(String message, [CaughtException exception]) { +- print(message); +- if (exception != null) { +- print(exception); +- } +- } +- +- @override +- void logInformation(String message, [CaughtException exception]) { +- print(message); +- if (exception != null) { +- print(exception); +- } +- } +-} +- +-/** +- * Wraps the given [_ElementVisitorFunction] into an instance of +- * [engine.GeneralizingElementVisitor]. +- */ +-class _ElementVisitorFunctionWrapper extends GeneralizingElementVisitor { +- final _ElementVisitorFunction function; +- _ElementVisitorFunctionWrapper(this.function); +- visitElement(Element element) { +- function(element); +- super.visitElement(element); +- } +-} +diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart +deleted file mode 100644 +index 86601445dfe..00000000000 +--- a/pkg/analysis_server/test/abstract_single_unit.dart ++++ /dev/null +@@ -1,144 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/visitor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/ast/utilities.dart'; +-import 'package:analyzer/src/dart/error/hint_codes.dart'; +-import 'package:analyzer/src/generated/java_engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:test/test.dart'; +- +-import 'abstract_context.dart'; +- +-class AbstractSingleUnitTest extends AbstractContextTest { +- bool verifyNoTestUnitErrors = true; +- +- String testCode; +- String testFile = '/test.dart'; +- Source testSource; +- CompilationUnit testUnit; +- CompilationUnitElement testUnitElement; +- LibraryElement testLibraryElement; +- +- void addTestSource(String code, [Uri uri]) { +- testCode = code; +- testSource = addSource(testFile, code, uri); +- } +- +- Element findElement(String name, [ElementKind kind]) { +- return findChildElement(testUnitElement, name, kind); +- } +- +- int findEnd(String search) { +- return findOffset(search) + search.length; +- } +- +- /** +- * Returns the [SimpleIdentifier] at the given search pattern. +- */ +- SimpleIdentifier findIdentifier(String search) { +- return findNodeAtString(search, (node) => node is SimpleIdentifier); +- } +- +- /** +- * Search the [testUnit] for the [LocalVariableElement] with the given [name]. +- * Fail if there is not exactly one such variable. +- */ +- LocalVariableElement findLocalVariable(String name) { +- var finder = new _ElementsByNameFinder(name); +- testUnit.accept(finder); +- List localVariables = +- finder.elements.where((e) => e is LocalVariableElement).toList(); +- expect(localVariables, hasLength(1)); +- return localVariables[0]; +- } +- +- AstNode findNodeAtOffset(int offset, [Predicate predicate]) { +- AstNode result = new NodeLocator(offset).searchWithin(testUnit); +- if (result != null && predicate != null) { +- result = result.getAncestor(predicate); +- } +- return result; +- } +- +- AstNode findNodeAtString(String search, [Predicate predicate]) { +- int offset = findOffset(search); +- return findNodeAtOffset(offset, predicate); +- } +- +- Element findNodeElementAtString(String search, +- [Predicate predicate]) { +- AstNode node = findNodeAtString(search, predicate); +- if (node == null) { +- return null; +- } +- return ElementLocator.locate(node); +- } +- +- int findOffset(String search) { +- int offset = testCode.indexOf(search); +- expect(offset, isNonNegative, reason: "Not found '$search' in\n$testCode"); +- return offset; +- } +- +- int getLeadingIdentifierLength(String search) { +- int length = 0; +- while (length < search.length) { +- int c = search.codeUnitAt(length); +- if (c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0)) { +- length++; +- continue; +- } +- if (c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0)) { +- length++; +- continue; +- } +- if (c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0)) { +- length++; +- continue; +- } +- break; +- } +- return length; +- } +- +- Future resolveTestUnit(String code) async { +- addTestSource(code); +- AnalysisResult result = await driver.getResult(testFile); +- testUnit = result.unit; +- if (verifyNoTestUnitErrors) { +- expect(result.errors.where((AnalysisError error) { +- return error.errorCode != HintCode.DEAD_CODE && +- error.errorCode != HintCode.UNUSED_CATCH_CLAUSE && +- error.errorCode != HintCode.UNUSED_CATCH_STACK && +- error.errorCode != HintCode.UNUSED_ELEMENT && +- error.errorCode != HintCode.UNUSED_FIELD && +- error.errorCode != HintCode.UNUSED_IMPORT && +- error.errorCode != HintCode.UNUSED_LOCAL_VARIABLE; +- }), isEmpty); +- } +- testUnitElement = testUnit.element; +- testLibraryElement = testUnitElement.library; +- } +-} +- +-class _ElementsByNameFinder extends RecursiveAstVisitor { +- final String name; +- final List elements = []; +- +- _ElementsByNameFinder(this.name); +- +- @override +- visitSimpleIdentifier(SimpleIdentifier node) { +- if (node.name == name && node.inDeclarationContext()) { +- elements.add(node.staticElement); +- } +- } +-} +diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart +deleted file mode 100644 +index 431f5ed7651..00000000000 +--- a/pkg/analysis_server/test/analysis/get_errors_test.dart ++++ /dev/null +@@ -1,150 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetErrorsTest); +- }); +-} +- +-@reflectiveTest +-class GetErrorsTest extends AbstractAnalysisTest { +- static const String requestId = 'test-getError'; +- +- @override +- void setUp() { +- super.setUp(); +- server.handlers = [ +- new AnalysisDomainHandler(server), +- ]; +- createProject(); +- } +- +- test_afterAnalysisComplete() async { +- addTestFile(''' +-main() { +- print(42) +-} +-'''); +- await waitForTasksFinished(); +- List errors = await _getErrors(testFile); +- expect(errors, hasLength(1)); +- } +- +- test_errorInPart() async { +- String libPath = '$testFolder/main.dart'; +- String partPath = '$testFolder/main_part.dart'; +- addFile(libPath, r''' +-library main; +-part 'main_part.dart'; +-class A {} +-'''); +- addFile(partPath, r''' +-part of main; +-class A {} +-'''); +- await waitForTasksFinished(); +- { +- List libErrors = await _getErrors(libPath); +- expect(libErrors, isEmpty); +- } +- { +- List partErrors = await _getErrors(partPath); +- expect(partErrors, hasLength(1)); +- } +- } +- +- @failingTest +- test_fileDoesNotExist() { +- // Broken under the new driver. +- String file = '$projectPath/doesNotExist.dart'; +- return _checkInvalid(file); +- } +- +- @failingTest +- test_fileWithoutContext() { +- // Broken under the new driver. +- String file = '/outside.dart'; +- addFile(file, ''' +-main() { +- print(42); +-} +-'''); +- return _checkInvalid(file); +- } +- +- test_hasErrors() async { +- addTestFile(''' +-main() { +- print(42) +-} +-'''); +- List errors = await _getErrors(testFile); +- expect(errors, hasLength(1)); +- { +- AnalysisError error = errors[0]; +- expect(error.severity, AnalysisErrorSeverity.ERROR); +- expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR); +- expect(error.location.file, testFile); +- expect(error.location.startLine, 2); +- } +- } +- +- test_noErrors() async { +- addTestFile(''' +-main() { +- print(42); +-} +-'''); +- List errors = await _getErrors(testFile); +- expect(errors, isEmpty); +- } +- +- @failingTest +- test_removeContextAfterRequest() async { +- // Broken under the new driver. +- addTestFile(''' +-main() { +- print(42) +-} +-'''); +- // handle the request synchronously +- Request request = _createGetErrorsRequest(testFile); +- server.handleRequest(request); +- // remove context, causes sending an "invalid file" error +- resourceProvider.deleteFolder(projectPath); +- // wait for an error response +- Response response = await serverChannel.waitForResponse(request); +- expect(response.error, isNotNull); +- expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE); +- } +- +- Future _checkInvalid(String file) async { +- Request request = _createGetErrorsRequest(file); +- Response response = await serverChannel.sendRequest(request); +- expect(response.error, isNotNull); +- expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE); +- } +- +- Request _createGetErrorsRequest(String file) { +- return new AnalysisGetErrorsParams(file).toRequest(requestId); +- } +- +- Future> _getErrors(String file) async { +- Request request = _createGetErrorsRequest(file); +- Response response = await serverChannel.sendRequest(request); +- return new AnalysisGetErrorsResult.fromResponse(response).errors; +- } +-} +diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart +deleted file mode 100644 +index 64cb212a4ea..00000000000 +--- a/pkg/analysis_server/test/analysis/get_hover_test.dart ++++ /dev/null +@@ -1,562 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisHoverTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisHoverTest extends AbstractAnalysisTest { +- Future prepareHover(String search) { +- int offset = findOffset(search); +- return prepareHoverAt(offset); +- } +- +- Future prepareHoverAt(int offset) async { +- await waitForTasksFinished(); +- Request request = +- new AnalysisGetHoverParams(testFile, offset).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new AnalysisGetHoverResult.fromResponse(response); +- List hovers = result.hovers; +- return hovers.isNotEmpty ? hovers.first : null; +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- test_class() async { +- addTestFile(''' +-class A {} +-class I1 {} +-class I2 {} +-class M1 {} +-class M2 {} +-class B extends A with M1, M2 implements I1, I2 {} +-'''); +- HoverInformation hover = await prepareHover('B'); +- expect( +- hover.elementDescription, +- 'class B extends A with M1, M2 ' +- 'implements I1, I2'); +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- } +- +- test_class_abstract() async { +- addTestFile(''' +-class A {} +-abstract class B extends A {} +-'''); +- HoverInformation hover = await prepareHover('B extends'); +- expect(hover.elementDescription, 'abstract class B extends A'); +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- } +- +- test_dartdoc_clunky() async { +- addTestFile(''' +-library my.library; +-/** +- * doc aaa +- * doc bbb +- */ +-main() { +-} +-'''); +- HoverInformation hover = await prepareHover('main() {'); +- expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); +- } +- +- test_dartdoc_elegant() async { +- addTestFile(''' +-library my.library; +-/// doc aaa +-/// doc bbb +-main() { +-} +-'''); +- HoverInformation hover = await prepareHover('main() {'); +- expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); +- } +- +- test_dartdoc_inherited_methodByMethod_fromInterface() async { +- addTestFile(''' +-class A { +- /// my doc +- m() {} // in A +-} +- +-class B implements A { +- m() {} // in B +-} +-'''); +- HoverInformation hover = await prepareHover('m() {} // in B'); +- expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); +- } +- +- test_dartdoc_inherited_methodByMethod_fromSuper_direct() async { +- addTestFile(''' +-class A { +- /// my doc +- m() {} // in A +-} +- +-class B extends A { +- m() {} // in B +-} +-'''); +- HoverInformation hover = await prepareHover('m() {} // in B'); +- expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); +- } +- +- test_dartdoc_inherited_methodByMethod_fromSuper_indirect() async { +- addTestFile(''' +-class A { +- /// my doc +- m() {} +-} +-class B extends A { +- m() {} +-} +-class C extends B { +- m() {} // in C +-}'''); +- HoverInformation hover = await prepareHover('m() {} // in C'); +- expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); +- } +- +- test_dartdoc_inherited_methodByMethod_preferSuper() async { +- addTestFile(''' +-class A { +- /// my doc +- m() {} +-} +-class B extends A { +-} +-class I { +- // wrong doc +- m() {} +-} +-class C extends B implements I { +- m() {} // in C +-}'''); +- HoverInformation hover = await prepareHover('m() {} // in C'); +- expect(hover.dartdoc, '''my doc\n\nCopied from `A`.'''); +- } +- +- test_enum() async { +- addTestFile(''' +-enum MyEnum {AAA, BBB, CCC} +-'''); +- HoverInformation hover = await prepareHover('MyEnum'); +- expect(hover.elementDescription, 'enum MyEnum'); +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- } +- +- test_expression_function() async { +- addTestFile(''' +-library my.library; +-/// doc aaa +-/// doc bbb +-List fff(int a, String b) { +-} +-'''); +- HoverInformation hover = await prepareHover('fff(int a'); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.containingClassDescription, isNull); +- expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); +- expect(hover.elementDescription, 'fff(int a, String b) → List'); +- expect(hover.elementKind, 'function'); +- // types +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_expression_literal_noElement() async { +- addTestFile(''' +-main() { +- foo(123); +-} +-foo(Object myParameter) {} +-'''); +- HoverInformation hover = await prepareHover('123'); +- // literal, no Element +- expect(hover.containingClassDescription, isNull); +- expect(hover.elementDescription, isNull); +- expect(hover.elementKind, isNull); +- // types +- expect(hover.staticType, 'int'); +- expect(hover.propagatedType, isNull); +- // parameter +- expect(hover.parameter, 'Object myParameter'); +- } +- +- test_expression_method() async { +- addTestFile(''' +-library my.library; +-class A { +- /// doc aaa +- /// doc bbb +- List mmm(int a, String b) { +- } +-} +-'''); +- HoverInformation hover = await prepareHover('mmm(int a'); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.containingClassDescription, 'A'); +- expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); +- expect(hover.elementDescription, 'mmm(int a, String b) → List'); +- expect(hover.elementKind, 'method'); +- // types +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_expression_method_deprecated() async { +- addTestFile(''' +-class A { +- @deprecated +- static void test() {} +-} +-main() { +- A.test(); +-} +-'''); +- HoverInformation hover = await prepareHover('test();'); +- // element +- expect(hover.containingLibraryPath, testFile); +- expect(hover.elementDescription, 'test() → void'); +- expect(hover.elementKind, 'method'); +- expect(hover.isDeprecated, isTrue); +- } +- +- test_expression_method_invocation() async { +- addTestFile(''' +-library my.library; +-class A { +- List mmm(int a, String b) { +- } +-} +-main(A a) { +- a.mmm(42, 'foo'); +-} +-'''); +- HoverInformation hover = await prepareHover('mm(42, '); +- // range +- expect(hover.offset, findOffset('mmm(42, ')); +- expect(hover.length, 'mmm'.length); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.elementDescription, 'mmm(int a, String b) → List'); +- expect(hover.elementKind, 'method'); +- expect(hover.isDeprecated, isFalse); +- // types +- expect(hover.staticType, '(int, String) → List'); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_expression_method_invocation_genericMethod() async { +- addTestFile(''' +-library my.library; +- +-abstract class Stream { +- Stream transform(StreamTransformer streamTransformer); +-} +-abstract class StreamTransformer {} +- +-f(Stream s) { +- s.transform(null); +-} +-'''); +- HoverInformation hover = await prepareHover('nsform(n'); +- // range +- expect(hover.offset, findOffset('transform(n')); +- expect(hover.length, 'transform'.length); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.elementDescription, +- 'Stream.transform(StreamTransformer streamTransformer) → Stream'); +- expect(hover.elementKind, 'method'); +- expect(hover.isDeprecated, isFalse); +- // types +- expect(hover.staticType, +- '(StreamTransformer) → Stream'); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_expression_parameter() async { +- addTestFile(''' +-library my.library; +-class A { +- /// The method documentation. +- m(int p) { +- } +-} +-'''); +- HoverInformation hover = await prepareHover('p) {'); +- // element +- expect(hover.containingLibraryName, isNull); +- expect(hover.containingLibraryPath, isNull); +- expect(hover.containingClassDescription, isNull); +- expect(hover.dartdoc, 'The method documentation.'); +- expect(hover.elementDescription, 'int p'); +- expect(hover.elementKind, 'parameter'); +- // types +- expect(hover.staticType, 'int'); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_expression_parameter_fieldFormal_declaration() async { +- addTestFile(''' +-class A { +- /// The field documentation. +- final int fff; +- A({this.fff}); +-} +-main() { +- new A(fff: 42); +-} +-'''); +- HoverInformation hover = await prepareHover('fff});'); +- expect(hover.containingLibraryName, isNull); +- expect(hover.containingLibraryPath, isNull); +- expect(hover.containingClassDescription, isNull); +- expect(hover.dartdoc, 'The field documentation.'); +- expect(hover.elementDescription, '{int fff}'); +- expect(hover.elementKind, 'parameter'); +- expect(hover.staticType, 'int'); +- } +- +- test_expression_parameter_fieldFormal_use() async { +- addTestFile(''' +-class A { +- /// The field documentation. +- final int fff; +- A({this.fff}); +-} +-main() { +- new A(fff: 42); +-} +-'''); +- HoverInformation hover = await prepareHover('fff: 42'); +- expect(hover.containingLibraryName, isNull); +- expect(hover.containingLibraryPath, isNull); +- expect(hover.containingClassDescription, isNull); +- expect(hover.dartdoc, 'The field documentation.'); +- expect(hover.elementDescription, '{int fff}'); +- expect(hover.elementKind, 'parameter'); +- expect(hover.staticType, 'int'); +- } +- +- test_expression_syntheticGetter_invocation() async { +- addTestFile(''' +-library my.library; +-class A { +- /// doc aaa +- /// doc bbb +- String fff; +-} +-main(A a) { +- print(a.fff); +-} +-'''); +- HoverInformation hover = await prepareHover('fff);'); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.containingClassDescription, 'A'); +- expect(hover.dartdoc, '''doc aaa\ndoc bbb'''); +- expect(hover.elementDescription, 'String fff'); +- expect(hover.elementKind, 'field'); +- // types +- expect(hover.staticType, 'String'); +- expect(hover.propagatedType, isNull); +- } +- +- test_expression_variable_hasPropagatedType() async { +- addTestFile(''' +-library my.library; +-main() { +- var vvv = 123; +- print(vvv); +-} +-'''); +- HoverInformation hover = await prepareHover('vvv);'); +- // element +- expect(hover.containingLibraryName, isNull); +- expect(hover.containingLibraryPath, isNull); +- expect(hover.containingClassDescription, isNull); +- expect(hover.dartdoc, isNull); +- expect(hover.elementDescription, 'dynamic vvv'); +- expect(hover.elementKind, 'local variable'); +- // types +- expect(hover.staticType, 'dynamic'); +- expect(hover.propagatedType, 'int'); +- } +- +- test_expression_variable_inMethod() async { +- addTestFile(''' +-library my.library; +-class A { +- m() { +- num vvv = 42; +- } +-} +-'''); +- HoverInformation hover = await prepareHover('vvv = 42'); +- // element +- expect(hover.containingLibraryName, isNull); +- expect(hover.containingLibraryPath, isNull); +- expect(hover.containingClassDescription, isNull); +- expect(hover.dartdoc, isNull); +- expect(hover.elementDescription, 'num vvv'); +- expect(hover.elementKind, 'local variable'); +- // types +- expect(hover.staticType, 'num'); +- expect(hover.propagatedType, 'int'); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_instanceCreation_implicit() async { +- addTestFile(''' +-library my.library; +-class A { +-} +-main() { +- new A(); +-} +-'''); +- HoverInformation hover = await prepareHover('new A'); +- // range +- expect(hover.offset, findOffset('new A')); +- expect(hover.length, 'new A()'.length); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.dartdoc, isNull); +- expect(hover.elementDescription, 'A() → A'); +- expect(hover.elementKind, 'constructor'); +- // types +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- test_instanceCreation_implicit_withTypeArgument() async { +- addTestFile(''' +-library my.library; +-class A {} +-main() { +- new A(); +-} +-'''); +- void onConstructor(HoverInformation hover) { +- // range +- expect(hover.offset, findOffset('new A')); +- expect(hover.length, 'new A()'.length); +- // element +- expect(hover.containingLibraryName, 'my.library'); +- expect(hover.containingLibraryPath, testFile); +- expect(hover.dartdoc, isNull); +- expect(hover.elementDescription, 'A() → A'); +- expect(hover.elementKind, 'constructor'); +- // types +- expect(hover.staticType, isNull); +- expect(hover.propagatedType, isNull); +- // no parameter +- expect(hover.parameter, isNull); +- } +- +- { +- HoverInformation hover = await prepareHover('new A'); +- onConstructor(hover); +- } +- { +- HoverInformation hover = await prepareHover('A()'); +- onConstructor(hover); +- } +- { +- HoverInformation hover = await prepareHover('String>'); +- expect(hover.offset, findOffset('String>')); +- expect(hover.length, 'String'.length); +- expect(hover.elementKind, 'class'); +- } +- } +- +- test_instanceCreation_named() async { +- addTestFile(''' +-library my.library; +-class A { +- /// my doc +- A.named() {} +-} +-main() { +- new A.named(); +-} +-'''); +- void onConstructor(HoverInformation hover) { +- // range +- expect(hover.offset, findOffset('new A')); +- expect(hover.length, 'new A.named()'.length); +- // element +- expect(hover.dartdoc, 'my doc'); +- expect(hover.elementDescription, 'A.named() → A'); +- expect(hover.elementKind, 'constructor'); +- } +- +- { +- HoverInformation hover = await prepareHover('new A'); +- onConstructor(hover); +- } +- { +- HoverInformation hover = await prepareHover('named();'); +- onConstructor(hover); +- } +- } +- +- test_noHoverInfo() async { +- addTestFile(''' +-library my.library; +-main() { +- // nothing +-} +-'''); +- HoverInformation hover = await prepareHover('nothing'); +- expect(hover, isNull); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart +deleted file mode 100644 +index 6df117964a3..00000000000 +--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart ++++ /dev/null +@@ -1,250 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'notification_navigation_test.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetNavigationTest); +- }); +-} +- +-@reflectiveTest +-class GetNavigationTest extends AbstractNavigationTest { +- static const String requestId = 'test-getNavigation'; +- +- @override +- void setUp() { +- generateSummaryFiles = true; +- super.setUp(); +- server.handlers = [ +- new AnalysisDomainHandler(server), +- ]; +- createProject(); +- } +- +- test_beforeAnalysisComplete() async { +- addTestFile(''' +-main() { +- var test = 0; +- print(test); +-} +-'''); +- await _getNavigation(testFile, testCode.indexOf('test);'), 0); +- assertHasRegion('test);'); +- assertHasTarget('test = 0'); +- } +- +- test_fileDoesNotExist() async { +- String file = '$projectPath/doesNotExist.dart'; +- Request request = _createGetNavigationRequest(file, 0, 100); +- Response response = await serverChannel.sendRequest(request); +- expect(response.error, isNull); +- expect(response.result['files'], isEmpty); +- expect(response.result['targets'], isEmpty); +- expect(response.result['regions'], isEmpty); +- } +- +- test_fileOutsideOfRoot() async { +- testFile = '/outside.dart'; +- addTestFile(''' +-main() { +- var test = 0; +- print(test); +-} +-'''); +- await _getNavigation(testFile, testCode.indexOf('test);'), 0); +- assertHasRegion('test);'); +- assertHasTarget('test = 0'); +- } +- +- test_importDirective() async { +- addTestFile(''' +-import 'dart:math'; +- +-main() { +-}'''); +- await waitForTasksFinished(); +- await _getNavigation(testFile, 0, 17); +- expect(regions, hasLength(1)); +- assertHasRegionString("'dart:math'"); +- expect(testTargets, hasLength(1)); +- expect(testTargets[0].kind, ElementKind.LIBRARY); +- } +- +- test_importKeyword() async { +- addTestFile(''' +-import 'dart:math'; +- +-main() { +-}'''); +- await waitForTasksFinished(); +- await _getNavigation(testFile, 0, 1); +- expect(regions, hasLength(1)); +- assertHasRegionString("'dart:math'"); +- expect(testTargets, hasLength(1)); +- expect(testTargets[0].kind, ElementKind.LIBRARY); +- } +- +- test_importUri() async { +- addTestFile(''' +-import 'dart:math'; +- +-main() { +-}'''); +- await waitForTasksFinished(); +- await _getNavigation(testFile, 7, 11); +- expect(regions, hasLength(1)); +- assertHasRegionString("'dart:math'"); +- expect(testTargets, hasLength(1)); +- expect(testTargets[0].kind, ElementKind.LIBRARY); +- } +- +- test_multipleRegions() async { +- addTestFile(''' +-main() { +- var aaa = 1; +- var bbb = 2; +- var ccc = 3; +- var ddd = 4; +- print(aaa + bbb + ccc + ddd); +-} +-'''); +- await waitForTasksFinished(); +- // request navigation +- String navCode = ' + bbb + '; +- await _getNavigation(testFile, testCode.indexOf(navCode), navCode.length); +- // verify +- { +- assertHasRegion('aaa +'); +- assertHasTarget('aaa = 1'); +- } +- { +- assertHasRegion('bbb +'); +- assertHasTarget('bbb = 2'); +- } +- { +- assertHasRegion('ccc +'); +- assertHasTarget('ccc = 3'); +- } +- assertNoRegionAt('ddd)'); +- } +- +- test_operator_index() async { +- addTestFile(''' +-class A { +- A operator [](index) => null; +- operator []=(index, A value) {} +-} +-main() { +- var a = new A(); +- a[0] // []; +- a[1] = 1; // []=; +- a[2] += 2; +-} +-'''); +- await waitForTasksFinished(); +- { +- String search = '[0'; +- await _getNavigation(testFile, testCode.indexOf(search), 1); +- assertHasOperatorRegion(search, 1, '[](index)', 2); +- } +- { +- String search = '] // []'; +- await _getNavigation(testFile, testCode.indexOf(search), 1); +- assertHasOperatorRegion(search, 1, '[](index)', 2); +- } +- { +- String search = '[1'; +- await _getNavigation(testFile, testCode.indexOf(search), 1); +- assertHasOperatorRegion(search, 1, '[]=(index', 3); +- } +- { +- String search = '] = 1'; +- await _getNavigation(testFile, testCode.indexOf(search), 1); +- assertHasOperatorRegion(search, 1, '[]=(index', 3); +- } +- { +- String search = '[2'; +- await _getNavigation(testFile, testCode.indexOf(search), 1); +- assertHasOperatorRegion(search, 1, '[]=(index', 3); +- } +- { +- String search = '] += 2'; +- await _getNavigation(testFile, testCode.indexOf(search), 1); +- assertHasOperatorRegion(search, 1, '[]=(index', 3); +- } +- } +- +- test_removeContextAfterRequest() async { +- addTestFile(''' +-main() { +- var test = 0; +- print(test); +-} +-'''); +- // handle the request synchronously +- Request request = +- _createGetNavigationRequest(testFile, testCode.indexOf('test);'), 0); +- server.handleRequest(request); +- // remove context, causes sending an "invalid file" error +- { +- Folder projectFolder = resourceProvider.getResource(projectPath); +- server.contextManager.callbacks.removeContext(projectFolder, []); +- } +- // wait for an error response +- Response response = await serverChannel.waitForResponse(request); +- expect(response.error, isNotNull); +- expect(response.error.code, RequestErrorCode.GET_NAVIGATION_INVALID_FILE); +- } +- +- test_zeroLength_end() async { +- addTestFile(''' +-main() { +- var test = 0; +- print(test); +-} +-'''); +- await waitForTasksFinished(); +- await _getNavigation(testFile, testCode.indexOf(');'), 0); +- assertHasRegion('test);'); +- assertHasTarget('test = 0'); +- } +- +- test_zeroLength_start() async { +- addTestFile(''' +-main() { +- var test = 0; +- print(test); +-} +-'''); +- await waitForTasksFinished(); +- await _getNavigation(testFile, testCode.indexOf('test);'), 0); +- assertHasRegion('test);'); +- assertHasTarget('test = 0'); +- } +- +- Request _createGetNavigationRequest(String file, int offset, int length) { +- return new AnalysisGetNavigationParams(file, offset, length) +- .toRequest(requestId); +- } +- +- _getNavigation(String file, int offset, int length) async { +- Request request = _createGetNavigationRequest(file, offset, length); +- Response response = await serverChannel.sendRequest(request); +- AnalysisGetNavigationResult result = +- new AnalysisGetNavigationResult.fromResponse(response); +- targetFiles = result.files; +- targets = result.targets; +- regions = result.regions; +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart +deleted file mode 100644 +index 4293c6cf41a..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart ++++ /dev/null +@@ -1,334 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart' +- hide AnalysisOptions; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:linter/src/rules.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(NewAnalysisOptionsFileNotificationTest); +- defineReflectiveTests(OldAnalysisOptionsFileNotificationTest); +- }); +-} +- +-abstract class AnalysisOptionsFileNotificationTest +- extends AbstractAnalysisTest { +- Map> filesErrors = {}; +- +- final testSource = ''' +-main() { +- var x = ''; +- int y = x; // Not assignable in strong-mode +- print(y); +-}'''; +- +- List get errors => filesErrors[testFile]; +- +- List get optionsFileErrors => filesErrors[optionsFilePath]; +- +- String get optionsFilePath; +- +- List get testFileErrors => filesErrors[testFile]; +- +- void addOptionsFile(String contents) { +- addFile(optionsFilePath, contents); +- } +- +- void deleteFile(String filePath) { +- resourceProvider.deleteFile(filePath); +- } +- +- @override +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { +- var decoded = new AnalysisErrorsParams.fromNotification(notification); +- filesErrors[decoded.file] = decoded.errors; +- } +- } +- +- void setAnalysisRoot() { +- Request request = +- new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- void setStrongMode(bool isSet) { +- addOptionsFile(''' +-analyzer: +- strong-mode: $isSet +-'''); +- } +- +- @override +- void setUp() { +- generateSummaryFiles = true; +- registerLintRules(); +- super.setUp(); +- server.handlers = [new AnalysisDomainHandler(server)]; +- } +- +- @override +- void tearDown() { +- filesErrors[optionsFilePath] = []; +- filesErrors[testFile] = []; +- super.tearDown(); +- } +- +- test_error_filter() async { +- addOptionsFile(''' +-analyzer: +- errors: +- unused_local_variable: ignore +-'''); +- +- addTestFile(''' +-main() { +- String unused = ""; +-} +-'''); +- +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- // Verify options file. +- // TODO(brianwilkerson) Implement options file analysis in the new driver. +-// expect(optionsFileErrors, isNotNull); +-// expect(optionsFileErrors, isEmpty); +- +- // Verify test file. +- expect(testFileErrors, isNotNull); +- expect(testFileErrors, isEmpty); +- } +- +- test_error_filter_removed() async { +- addOptionsFile(''' +-analyzer: +- errors: +- unused_local_variable: ignore +-'''); +- +- addTestFile(''' +-main() { +- String unused = ""; +-} +-'''); +- +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- // Verify options file. +- // TODO(brianwilkerson) Implement options file analysis in the new driver. +-// expect(optionsFileErrors, isNotNull); +-// expect(optionsFileErrors, isEmpty); +- +- // Verify test file. +- expect(testFileErrors, isNotNull); +- expect(testFileErrors, isEmpty); +- +- addOptionsFile(''' +-analyzer: +- errors: +- # unused_local_variable: ignore +-'''); +- +- await pumpEventQueue(); +- await waitForTasksFinished(); +- +- // Verify options file. +- // TODO(brianwilkerson) Implement options file analysis in the new driver. +-// expect(optionsFileErrors, isEmpty); +- +- // Verify test file. +- expect(testFileErrors, hasLength(1)); +- } +- +- test_lint_options_changes() async { +- addOptionsFile(''' +-linter: +- rules: +- - camel_case_types +- - constant_identifier_names +-'''); +- +- addTestFile(testSource); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- verifyLintsEnabled(['camel_case_types', 'constant_identifier_names']); +- +- addOptionsFile(''' +-linter: +- rules: +- - camel_case_types +-'''); +- +- await pumpEventQueue(); +- await waitForTasksFinished(); +- +- verifyLintsEnabled(['camel_case_types']); +- } +- +- test_lint_options_unsupported() async { +- addOptionsFile(''' +-linter: +- rules: +- - unsupported +-'''); +- +- addTestFile(testSource); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- // TODO(brianwilkerson) Implement options file analysis in the new driver. +-// expect(optionsFileErrors, hasLength(1)); +-// expect(optionsFileErrors.first.severity, AnalysisErrorSeverity.WARNING); +-// expect(optionsFileErrors.first.type, AnalysisErrorType.STATIC_WARNING); +- } +- +- test_options_file_added() async { +- addTestFile(testSource); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- // Verify strong-mode disabled. +- verifyStrongMode(enabled: false); +- +- // Clear errors. +- filesErrors[testFile] = []; +- +- // Add options file with strong mode enabled. +- setStrongMode(true); +- +- await pumpEventQueue(); +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: true); +- } +- +- test_options_file_parse_error() async { +- addOptionsFile(''' +-; #bang +-'''); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- // TODO(brianwilkerson) Implement options file analysis in the new driver. +-// expect(optionsFileErrors, hasLength(1)); +-// expect(optionsFileErrors.first.severity, AnalysisErrorSeverity.ERROR); +-// expect(optionsFileErrors.first.type, AnalysisErrorType.COMPILE_TIME_ERROR); +- } +- +- test_options_file_removed() async { +- setStrongMode(true); +- +- addTestFile(testSource); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: true); +- +- // Clear errors. +- filesErrors[testFile] = []; +- +- deleteFile(optionsFilePath); +- +- await pumpEventQueue(); +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: false); +- } +- +- test_strong_mode_changed_off() async { +- setStrongMode(true); +- +- addTestFile(testSource); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: true); +- +- // Clear errors. +- filesErrors[testFile] = []; +- +- setStrongMode(false); +- +- await pumpEventQueue(); +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: false); +- } +- +- test_strong_mode_changed_on() async { +- setStrongMode(false); +- +- addTestFile(testSource); +- setAnalysisRoot(); +- +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: false); +- +- setStrongMode(true); +- +- await pumpEventQueue(); +- await waitForTasksFinished(); +- +- verifyStrongMode(enabled: true); +- } +- +- void verifyLintsEnabled(List lints) { +- AnalysisOptions options = analysisOptions; +- expect(options.lint, true); +- var rules = options.lintRules.map((rule) => rule.name); +- expect(rules, unorderedEquals(lints)); +- } +- +- verifyStrongMode({bool enabled}) { +- // Verify strong-mode enabled. +- expect(analysisOptions.strongMode, enabled); +- +- if (enabled) { +- // Should produce a type warning. +- expect(errors.map((error) => error.type), +- unorderedEquals([AnalysisErrorType.STATIC_TYPE_WARNING])); +- } else { +- // Should only produce a hint. +- expect(errors.map((error) => error.type), +- unorderedEquals([AnalysisErrorType.HINT])); +- } +- } +-} +- +-@reflectiveTest +-class NewAnalysisOptionsFileNotificationTest +- extends AnalysisOptionsFileNotificationTest { +- @override +- String get optionsFilePath => '$projectPath/analysis_options.yaml'; +-} +- +-@reflectiveTest +-class OldAnalysisOptionsFileNotificationTest +- extends AnalysisOptionsFileNotificationTest { +- @override +- String get optionsFilePath => '$projectPath/.analysis_options'; +-} +diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart +deleted file mode 100644 +index c7a11964eaa..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart ++++ /dev/null +@@ -1,133 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationAnalyzedFilesTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNotificationAnalyzedFilesTest extends AbstractAnalysisTest { +- List analyzedFiles; +- bool analyzedFilesReceived = false; +- +- void assertHasFile(String filePath) { +- expect(analyzedFilesReceived, isTrue); +- expect(analyzedFiles, contains(filePath)); +- } +- +- void assertHasNoFile(String filePath) { +- expect(analyzedFilesReceived, isTrue); +- expect(analyzedFiles, isNot(contains(filePath))); +- } +- +- Future prepareAnalyzedFiles() async { +- addGeneralAnalysisSubscription(GeneralAnalysisService.ANALYZED_FILES); +- await pumpEventQueue(); +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ANALYZED_FILES) { +- AnalysisAnalyzedFilesParams params = +- new AnalysisAnalyzedFilesParams.fromNotification(notification); +- analyzedFilesReceived = true; +- analyzedFiles = params.directories; +- } +- } +- +- void setUp() { +- generateSummaryFiles = true; +- super.setUp(); +- createProject(); +- } +- +- test_afterAnalysis() async { +- addTestFile(''' +-class A {} +-'''); +- await waitForTasksFinished(); +- await prepareAnalyzedFiles(); +- assertHasFile(testFile); +- } +- +- test_beforeAnalysis() async { +- addTestFile(''' +-class A {} +-'''); +- await prepareAnalyzedFiles(); +- assertHasFile(testFile); +- } +- +- test_beforeAnalysis_excludeYamlFiles() async { +- File yamlFile = resourceProvider +- .getFolder(projectPath) +- .getChildAssumingFile('sample.yaml'); +- yamlFile.writeAsStringSync(''); +- addTestFile(''' +-class A {} +-'''); +- await prepareAnalyzedFiles(); +- assertHasFile(testFile); +- assertHasNoFile(yamlFile.path); +- } +- +- test_insignificant_change() async { +- // Making a change that doesn't affect the set of reachable files should +- // not trigger the notification to be re-sent. +- addTestFile('class A {}'); +- await prepareAnalyzedFiles(); +- expect(analyzedFilesReceived, isTrue); +- +- analyzedFilesReceived = false; +- modifyTestFile('class B {}'); +- await prepareAnalyzedFiles(); +- expect(analyzedFilesReceived, isFalse); +- } +- +- test_resubscribe_no_changes() async { +- // Unsubscribing and resubscribing should cause the notification to be +- // re-sent, even if nothing has changed. +- addTestFile('class A {}'); +- await prepareAnalyzedFiles(); +- expect(analyzedFilesReceived, isTrue); +- +- unsubscribeAnalyzedFiles(); +- analyzedFilesReceived = false; +- +- await prepareAnalyzedFiles(); +- expect(analyzedFilesReceived, isTrue); +- assertHasFile(testFile); +- } +- +- test_significant_change() async { +- // Making a change that *does* affect the set of reachable files should +- // trigger the notification to be re-sent. +- addTestFile('class A {}'); +- addFile('/foo.dart', 'library foo;'); +- await prepareAnalyzedFiles(); +- expect(analyzedFilesReceived, isTrue); +- +- analyzedFilesReceived = false; +- modifyTestFile('import "/foo.dart";'); +- await prepareAnalyzedFiles(); +- assertHasFile('/foo.dart'); +- } +- +- void unsubscribeAnalyzedFiles() { +- removeGeneralAnalysisSubscription(GeneralAnalysisService.ANALYZED_FILES); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_closingLabels_test.dart b/pkg/analysis_server/test/analysis/notification_closingLabels_test.dart +deleted file mode 100644 +index c99d004fa44..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_closingLabels_test.dart ++++ /dev/null +@@ -1,101 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(_AnalysisNotificationClosingLabelsTest); +- }); +-} +- +-@reflectiveTest +-class _AnalysisNotificationClosingLabelsTest extends AbstractAnalysisTest { +- static const sampleCode = ''' +-Widget build(BuildContext context) { +- return /*1*/new Row( +- children: /*2*/[ +- new Text('a'), +- new Text('b'), +- ]/*/2*/, +- )/*/1*/; +-} +-'''; +- +- static final expectedResults = [ +- new ClosingLabel(51, 96, "Row"), +- new ClosingLabel(79, 57, "[]") +- ]; +- +- List lastLabels; +- +- Completer _labelsReceived; +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_CLOSING_LABELS) { +- var params = +- new AnalysisClosingLabelsParams.fromNotification(notification); +- if (params.file == testFile) { +- lastLabels = params.labels; +- _labelsReceived.complete(null); +- } +- } else if (notification.event == SERVER_NOTIFICATION_ERROR) { +- var params = new ServerErrorParams.fromNotification(notification); +- throw "${params.message}\n${params.stackTrace}"; +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- void subscribeForLabels() { +- addAnalysisSubscription(AnalysisService.CLOSING_LABELS, testFile); +- } +- +- test_afterAnalysis() async { +- addTestFile(sampleCode); +- await waitForTasksFinished(); +- expect(lastLabels, isNull); +- +- await waitForLabels(() => subscribeForLabels()); +- +- expect(lastLabels, expectedResults); +- } +- +- test_afterUpdate() async { +- addTestFile(''); +- // Currently required to get notifications on updates +- setPriorityFiles([testFile]); +- +- // Before subscribing, we shouldn't have had any labels. +- await waitForTasksFinished(); +- expect(lastLabels, isNull); +- +- // With no content, there should be zero labels. +- await waitForLabels(() => subscribeForLabels()); +- expect(lastLabels, hasLength(0)); +- +- // With sample code there will be labels. +- await waitForLabels(() => modifyTestFile(sampleCode)); +- +- expect(lastLabels, expectedResults); +- } +- +- Future waitForLabels(action()) { +- _labelsReceived = new Completer(); +- action(); +- return _labelsReceived.future; +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart +deleted file mode 100644 +index 904a0e4cc44..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart ++++ /dev/null +@@ -1,146 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/context_manager.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/lint/linter.dart'; +-import 'package:analyzer/src/services/lint.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:linter/src/rules.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(NotificationErrorsTest); +- }); +-} +- +-@reflectiveTest +-class NotificationErrorsTest extends AbstractAnalysisTest { +- Map> filesErrors = {}; +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { +- var decoded = new AnalysisErrorsParams.fromNotification(notification); +- filesErrors[decoded.file] = decoded.errors; +- } +- } +- +- @override +- void setUp() { +- generateSummaryFiles = true; +- registerLintRules(); +- super.setUp(); +- server.handlers = [ +- new AnalysisDomainHandler(server), +- ]; +- } +- +- test_importError() async { +- createProject(); +- +- addTestFile(''' +-import 'does_not_exist.dart'; +-'''); +- await waitForTasksFinished(); +- await pumpEventQueue(); +- List errors = filesErrors[testFile]; +- // Verify that we are generating only 1 error for the bad URI. +- // https://github.com/dart-lang/sdk/issues/23754 +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.severity, AnalysisErrorSeverity.ERROR); +- expect(error.type, AnalysisErrorType.COMPILE_TIME_ERROR); +- expect(error.message, startsWith("Target of URI doesn't exist")); +- } +- +- test_lintError() async { +- var camelCaseTypesLintName = 'camel_case_types'; +- +- addFile('$projectPath/.analysis_options', ''' +-linter: +- rules: +- - $camelCaseTypesLintName +-'''); +- +- addTestFile('class a { }'); +- +- Request request = +- new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0'); +- handleSuccessfulRequest(request); +- +- await waitForTasksFinished(); +- List lints; +- AnalysisDriver testDriver = (server.contextManager as ContextManagerImpl) +- .getContextInfoFor(resourceProvider.getFolder(projectPath)) +- .analysisDriver; +- lints = testDriver.analysisOptions.lintRules; +- // Registry should only contain single lint rule. +- expect(lints, hasLength(1)); +- LintRule lint = lints.first as LintRule; +- expect(lint.name, camelCaseTypesLintName); +- // Verify lint error result. +- List errors = filesErrors[testFile]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.location.file, '/project/bin/test.dart'); +- expect(error.severity, AnalysisErrorSeverity.INFO); +- expect(error.type, AnalysisErrorType.LINT); +- expect(error.message, lint.description); +- } +- +- test_notInAnalysisRoot() async { +- createProject(); +- String otherFile = '/other.dart'; +- addFile(otherFile, 'UnknownType V;'); +- addTestFile(''' +-import '/other.dart'; +-main() { +- print(V); +-} +-'''); +- await waitForTasksFinished(); +- expect(filesErrors[otherFile], isNull); +- } +- +- test_ParserError() async { +- createProject(); +- addTestFile('library lib'); +- await waitForTasksFinished(); +- await pumpEventQueue(); +- List errors = filesErrors[testFile]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.location.file, '/project/bin/test.dart'); +- expect(error.location.offset, isPositive); +- expect(error.location.length, isNonNegative); +- expect(error.severity, AnalysisErrorSeverity.ERROR); +- expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR); +- expect(error.message, isNotNull); +- } +- +- test_StaticWarning() async { +- createProject(); +- addTestFile(''' +-main() { +- print(UNKNOWN); +-} +-'''); +- await waitForTasksFinished(); +- await pumpEventQueue(); +- List errors = filesErrors[testFile]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.severity, AnalysisErrorSeverity.WARNING); +- expect(error.type, AnalysisErrorType.STATIC_WARNING); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart +deleted file mode 100644 +index ceabbceb2ec..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart ++++ /dev/null +@@ -1,960 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationHighlightsTest); +- defineReflectiveTests(HighlightTypeTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNotificationHighlightsTest extends AbstractAnalysisTest { +- List regions; +- +- Completer _resultsAvailable = new Completer(); +- +- void assertHasRawRegion(HighlightRegionType type, int offset, int length) { +- for (HighlightRegion region in regions) { +- if (region.offset == offset && +- region.length == length && +- region.type == type) { +- return; +- } +- } +- fail('Expected to find (offset=$offset; length=$length; type=$type) in\n' +- '${regions.join('\n')}'); +- } +- +- void assertHasRegion(HighlightRegionType type, String search, +- [int length = -1]) { +- int offset = findOffset(search); +- length = findRegionLength(search, length); +- assertHasRawRegion(type, offset, length); +- } +- +- void assertHasStringRegion(HighlightRegionType type, String str) { +- int offset = findOffset(str); +- int length = str.length; +- assertHasRawRegion(type, offset, length); +- } +- +- void assertNoRawRegion(HighlightRegionType type, int offset, int length) { +- for (HighlightRegion region in regions) { +- if (region.offset == offset && +- region.length == length && +- region.type == type) { +- fail( +- 'Not expected to find (offset=$offset; length=$length; type=$type) in\n' +- '${regions.join('\n')}'); +- } +- } +- } +- +- void assertNoRegion(HighlightRegionType type, String search, +- [int length = -1]) { +- int offset = findOffset(search); +- length = findRegionLength(search, length); +- assertNoRawRegion(type, offset, length); +- } +- +- int findRegionLength(String search, int length) { +- if (length == -1) { +- length = 0; +- while (length < search.length) { +- int c = search.codeUnitAt(length); +- if (length == 0 && c == '@'.codeUnitAt(0)) { +- length++; +- continue; +- } +- if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) || +- c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) || +- c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) { +- break; +- } +- length++; +- } +- } +- return length; +- } +- +- Future prepareHighlights() { +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile); +- return _resultsAvailable.future; +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) { +- var params = new AnalysisHighlightsParams.fromNotification(notification); +- if (params.file == testFile) { +- regions = params.regions; +- _resultsAvailable.complete(null); +- } +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- test_ANNOTATION_hasArguments() async { +- addTestFile(''' +-class AAA { +- const AAA(a, b, c); +-} +-@AAA(1, 2, 3) main() {} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length); +- assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length); +- } +- +- test_ANNOTATION_noArguments() async { +- addTestFile(''' +-const AAA = 42; +-@AAA main() {} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA'); +- } +- +- test_BUILT_IN_abstract() async { +- addTestFile(''' +-abstract class A {}; +-abstract class B = Object with A; +-main() { +- var abstract = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42'); +- } +- +- test_BUILT_IN_as() async { +- addTestFile(''' +-import 'dart:math' as math; +-main() { +- p as int; +- var as = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'as math'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'as int'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42'); +- } +- +- test_BUILT_IN_async() async { +- addTestFile(''' +-fa() async {} +-fb() async* {} +-main() { +- bool async = false; +-} +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async'); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false'); +- } +- +- test_BUILT_IN_await() async { +- addTestFile(''' +-main() async { +- await 42; +- await for (var item in []) { +- print(item); +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'await for'); +- } +- +- test_BUILT_IN_deferred() async { +- addTestFile(''' +-import 'dart:math' deferred as math; +-main() { +- var deferred = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42'); +- } +- +- test_BUILT_IN_export() async { +- addTestFile(''' +-export "dart:math"; +-main() { +- var export = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42'); +- } +- +- test_BUILT_IN_external() async { +- addTestFile(''' +-class A { +- external A(); +- external aaa(); +-} +-external main() { +- var external = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42'); +- } +- +- test_BUILT_IN_factory() async { +- addTestFile(''' +-class A { +- factory A() => null; +-} +-main() { +- var factory = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42'); +- } +- +- test_BUILT_IN_get() async { +- addTestFile(''' +-get aaa => 1; +-class A { +- get bbb => 2; +-} +-main() { +- var get = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42'); +- } +- +- test_BUILT_IN_hide() async { +- addTestFile(''' +-import 'foo.dart' hide Foo; +-main() { +- var hide = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42'); +- } +- +- test_BUILT_IN_implements() async { +- addTestFile(''' +-class A {} +-class B implements A {} +-main() { +- var implements = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42'); +- } +- +- test_BUILT_IN_import() async { +- addTestFile(''' +-import "foo.dart"; +-main() { +- var import = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'import "'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42'); +- } +- +- test_BUILT_IN_library() async { +- addTestFile(''' +-library lib; +-main() { +- var library = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42'); +- } +- +- test_BUILT_IN_native() async { +- addTestFile(''' +-class A native "A_native" {} +-class B { +- bbb() native "bbb_native"; +-} +-main() { +- var native = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42'); +- } +- +- test_BUILT_IN_on() async { +- addTestFile(''' +-main() { +- try { +- } on int catch (e) { +- } +- var on = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'on int'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42'); +- } +- +- test_BUILT_IN_operator() async { +- addTestFile(''' +-class A { +- operator +(x) => null; +-} +-main() { +- var operator = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +('); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42'); +- } +- +- test_BUILT_IN_part() async { +- addTestFile(''' +-part "my_part.dart"; +-main() { +- var part = 42; +-}'''); +- addFile('/project/bin/my_part.dart', 'part of lib;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42'); +- } +- +- test_BUILT_IN_partOf() async { +- addTestFile(''' +-part of lib; +-main() { +- var part = 1; +- var of = 2; +-}'''); +- _addLibraryForTestPart(); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2'); +- } +- +- test_BUILT_IN_set() async { +- addTestFile(''' +-set aaa(x) {} +-class A +- set bbb(x) {} +-} +-main() { +- var set = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa('); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb('); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42'); +- } +- +- test_BUILT_IN_show() async { +- addTestFile(''' +-import 'foo.dart' show Foo; +-main() { +- var show = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42'); +- } +- +- test_BUILT_IN_static() async { +- addTestFile(''' +-class A { +- static aaa; +- static bbb() {} +-} +-main() { +- var static = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42'); +- } +- +- test_BUILT_IN_sync() async { +- addTestFile(''' +-fa() sync {} +-fb() sync* {} +-main() { +- bool sync = false; +-} +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync'); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false'); +- } +- +- test_BUILT_IN_typedef() async { +- addTestFile(''' +-typedef A(); +-main() { +- var typedef = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42'); +- } +- +- test_BUILT_IN_yield() async { +- addTestFile(''' +-main() async* { +- yield 42; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42'); +- } +- +- test_BUILT_IN_yieldStar() async { +- addTestFile(''' +-main() async* { +- yield* []; +-} +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*'); +- } +- +- test_CLASS() async { +- addTestFile(''' +-class AAA {} +-AAA aaa; +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.CLASS, 'AAA {}'); +- assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa'); +- } +- +- test_CLASS_notDynamic() async { +- addTestFile(''' +-dynamic f() {} +-'''); +- await prepareHighlights(); +- assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()'); +- } +- +- test_CLASS_notVoid() async { +- addTestFile(''' +-void f() {} +-'''); +- await prepareHighlights(); +- assertNoRegion(HighlightRegionType.CLASS, 'void f()'); +- } +- +- test_COMMENT() async { +- addTestFile(''' +-/** +- * documentation comment +- */ +-void main() { +- // end-of-line comment +- my_function(1); +-} +- +-void my_function(String a) { +- /* block comment */ +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32); +- assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22); +- assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19); +- } +- +- test_CONSTRUCTOR() async { +- addTestFile(''' +-class AAA { +- AAA() {} +- AAA.name(p) {} +-} +-main() { +- new AAA(); +- new AAA.name(42); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)'); +- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)'); +- assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA() {}'); +- assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA();'); +- } +- +- test_DIRECTIVE() async { +- addTestFile(''' +-library lib; +-import 'dart:math'; +-export 'dart:math'; +-part 'part.dart'; +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "library lib;"); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';"); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';"); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';"); +- } +- +- test_DIRECTIVE_partOf() async { +- addTestFile(''' +-part of lib; +-'''); +- _addLibraryForTestPart(); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part of lib;"); +- } +- +- test_DYNAMIC_TYPE() async { +- addTestFile(''' +-f() {} +-main(p) { +- print(p); +- var v1 = f(); +- int v2; +- var v3 = v2; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'p)'); +- assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'v1 ='); +- assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v2;'); +- assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v3 ='); +- } +- +- test_ENUM() async { +- addTestFile(''' +-enum MyEnum {A, B, C} +-MyEnum value; +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {'); +- assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;'); +- } +- +- test_ENUM_CONSTANT() async { +- addTestFile(''' +-enum MyEnum {AAA, BBB} +-main() { +- print(MyEnum.AAA); +- print(MyEnum.BBB); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, '); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}'); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);'); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);'); +- } +- +- test_FIELD() async { +- addTestFile(''' +-class A { +- int aaa = 1; +- int bbb = 2; +- A([this.bbb = 3]); +-} +-main(A a) { +- a.aaa = 4; +- a.bbb = 5; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.FIELD, 'aaa = 1'); +- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2'); +- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 3'); +- assertHasRegion(HighlightRegionType.FIELD, 'aaa = 4'); +- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 5'); +- } +- +- test_FIELD_STATIC() async { +- addTestFile(''' +-class A { +- static aaa = 1; +- static get bbb => null; +- static set ccc(x) {} +-} +-main() { +- A.aaa = 2; +- A.bbb; +- A.ccc = 3; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 1'); +- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 2'); +- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'bbb;'); +- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'ccc = 3'); +- } +- +- test_FUNCTION() async { +- addTestFile(''' +-fff(p) {} +-main() { +- fff(42); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.FUNCTION_DECLARATION, 'fff(p) {}'); +- assertHasRegion(HighlightRegionType.FUNCTION, 'fff(42)'); +- } +- +- test_FUNCTION_TYPE_ALIAS() async { +- addTestFile(''' +-typedef FFF(p); +-main(FFF fff) { +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)'); +- assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)'); +- } +- +- test_GETTER_DECLARATION() async { +- addTestFile(''' +-get aaa => null; +-class A { +- get bbb => null; +-} +-main(A a) { +- aaa; +- a.bbb; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'aaa => null'); +- assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'bbb => null'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa;'); +- assertHasRegion(HighlightRegionType.FIELD, 'bbb;'); +- } +- +- test_IDENTIFIER_DEFAULT() async { +- addTestFile(''' +-main() { +- aaa = 42; +- bbb(84); +- CCC ccc; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42'); +- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)'); +- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc'); +- } +- +- test_IMPORT_PREFIX() async { +- addTestFile(''' +-import 'dart:math' as ma; +-main() { +- ma.max(1, 2); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;'); +- assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max'); +- } +- +- test_KEYWORD() async { +- addTestFile(''' +-main() { +- assert(true); +- for (;;) break; +- switch (0) { +- case 0: break; +- default: break; +- } +- try {} catch (e) {} +- const v1 = 0; +- for (;;) continue; +- do {} while (true); +- if (true) {} else {} +- var v2 = false; +- final v3 = 1; +- try {} finally {} +- for (var v4 in []) {} +- v3 is int; +- new A(); +- try {} catch (e) {rethrow;} +- var v5 = true; +- while (true) {} +-} +-class A {} +-class B extends A { +- B() : super(); +- m() { +- return this; +- } +-} +-class C = Object with A; +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'break;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'const v1'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'continue;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'default:'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'false;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 ='); +- assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'in []'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'is int'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'new A();'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'return this'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'super();'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'this;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'true;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'try {'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'with A;'); +- } +- +- test_KEYWORD_void() async { +- addTestFile(''' +-void main() { +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.KEYWORD, 'void main()'); +- } +- +- test_LABEL() async { +- addTestFile(''' +-main() { +-myLabel: +- while (true) { +- break myLabel; +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LABEL, 'myLabel:'); +- assertHasRegion(HighlightRegionType.LABEL, 'myLabel;'); +- } +- +- test_LITERAL_BOOLEAN() async { +- addTestFile('var V = true;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;'); +- } +- +- test_LITERAL_DOUBLE() async { +- addTestFile('var V = 4.2;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length); +- } +- +- test_LITERAL_INTEGER() async { +- addTestFile('var V = 42;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;'); +- } +- +- test_LITERAL_LIST() async { +- addTestFile('var V = [1, 2, 3];'); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '[1, 2, 3]'); +- } +- +- test_LITERAL_MAP() async { +- addTestFile("var V = const {1: 'a', 2: 'b', 3: 'c'};"); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.LITERAL_MAP, +- "const {1: 'a', 2: 'b', 3: 'c'}"); +- } +- +- test_LITERAL_STRING() async { +- addTestFile('var V = "abc";'); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length); +- } +- +- test_LOCAL_VARIABLE() async { +- addTestFile(''' +-main() { +- int vvv = 0; +- vvv; +- vvv = 1; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0'); +- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv;'); +- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv = 1;'); +- } +- +- test_METHOD() async { +- addTestFile(''' +-class A { +- aaa() {} +- static bbb() {} +-} +-main(A a) { +- a.aaa(); +- a.aaa; +- A.bbb(); +- A.bbb; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.METHOD_DECLARATION, 'aaa() {}'); +- assertHasRegion(HighlightRegionType.METHOD_DECLARATION_STATIC, 'bbb() {}'); +- assertHasRegion(HighlightRegionType.METHOD, 'aaa();'); +- assertHasRegion(HighlightRegionType.METHOD, 'aaa;'); +- assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb();'); +- assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb;'); +- } +- +- test_METHOD_bestType() async { +- addTestFile(''' +-main(p) { +- if (p is List) { +- p.add(null); +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.METHOD, 'add(null)'); +- } +- +- test_PARAMETER() async { +- addTestFile(''' +-main(int p) { +- p; +- p = 42; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.PARAMETER, 'p) {'); +- assertHasRegion(HighlightRegionType.PARAMETER, 'p;'); +- assertHasRegion(HighlightRegionType.PARAMETER, 'p = 42'); +- } +- +- test_SETTER_DECLARATION() async { +- addTestFile(''' +-set aaa(x) {} +-class A { +- set bbb(x) {} +-} +-main(A a) { +- aaa = 1; +- a.bbb = 2; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'aaa(x)'); +- assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'bbb(x)'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa = 1'); +- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2'); +- } +- +- test_TOP_LEVEL_VARIABLE() async { +- addTestFile(''' +-const VVV = 0; +-@VVV // annotation +-main() { +- print(VVV); +- VVV = 1; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 0'); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV // annotation'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV);'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 1'); +- } +- +- test_TYPE_NAME_DYNAMIC() async { +- addTestFile(''' +-dynamic main() { +- dynamic = 42; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()'); +- assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()'); +- assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42'); +- } +- +- test_TYPE_PARAMETER() async { +- addTestFile(''' +-class A { +- T fff; +- T mmm(T p) => null; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {'); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;'); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm('); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)'); +- } +- +- void _addLibraryForTestPart() { +- addFile('$testFolder/my_lib.dart', ''' +-library lib; +-part 'test.dart'; +- '''); +- } +-} +- +-@reflectiveTest +-class HighlightTypeTest { +- void test_constructor() { +- expect(HighlightRegionType.CLASS, +- new HighlightRegionType(HighlightRegionType.CLASS.name)); +- } +- +- void test_toString() { +- expect(HighlightRegionType.CLASS.toString(), 'HighlightRegionType.CLASS'); +- } +- +- void test_valueOf_unknown() { +- expect(() { +- new HighlightRegionType('no-such-type'); +- }, throwsException); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart +deleted file mode 100644 +index df9b59d7835..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart ++++ /dev/null +@@ -1,1111 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationHighlightsTest); +- defineReflectiveTests(HighlightTypeTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNotificationHighlightsTest extends AbstractAnalysisTest { +- List regions; +- +- Completer _resultsAvailable = new Completer(); +- +- void assertHasRawRegion(HighlightRegionType type, int offset, int length) { +- for (HighlightRegion region in regions) { +- if (region.offset == offset && +- region.length == length && +- region.type == type) { +- return; +- } +- } +- fail('Expected to find (offset=$offset; length=$length; type=$type) in\n' +- '${regions.join('\n')}'); +- } +- +- void assertHasRegion(HighlightRegionType type, String search, +- [int length = -1]) { +- int offset = findOffset(search); +- length = findRegionLength(search, length); +- assertHasRawRegion(type, offset, length); +- } +- +- void assertHasStringRegion(HighlightRegionType type, String str) { +- int offset = findOffset(str); +- int length = str.length; +- assertHasRawRegion(type, offset, length); +- } +- +- void assertNoRawRegion(HighlightRegionType type, int offset, int length) { +- for (HighlightRegion region in regions) { +- if (region.offset == offset && +- region.length == length && +- region.type == type) { +- fail( +- 'Not expected to find (offset=$offset; length=$length; type=$type) in\n' +- '${regions.join('\n')}'); +- } +- } +- } +- +- void assertNoRegion(HighlightRegionType type, String search, +- [int length = -1]) { +- int offset = findOffset(search); +- length = findRegionLength(search, length); +- assertNoRawRegion(type, offset, length); +- } +- +- int findRegionLength(String search, int length) { +- if (length == -1) { +- length = 0; +- while (length < search.length) { +- int c = search.codeUnitAt(length); +- if (length == 0 && c == '@'.codeUnitAt(0)) { +- length++; +- continue; +- } +- if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) || +- c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) || +- c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) { +- break; +- } +- length++; +- } +- } +- return length; +- } +- +- Future prepareHighlights() { +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile); +- return _resultsAvailable.future; +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) { +- var params = new AnalysisHighlightsParams.fromNotification(notification); +- if (params.file == testFile) { +- regions = params.regions; +- _resultsAvailable.complete(null); +- } +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- server.options.useAnalysisHighlight2 = true; +- createProject(); +- } +- +- test_ANNOTATION_hasArguments() async { +- addTestFile(''' +-class AAA { +- const AAA(a, b, c); +-} +-@AAA(1, 2, 3) main() {} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length); +- assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length); +- } +- +- test_ANNOTATION_noArguments() async { +- addTestFile(''' +-const AAA = 42; +-@AAA main() {} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA'); +- } +- +- test_BUILT_IN_abstract() async { +- addTestFile(''' +-abstract class A {}; +-abstract class B = Object with A; +-main() { +- var abstract = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42'); +- } +- +- test_BUILT_IN_as() async { +- addTestFile(''' +-import 'dart:math' as math; +-main() { +- p as int; +- var as = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'as math'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'as int'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42'); +- } +- +- test_BUILT_IN_async() async { +- addTestFile(''' +-fa() async {} +-fb() async* {} +-main() { +- bool async = false; +-} +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async'); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false'); +- } +- +- test_BUILT_IN_await() async { +- addTestFile(''' +-main() async { +- await 42; +- await for (var item in []) { +- print(item); +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'await for'); +- } +- +- test_BUILT_IN_deferred() async { +- addTestFile(''' +-import 'dart:math' deferred as math; +-main() { +- var deferred = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42'); +- } +- +- test_BUILT_IN_export() async { +- addTestFile(''' +-export "dart:math"; +-main() { +- var export = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42'); +- } +- +- test_BUILT_IN_external() async { +- addTestFile(''' +-class A { +- external A(); +- external aaa(); +-} +-external main() { +- var external = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42'); +- } +- +- test_BUILT_IN_factory() async { +- addTestFile(''' +-class A { +- factory A() => null; +-} +-main() { +- var factory = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42'); +- } +- +- test_BUILT_IN_get() async { +- addTestFile(''' +-get aaa => 1; +-class A { +- get bbb => 2; +-} +-main() { +- var get = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42'); +- } +- +- test_BUILT_IN_hide() async { +- addTestFile(''' +-import 'foo.dart' hide Foo; +-main() { +- var hide = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42'); +- } +- +- test_BUILT_IN_implements() async { +- addTestFile(''' +-class A {} +-class B implements A {} +-main() { +- var implements = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42'); +- } +- +- test_BUILT_IN_import() async { +- addTestFile(''' +-import "foo.dart"; +-main() { +- var import = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'import "'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42'); +- } +- +- test_BUILT_IN_library() async { +- addTestFile(''' +-library lib; +-main() { +- var library = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42'); +- } +- +- test_BUILT_IN_native() async { +- addTestFile(''' +-class A native "A_native" {} +-class B { +- bbb() native "bbb_native"; +-} +-main() { +- var native = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42'); +- } +- +- test_BUILT_IN_on() async { +- addTestFile(''' +-main() { +- try { +- } on int catch (e) { +- } +- var on = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'on int'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42'); +- } +- +- test_BUILT_IN_operator() async { +- addTestFile(''' +-class A { +- operator +(x) => null; +-} +-main() { +- var operator = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +('); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42'); +- } +- +- test_BUILT_IN_part() async { +- addTestFile(''' +-part "my_part.dart"; +-main() { +- var part = 42; +-}'''); +- addFile('/project/bin/my_part.dart', 'part of lib;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42'); +- } +- +- test_BUILT_IN_partOf() async { +- addTestFile(''' +-part of lib; +-main() { +- var part = 1; +- var of = 2; +-}'''); +- _addLibraryForTestPart(); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2'); +- } +- +- test_BUILT_IN_set() async { +- addTestFile(''' +-set aaa(x) {} +-class A +- set bbb(x) {} +-} +-main() { +- var set = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa('); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb('); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42'); +- } +- +- test_BUILT_IN_show() async { +- addTestFile(''' +-import 'foo.dart' show Foo; +-main() { +- var show = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42'); +- } +- +- test_BUILT_IN_static() async { +- addTestFile(''' +-class A { +- static aaa; +- static bbb() {} +-} +-main() { +- var static = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;'); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42'); +- } +- +- test_BUILT_IN_sync() async { +- addTestFile(''' +-fa() sync {} +-fb() sync* {} +-main() { +- bool sync = false; +-} +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync'); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false'); +- } +- +- test_BUILT_IN_typedef() async { +- addTestFile(''' +-typedef A(); +-main() { +- var typedef = 42; +-}'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();'); +- assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42'); +- } +- +- test_BUILT_IN_yield() async { +- addTestFile(''' +-main() async* { +- yield 42; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42'); +- } +- +- test_BUILT_IN_yieldStar() async { +- addTestFile(''' +-main() async* { +- yield* []; +-} +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*'); +- } +- +- test_CLASS() async { +- addTestFile(''' +-class AAA {} +-AAA aaa; +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.CLASS, 'AAA {}'); +- assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa'); +- } +- +- test_CLASS_notDynamic() async { +- addTestFile(''' +-dynamic f() {} +-'''); +- await prepareHighlights(); +- assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()'); +- } +- +- test_CLASS_notVoid() async { +- addTestFile(''' +-void f() {} +-'''); +- await prepareHighlights(); +- assertNoRegion(HighlightRegionType.CLASS, 'void f()'); +- } +- +- test_COMMENT() async { +- addTestFile(''' +-/** +- * documentation comment +- */ +-void main() { +- // end-of-line comment +- my_function(1); +-} +- +-void my_function(String a) { +- /* block comment */ +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32); +- assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22); +- assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19); +- } +- +- test_CONSTRUCTOR() async { +- addTestFile(''' +-class AAA { +- AAA() {} +- AAA.name(p) {} +-} +-main() { +- new AAA(); +- new AAA.name(42); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)'); +- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)'); +- assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA() {}'); +- assertNoRegion(HighlightRegionType.CONSTRUCTOR, 'AAA();'); +- } +- +- test_DIRECTIVE() async { +- addTestFile(''' +-library lib; +-import 'dart:math'; +-export 'dart:math'; +-part 'part.dart'; +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "library lib;"); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';"); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';"); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';"); +- } +- +- test_DIRECTIVE_partOf() async { +- addTestFile(''' +-part of lib; +-'''); +- _addLibraryForTestPart(); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part of lib;"); +- } +- +- test_DYNAMIC_LOCAL_VARIABLE() async { +- addTestFile(''' +-f() {} +-main(p) { +- var v = f(); +- v; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, 'v = f()'); +- assertHasRegion(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, 'v;'); +- } +- +- test_DYNAMIC_PARAMETER() async { +- addTestFile(''' +-main(p) { +- print(p); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, 'p)'); +- assertHasRegion(HighlightRegionType.DYNAMIC_PARAMETER_REFERENCE, 'p);'); +- } +- +- test_DYNAMIC_VARIABLE_field() async { +- addTestFile(''' +-class A { +- var f; +- m() { +- f = 1; +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'f;'); +- assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'f = 1'); +- } +- +- test_ENUM() async { +- addTestFile(''' +-enum MyEnum {A, B, C} +-MyEnum value; +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {'); +- assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;'); +- } +- +- test_ENUM_CONSTANT() async { +- addTestFile(''' +-enum MyEnum {AAA, BBB} +-main() { +- print(MyEnum.AAA); +- print(MyEnum.BBB); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, '); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}'); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);'); +- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);'); +- } +- +- test_FUNCTION_TYPE_ALIAS() async { +- addTestFile(''' +-typedef FFF(p); +-main(FFF fff) { +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)'); +- assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)'); +- } +- +- test_GETTER() async { +- addTestFile(''' +-get aaa => null; +-class A { +- get bbb => null; +- static get ccc => null; +-} +-main(A a) { +- aaa; +- a.bbb; +- A.ccc; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_GETTER_DECLARATION, 'aaa => null'); +- assertHasRegion( +- HighlightRegionType.INSTANCE_GETTER_DECLARATION, 'bbb => null'); +- assertHasRegion( +- HighlightRegionType.STATIC_GETTER_DECLARATION, 'ccc => null'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'aaa;'); +- assertHasRegion(HighlightRegionType.INSTANCE_GETTER_REFERENCE, 'bbb;'); +- assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'ccc;'); +- } +- +- test_IDENTIFIER_DEFAULT() async { +- addTestFile(''' +-main() { +- aaa = 42; +- bbb(84); +- CCC ccc; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42'); +- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)'); +- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc'); +- } +- +- test_IMPORT_PREFIX() async { +- addTestFile(''' +-import 'dart:math' as ma; +-main() { +- ma.max(1, 2); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;'); +- assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max'); +- } +- +- test_INSTANCE_FIELD() async { +- addTestFile(''' +-class A { +- int aaa = 1; +- int bbb = 2; +- A([this.bbb = 3]); +-} +-main(A a) { +- a.aaa = 4; +- a.bbb = 5; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'aaa = 1'); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'bbb = 2'); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'bbb = 3'); +- assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'aaa = 4'); +- assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'bbb = 5'); +- } +- +- test_INSTANCE_FIELD_dynamic() async { +- addTestFile(''' +-class A { +- var f; +- A(this.f); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'f;'); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'f);'); +- } +- +- test_KEYWORD() async { +- addTestFile(''' +-main() { +- assert(true); +- for (;;) break; +- switch (0) { +- case 0: break; +- default: break; +- } +- try {} catch (e) {} +- const v1 = 0; +- for (;;) continue; +- do {} while (true); +- if (true) {} else {} +- var v2 = false; +- final v3 = 1; +- try {} finally {} +- for (var v4 in []) {} +- v3 is int; +- new A(); +- try {} catch (e) {rethrow;} +- var v5 = true; +- while (true) {} +-} +-class A {} +-class B extends A { +- B() : super(); +- m() { +- return this; +- } +-} +-class C = Object with A; +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'break;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'const v1'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'continue;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'default:'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'false;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 ='); +- assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'in []'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'is int'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'new A();'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'return this'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'super();'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'this;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'true;'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'try {'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);'); +- assertHasRegion(HighlightRegionType.KEYWORD, 'with A;'); +- } +- +- test_KEYWORD_void() async { +- addTestFile(''' +-void main() { +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.KEYWORD, 'void main()'); +- } +- +- test_LABEL() async { +- addTestFile(''' +-main() { +-myLabel: +- while (true) { +- break myLabel; +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LABEL, 'myLabel:'); +- assertHasRegion(HighlightRegionType.LABEL, 'myLabel;'); +- } +- +- test_LIBRARY_NAME_libraryDirective() async { +- addTestFile(''' +-library my.lib.name; +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.LIBRARY_NAME, 'my.lib.name'); +- } +- +- test_LIBRARY_NAME_partOfDirective() async { +- _addLibraryForTestPart(); +- addTestFile(''' +-part of my.lib.name; +-'''); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.LIBRARY_NAME, 'my.lib.name'); +- } +- +- test_LITERAL_BOOLEAN() async { +- addTestFile('var V = true;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;'); +- } +- +- test_LITERAL_DOUBLE() async { +- addTestFile('var V = 4.2;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length); +- } +- +- test_LITERAL_INTEGER() async { +- addTestFile('var V = 42;'); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;'); +- } +- +- test_LITERAL_LIST() async { +- addTestFile('var V = [1, 2, 3];'); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '[1, 2, 3]'); +- } +- +- test_LITERAL_MAP() async { +- addTestFile("var V = const {1: 'a', 2: 'b', 3: 'c'};"); +- await prepareHighlights(); +- assertHasStringRegion(HighlightRegionType.LITERAL_MAP, +- "const {1: 'a', 2: 'b', 3: 'c'}"); +- } +- +- test_LITERAL_STRING() async { +- addTestFile('var V = "abc";'); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length); +- } +- +- test_LOCAL_FUNCTION() async { +- addTestFile(''' +-main() { +- fff() {} +- fff(); +- fff; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_DECLARATION, 'fff() {}'); +- assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff();'); +- assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff;'); +- } +- +- test_LOCAL_VARIABLE() async { +- addTestFile(''' +-main() { +- int vvv = 0; +- vvv; +- vvv = 1; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0'); +- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, 'vvv;'); +- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, 'vvv = 1;'); +- } +- +- test_METHOD() async { +- addTestFile(''' +-class A { +- aaa() {} +- static bbb() {} +-} +-main(A a) { +- a.aaa(); +- a.aaa; +- A.bbb(); +- A.bbb; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.INSTANCE_METHOD_DECLARATION, 'aaa() {}'); +- assertHasRegion(HighlightRegionType.STATIC_METHOD_DECLARATION, 'bbb() {}'); +- assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa();'); +- assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa;'); +- assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb();'); +- assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb;'); +- } +- +- test_METHOD_bestType() async { +- addTestFile(''' +-main(p) { +- if (p is List) { +- p.add(null); +- } +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'add(null)'); +- } +- +- test_PARAMETER() async { +- addTestFile(''' +-main(int p) { +- p; +- p = 42; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'p) {'); +- assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'p;'); +- assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'p = 42'); +- } +- +- test_PARAMETER_named() async { +- addTestFile(''' +-class C { +- final int aaa; +- C({this.aaa, int bbb}); +-} +-main() { +- new C(aaa: 1, bbb: 2); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'aaa,'); +- assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'bbb}'); +- assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'aaa: 1'); +- assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'bbb: 2'); +- } +- +- test_SETTER_DECLARATION() async { +- addTestFile(''' +-set aaa(x) {} +-class A { +- set bbb(x) {} +- static set ccc(x) {} +-} +-main(A a) { +- aaa = 1; +- a.bbb = 2; +- A.ccc = 3; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_DECLARATION, 'aaa(x)'); +- assertHasRegion(HighlightRegionType.INSTANCE_SETTER_DECLARATION, 'bbb(x)'); +- assertHasRegion(HighlightRegionType.STATIC_SETTER_DECLARATION, 'ccc(x)'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'aaa = 1'); +- assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'bbb = 2'); +- assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'ccc = 3'); +- } +- +- test_STATIC_FIELD() async { +- addTestFile(''' +-class A { +- static aaa = 1; +- static get bbb => null; +- static set ccc(x) {} +-} +-main() { +- A.aaa = 2; +- A.bbb; +- A.ccc = 3; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.STATIC_FIELD_DECLARATION, 'aaa = 1'); +- assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'aaa = 2'); +- assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'bbb;'); +- assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'ccc = 3'); +- } +- +- test_TOP_LEVEL_FUNCTION() async { +- addTestFile(''' +-fff(p) {} +-main() { +- fff(42); +-} +-'''); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, 'fff(p) {}'); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, 'fff(42)'); +- } +- +- test_TOP_LEVEL_VARIABLE() async { +- addTestFile(''' +-const V1 = 1; +-var V2 = 2; +-@V1 // annotation +-main() { +- print(V1); +- V2 = 3; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, 'V1 = 1'); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, 'V2 = 2'); +- assertHasRegion( +- HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'V1 // annotation'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'V1);'); +- assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'V2 = 3'); +- } +- +- test_TYPE_NAME_DYNAMIC() async { +- addTestFile(''' +-dynamic main() { +- dynamic = 42; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()'); +- assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()'); +- assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42'); +- } +- +- test_TYPE_PARAMETER() async { +- addTestFile(''' +-class A { +- T fff; +- T mmm(T p) => null; +-} +-'''); +- await prepareHighlights(); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {'); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;'); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm('); +- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)'); +- } +- +- test_UNRESOLVED_INSTANCE_MEMBER_REFERENCE_dynamicVarTarget() async { +- addTestFile(''' +-main(p) { +- p.aaa; +- p.aaa++; +- p.aaa += 0; +- ++p.aaa; // ++ +- p.aaa = 0; +- p.bbb(0); +- ''.length.ccc().ddd(); +-} +-'''); +- await prepareHighlights(); +- HighlightRegionType type = +- HighlightRegionType.UNRESOLVED_INSTANCE_MEMBER_REFERENCE; +- assertHasRegion(type, 'aaa'); +- assertHasRegion(type, 'aaa++'); +- assertHasRegion(type, 'aaa += 0'); +- assertHasRegion(type, 'aaa; // ++'); +- assertHasRegion(type, 'aaa ='); +- assertHasRegion(type, 'bbb('); +- assertHasRegion(type, 'ddd()'); +- } +- +- test_UNRESOLVED_INSTANCE_MEMBER_REFERENCE_nonDynamicTarget() async { +- addTestFile(''' +-import 'dart:math' as math; +-main(String str) { +- new Object().aaa(); +- math.bbb(); +- str.ccc(); +-} +-class A { +- m() { +- unresolved(1); +- this.unresolved(2); +- super.unresolved(3); +- } +-} +-'''); +- await prepareHighlights(); +- HighlightRegionType type = HighlightRegionType.IDENTIFIER_DEFAULT; +- assertHasRegion(type, 'aaa()'); +- assertHasRegion(type, 'bbb()'); +- assertHasRegion(type, 'ccc()'); +- assertHasRegion(type, 'unresolved(1)'); +- assertHasRegion(type, 'unresolved(2)'); +- assertHasRegion(type, 'unresolved(3)'); +- } +- +- void _addLibraryForTestPart() { +- addFile('$testFolder/my_lib.dart', ''' +-library lib; +-part 'test.dart'; +- '''); +- } +-} +- +-@reflectiveTest +-class HighlightTypeTest { +- void test_constructor() { +- expect(HighlightRegionType.CLASS, +- new HighlightRegionType(HighlightRegionType.CLASS.name)); +- } +- +- void test_toString() { +- expect(HighlightRegionType.CLASS.toString(), 'HighlightRegionType.CLASS'); +- } +- +- void test_valueOf_unknown() { +- expect(() { +- new HighlightRegionType('no-such-type'); +- }, throwsException); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart +deleted file mode 100644 +index cc80eb999cd..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart ++++ /dev/null +@@ -1,431 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationImplementedTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNotificationImplementedTest extends AbstractAnalysisTest { +- List implementedClasses; +- List implementedMembers; +- +- /** +- * Validates that there is an [ImplementedClass] at the offset of [search]. +- * +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertHasImplementedClass(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- if (implementedClasses == null) { +- fail('No notification of impemented classes was received'); +- } +- for (ImplementedClass clazz in implementedClasses) { +- if (clazz.offset == offset && clazz.length == length) { +- return; +- } +- } +- fail('Expect to find an implemented class at $offset' +- ' in $implementedClasses'); +- } +- +- /** +- * Validates that there is an [ImplementedClass] at the offset of [search]. +- * +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertHasImplementedMember(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- if (implementedMembers == null) { +- fail('No notification of impemented members was received'); +- } +- for (ImplementedMember member in implementedMembers) { +- if (member.offset == offset && member.length == length) { +- return; +- } +- } +- fail('Expect to find an implemented member at $offset' +- ' in $implementedMembers'); +- } +- +- /** +- * Validates that there is no an [ImplementedClass] at the offset of [search]. +- * +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertNoImplementedMember(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- if (implementedMembers == null) { +- fail('No notification of impemented members was received'); +- } +- for (ImplementedMember member in implementedMembers) { +- if (member.offset == offset) { +- fail('Unexpected implemented member at $offset' +- ' in $implementedMembers'); +- } +- } +- } +- +- /** +- * Subscribe for `IMPLEMENTED` and wait for the notification. +- */ +- Future prepareImplementedElements() { +- subscribeForImplemented(); +- return waitForImplementedElements(); +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_IMPLEMENTED) { +- var params = new AnalysisImplementedParams.fromNotification(notification); +- if (params.file == testFile) { +- implementedClasses = params.classes; +- implementedMembers = params.members; +- } +- } +- } +- +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- void subscribeForImplemented() { +- setPriorityFiles([testFile]); +- addAnalysisSubscription(AnalysisService.IMPLEMENTED, testFile); +- } +- +- test_afterAnalysis() async { +- addTestFile(''' +-class A {} +-class B extends A {} +-'''); +- await waitForTasksFinished(); +- await prepareImplementedElements(); +- assertHasImplementedClass('A {'); +- } +- +- test_afterIncrementalResolution() async { +- subscribeForImplemented(); +- addTestFile(''' +-class A {} +-class B extends A {} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedClass('A {'); +- // add a space +- implementedClasses = null; +- testCode = ''' +-class A {} +-class B extends A {} +-'''; +- server.updateContent('1', {testFile: new AddContentOverlay(testCode)}); +- await waitForImplementedElements(); +- assertHasImplementedClass('A {'); +- } +- +- test_class_extended() async { +- addTestFile(''' +-class A {} +-class B extends A {} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedClass('A {'); +- } +- +- test_class_implemented() async { +- addTestFile(''' +-class A {} +-class B implements A {} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedClass('A {'); +- } +- +- test_class_mixed() async { +- addTestFile(''' +-class A {} +-class B = Object with A; +-'''); +- await prepareImplementedElements(); +- assertHasImplementedClass('A {'); +- } +- +- test_field_withField() async { +- addTestFile(''' +-class A { +- int f; // A +-} +-class B extends A { +- int f; +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f; // A'); +- } +- +- test_field_withGetter() async { +- addTestFile(''' +-class A { +- int f; // A +-} +-class B extends A { +- get f => null; +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f; // A'); +- } +- +- test_field_withSetter() async { +- addTestFile(''' +-class A { +- int f; // A +-} +-class B extends A { +- void set f(_) {} +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f; // A'); +- } +- +- test_getter_withField() async { +- addTestFile(''' +-class A { +- get f => null; // A +-} +-class B extends A { +- int f; +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f => null; // A'); +- } +- +- test_getter_withGetter() async { +- addTestFile(''' +-class A { +- get f => null; // A +-} +-class B extends A { +- get f => null; +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f => null; // A'); +- } +- +- test_method_withMethod() async { +- addTestFile(''' +-class A { +- m() {} // A +-} +-class B extends A { +- m() {} // B +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('m() {} // A'); +- assertNoImplementedMember('m() {} // B'); +- } +- +- test_method_withMethod_indirectSubclass() async { +- addTestFile(''' +-class A { +- m() {} // A +-} +-class B extends A { +-} +-class C extends A { +- m() {} +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('m() {} // A'); +- } +- +- test_method_withMethod_private_differentLib() async { +- addFile('$testFolder/lib.dart', r''' +-import 'test.dart'; +-class B extends A { +- void _m() {} +-} +-'''); +- addTestFile(''' +-class A { +- _m() {} // A +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('_m() {} // A'); +- } +- +- test_method_withMethod_private_sameLibrary() async { +- addTestFile(''' +-class A { +- _m() {} // A +-} +-class B extends A { +- _m() {} // B +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('_m() {} // A'); +- assertNoImplementedMember('_m() {} // B'); +- } +- +- test_method_withMethod_wasAbstract() async { +- addTestFile(''' +-abstract class A { +- m(); // A +-} +-class B extends A { +- m() {} +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('m(); // A'); +- } +- +- test_setter_withField() async { +- addTestFile(''' +-class A { +- set f(_) {} // A +-} +-class B extends A { +- int f; +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f(_) {} // A'); +- } +- +- test_setter_withSetter() async { +- addTestFile(''' +-class A { +- set f(_) {} // A +-} +-class B extends A { +- set f(_) {} // B +-} +-'''); +- await prepareImplementedElements(); +- assertHasImplementedMember('f(_) {} // A'); +- } +- +- test_static_field_instanceStatic() async { +- addTestFile(''' +-class A { +- int F = 0; +-} +-class B extends A { +- static int F = 1; +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('F = 0'); +- } +- +- test_static_field_staticInstance() async { +- addTestFile(''' +-class A { +- static int F = 0; +-} +-class B extends A { +- int F = 1; +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('F = 0'); +- } +- +- test_static_field_staticStatic() async { +- addTestFile(''' +-class A { +- static int F = 0; +-} +-class B extends A { +- static int F = 1; +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('F = 0'); +- } +- +- test_static_method_instanceStatic() async { +- addTestFile(''' +-class A { +- int m() => 0; +-} +-class B extends A { +- static int m() => 1; +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('m() => 0'); +- } +- +- test_static_method_staticInstance() async { +- addTestFile(''' +-class A { +- static int m() => 0; +-} +-class B extends A { +- int m() => 1; +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('m() => 0'); +- } +- +- test_static_method_staticStatic() async { +- addTestFile(''' +-class A { +- static int m() => 0; +-} +-class B extends A { +- static int m() => 1; +-} +-'''); +- await prepareImplementedElements(); +- assertNoImplementedMember('m() => 0'); +- } +- +- Future waitForImplementedElements() { +- Future waitForNotification(int times) { +- if (times == 0 || implementedClasses != null) { +- return new Future.value(); +- } +- return new Future.delayed( +- new Duration(milliseconds: 1), () => waitForNotification(times - 1)); +- } +- +- return waitForNotification(30000); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart +deleted file mode 100644 +index f57c6715326..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart ++++ /dev/null +@@ -1,1031 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationNavigationTest); +- }); +-} +- +-class AbstractNavigationTest extends AbstractAnalysisTest { +- List regions; +- List targets; +- List targetFiles; +- +- NavigationRegion testRegion; +- List testTargetIndexes; +- List testTargets; +- NavigationTarget testTarget; +- +- /** +- * Validates that there is a target in [testTargetIndexes] with [file], +- * at [offset] and with the given [length]. +- */ +- void assertHasFileTarget(String file, int offset, int length) { +- for (NavigationTarget target in testTargets) { +- if (targetFiles[target.fileIndex] == file && +- target.offset == offset && +- target.length == length) { +- testTarget = target; +- return; +- } +- } +- fail( +- 'Expected to find target (file=$file; offset=$offset; length=$length) in\n' +- '$testRegion in\n' +- '${testTargets.join('\n')}'); +- } +- +- void assertHasOperatorRegion(String regionSearch, int regionLength, +- String targetSearch, int targetLength) { +- assertHasRegion(regionSearch, regionLength); +- assertHasTarget(targetSearch, targetLength); +- } +- +- /** +- * Validates that there is a region at the offset of [search] in [testFile]. +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertHasRegion(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- findRegion(offset, length, true); +- } +- +- /** +- * Validates that there is a region at the offset of [search] in [testFile] +- * with the given [length] or the length of [search]. +- */ +- void assertHasRegionString(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = search.length; +- } +- findRegion(offset, length, true); +- } +- +- /** +- * Validates that there is an identifier region at [regionSearch] with target +- * at [targetSearch]. +- */ +- void assertHasRegionTarget(String regionSearch, String targetSearch) { +- assertHasRegion(regionSearch); +- assertHasTarget(targetSearch); +- } +- +- /** +- * Validates that there is a target in [testTargets] with [testFile], at the +- * offset of [search] in [testFile], and with the given [length] or the length +- * of an leading identifier in [search]. +- */ +- void assertHasTarget(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- assertHasFileTarget(testFile, offset, length); +- } +- +- /** +- * Validates that there is a target in [testTargets] with [testFile], at the +- * offset of [str] in [testFile], and with the length of [str]. +- */ +- void assertHasTargetString(String str) { +- assertHasTarget(str, str.length); +- } +- +- /** +- * Validates that there is no a region at [search] and with the given +- * [length]. +- */ +- void assertNoRegion(String search, int length) { +- int offset = findOffset(search); +- findRegion(offset, length, false); +- } +- +- /** +- * Validates that there is no a region at [search] with any length. +- */ +- void assertNoRegionAt(String search) { +- int offset = findOffset(search); +- findRegion(offset, -1, false); +- } +- +- /** +- * Validates that there is no a region for [search] string. +- */ +- void assertNoRegionString(String search) { +- int offset = findOffset(search); +- int length = search.length; +- findRegion(offset, length, false); +- } +- +- void assertRegionsSorted() { +- int lastEnd = -1; +- for (NavigationRegion region in regions) { +- int offset = region.offset; +- if (offset < lastEnd) { +- fail('$lastEnd was expected to be > $offset in\n' + regions.join('\n')); +- } +- lastEnd = offset + region.length; +- } +- } +- +- /** +- * Finds the navigation region with the given [offset] and [length]. +- * If [length] is `-1`, then it is ignored. +- * +- * If [exists] is `true`, then fails if such region does not exist. +- * Otherwise remembers this it into [testRegion]. +- * Also fills [testTargets] with its targets. +- * +- * If [exists] is `false`, then fails if such region exists. +- */ +- void findRegion(int offset, int length, bool exists) { +- for (NavigationRegion region in regions) { +- if (region.offset == offset && +- (length == -1 || region.length == length)) { +- if (exists == false) { +- fail('Not expected to find (offset=$offset; length=$length) in\n' +- '${regions.join('\n')}'); +- } +- testRegion = region; +- testTargetIndexes = region.targets; +- testTargets = testTargetIndexes.map((i) => targets[i]).toList(); +- return; +- } +- } +- if (exists == true) { +- fail('Expected to find (offset=$offset; length=$length) in\n' +- '${regions.join('\n')}'); +- } +- } +-} +- +-@reflectiveTest +-class AnalysisNotificationNavigationTest extends AbstractNavigationTest { +- Completer _resultsAvailable = new Completer(); +- +- Future prepareNavigation() async { +- addAnalysisSubscription(AnalysisService.NAVIGATION, testFile); +- await _resultsAvailable.future; +- assertRegionsSorted(); +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_NAVIGATION) { +- var params = new AnalysisNavigationParams.fromNotification(notification); +- if (params.file == testFile) { +- regions = params.regions; +- targets = params.targets; +- targetFiles = params.files; +- _resultsAvailable.complete(null); +- } +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- test_afterAnalysis() async { +- addTestFile(''' +-class AAA {} +-AAA aaa; +-'''); +- await waitForTasksFinished(); +- await prepareNavigation(); +- assertHasRegionTarget('AAA aaa;', 'AAA {}'); +- } +- +- test_annotationConstructor_implicit() async { +- addTestFile(''' +-class A { +-} +-@A() +-main() { +-} +-'''); +- await prepareNavigation(); +- assertHasRegionString('A()', 'A'.length); +- assertHasTarget('A {'); +- } +- +- test_annotationConstructor_importPrefix() async { +- addFile('$testFolder/my_annotation.dart', r''' +-library an; +-class MyAnnotation { +- const MyAnnotation(); +- const MyAnnotation.named(); +-} +-'''); +- addTestFile(''' +-import 'my_annotation.dart' as man; +-@man.MyAnnotation() +-@man.MyAnnotation.named() +-main() { +-} +-'''); +- await prepareNavigation(); +- assertHasRegion('MyAnnotation()'); +- assertHasRegion('MyAnnotation.named()'); +- assertHasRegion('named()'); +- { +- assertHasRegion('man.MyAnnotation()'); +- assertHasTarget('man;'); +- } +- { +- assertHasRegion('man.MyAnnotation.named()'); +- assertHasTarget('man;'); +- } +- } +- +- test_annotationConstructor_named() async { +- addTestFile(''' +-class A { +- const A.named(p); +-} +-@A.named(0) +-main() { +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('A.named(0)'); +- assertHasTarget('named(p);'); +- } +- { +- assertHasRegion('named(0)'); +- assertHasTarget('named(p);'); +- } +- } +- +- test_annotationConstructor_unnamed() async { +- addTestFile(''' +-class A { +- const A(); +-} +-@A() +-main() { +-} +-'''); +- await prepareNavigation(); +- assertHasRegionString('A()', 'A'.length); +- assertHasTarget('A();', 0); +- } +- +- test_annotationField() async { +- addTestFile(''' +-const myan = new Object(); +-@myan // ref +-main() { +-} +-'''); +- await prepareNavigation(); +- assertHasRegion('myan // ref'); +- assertHasTarget('myan = new Object();'); +- } +- +- test_annotationField_importPrefix() async { +- addFile('$testFolder/mayn.dart', r''' +-library an; +-const myan = new Object(); +-'''); +- addTestFile(''' +-import 'mayn.dart' as man; +-@man.myan // ref +-main() { +-} +-'''); +- await prepareNavigation(); +- assertHasRegion('myan // ref'); +- } +- +- test_class_fromSDK() async { +- addTestFile(''' +-int V = 42; +-'''); +- await prepareNavigation(); +- assertHasRegion('int V'); +- int targetIndex = testTargetIndexes[0]; +- NavigationTarget target = targets[targetIndex]; +- expect(target.startLine, greaterThan(0)); +- expect(target.startColumn, greaterThan(0)); +- } +- +- test_constructor_named() async { +- addTestFile(''' +-class A { +- A.named(BBB p) {} +-} +-class BBB {} +-'''); +- await prepareNavigation(); +- // has region for complete "A.named" +- assertHasRegionString('A.named'); +- assertHasTarget('named(BBB'); +- // no separate regions for "A" and "named" +- assertNoRegion('A.named(', 'A'.length); +- assertNoRegion('named(', 'named'.length); +- // validate that we don't forget to resolve parameters +- assertHasRegionTarget('BBB p', 'BBB {}'); +- } +- +- test_constructor_unnamed() async { +- addTestFile(''' +-class A { +- A(BBB p) {} +-} +-class BBB {} +-'''); +- await prepareNavigation(); +- // has region for complete "A.named" +- assertHasRegion("A(BBB"); +- assertHasTarget("A(BBB", 0); +- // validate that we don't forget to resolve parameters +- assertHasRegionTarget('BBB p', 'BBB {}'); +- } +- +- test_factoryRedirectingConstructor_implicit() async { +- addTestFile(''' +-class A { +- factory A() = B; +-} +-class B { +-} +-'''); +- await prepareNavigation(); +- assertHasRegion('B;'); +- assertHasTarget('B {'); +- } +- +- test_factoryRedirectingConstructor_implicit_withTypeArgument() async { +- addTestFile(''' +-class A {} +-class B { +- factory B() = C; +-} +-class C {} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('C'); +- assertHasTarget('C {'); +- } +- { +- assertHasRegion('A>;'); +- assertHasTarget('A {'); +- } +- } +- +- test_factoryRedirectingConstructor_named() async { +- addTestFile(''' +-class A { +- factory A() = B.named; +-} +-class B { +- B.named(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegionString('B.named;', 'B'.length); +- assertHasTarget('named();'); +- } +- { +- assertHasRegionString('named;', 'named'.length); +- assertHasTarget('named();'); +- } +- } +- +- test_factoryRedirectingConstructor_named_withTypeArgument() async { +- addTestFile(''' +-class A {} +-class B { +- factory B.named() = C.named; +-} +-class C { +- C.named() {} +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('C'); +- assertHasTarget('named() {}'); +- } +- { +- assertHasRegion('A>.named'); +- assertHasTarget('A {'); +- } +- { +- assertHasRegion('named;', 'named'.length); +- assertHasTarget('named() {}'); +- } +- } +- +- test_factoryRedirectingConstructor_unnamed() async { +- addTestFile(''' +-class A { +- factory A() = B; +-} +-class B { +- B() {} +-} +-'''); +- await prepareNavigation(); +- assertHasRegion('B;'); +- assertHasTarget('B() {}', 0); +- } +- +- test_factoryRedirectingConstructor_unnamed_withTypeArgument() async { +- addTestFile(''' +-class A {} +-class B { +- factory B() = C; +-} +-class C { +- C() {} +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('C'); +- assertHasTarget('C() {}', 0); +- } +- { +- assertHasRegion('A>;'); +- assertHasTarget('A {'); +- } +- } +- +- test_factoryRedirectingConstructor_unresolved() async { +- addTestFile(''' +-class A { +- factory A() = B; +-} +-'''); +- await prepareNavigation(); +- // don't check regions, but there should be no exceptions +- } +- +- test_fieldFormalParameter() async { +- addTestFile(''' +-class AAA { +- int fff = 123; +- AAA(this.fff); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('fff);', 'fff = 123'); +- } +- +- test_fieldFormalParameter_unresolved() async { +- addTestFile(''' +-class AAA { +- AAA(this.fff); +-} +-'''); +- await prepareNavigation(); +- assertNoRegion('fff);', 3); +- } +- +- test_identifier_resolved() async { +- addTestFile(''' +-class AAA {} +-main() { +- AAA aaa = null; +- print(aaa); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('AAA aaa', 'AAA {}'); +- assertHasRegionTarget('aaa);', 'aaa = null'); +- assertHasRegionTarget('main() {', 'main() {'); +- } +- +- test_identifier_unresolved() async { +- addTestFile(''' +-main() { +- print(vvv); +-} +-'''); +- await prepareNavigation(); +- assertNoRegionString('vvv'); +- } +- +- test_identifier_whenStrayImportDirective() async { +- addTestFile(''' +-main() { +- int aaa = 42; +- print(aaa); +-} +-import 'dart:math'; +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('aaa);', 'aaa = 42'); +- } +- +- test_inComment() async { +- addTestFile(''' +-class FirstClass {} +-class SecondClass { +- /** +- * Return a [FirstClass] object equivalent to this object in every other way. +- */ +- convert() { +- return new FirstClass(); +- } +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('FirstClass]', 'FirstClass {'); +- assertHasRegionTarget('FirstClass(', 'FirstClass {'); +- } +- +- test_instanceCreation_implicit() async { +- addTestFile(''' +-class A { +-} +-main() { +- new A(); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionString('A()', 'A'.length); +- assertHasTarget('A {'); +- } +- +- test_instanceCreation_implicit_withTypeArgument() async { +- addTestFile(''' +-class A {} +-class B {} +-main() { +- new B(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('B', 'B'.length); +- assertHasTarget('B {'); +- } +- { +- assertHasRegion('A>();', 'A'.length); +- assertHasTarget('A {'); +- } +- } +- +- test_instanceCreation_named() async { +- addTestFile(''' +-class A { +- A.named() {} +-} +-main() { +- new A.named(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegionString('A.named();', 'A'.length); +- assertHasTarget('named() {}'); +- } +- { +- assertHasRegionString('named();', 'named'.length); +- assertHasTarget('named() {}'); +- } +- } +- +- test_instanceCreation_named_withTypeArgument() async { +- addTestFile(''' +-class A {} +-class B { +- B.named() {} +-} +-main() { +- new B.named(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegionString('B', 'B'.length); +- assertHasTarget('named() {}'); +- } +- { +- assertHasRegion('A>.named'); +- assertHasTarget('A {'); +- } +- { +- assertHasRegion('named();', 'named'.length); +- assertHasTarget('named() {}'); +- } +- } +- +- test_instanceCreation_unnamed() async { +- addTestFile(''' +-class A { +- A() {} +-} +-main() { +- new A(); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionString('A();', 'A'.length); +- assertHasTarget('A() {}', 0); +- } +- +- test_instanceCreation_unnamed_withTypeArgument() async { +- addTestFile(''' +-class A {} +-class B { +- B() {} +-} +-main() { +- new B(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegionString('B();', 'B'.length); +- assertHasTarget('B() {}', 0); +- } +- { +- assertHasRegion('A>();'); +- assertHasTarget('A {'); +- } +- } +- +- test_instanceCreation_withImportPrefix_named() async { +- addTestFile(''' +-import 'dart:async' as ppp; +-main() { +- new ppp.Future.value(42); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('ppp.'); +- assertHasTarget('ppp;'); +- } +- assertHasRegion('Future.value'); +- assertHasRegion('value(42)'); +- } +- +- test_library() async { +- addTestFile(''' +-library my.lib; +-'''); +- await prepareNavigation(); +- assertHasRegionString('my.lib'); +- assertHasTargetString('my.lib'); +- } +- +- test_multiplyDefinedElement() async { +- addFile('$projectPath/bin/libA.dart', 'library A; int TEST = 1;'); +- addFile('$projectPath/bin/libB.dart', 'library B; int TEST = 2;'); +- addTestFile(''' +-import 'libA.dart'; +-import 'libB.dart'; +-main() { +- TEST; +-} +-'''); +- await prepareNavigation(); +- assertNoRegionAt('TEST'); +- } +- +- test_operator_arithmetic() async { +- addTestFile(''' +-class A { +- A operator +(other) => null; +- A operator -() => null; +- A operator -(other) => null; +- A operator *(other) => null; +- A operator /(other) => null; +-} +-main() { +- var a = new A(); +- a - 1; +- a + 2; +- -a; // unary +- --a; +- ++a; +- a--; // mm +- a++; // pp +- a -= 3; +- a += 4; +- a *= 5; +- a /= 6; +-} +-'''); +- await prepareNavigation(); +- assertHasOperatorRegion('- 1', 1, '-(other) => null', 1); +- assertHasOperatorRegion('+ 2', 1, '+(other) => null', 1); +- assertHasOperatorRegion('-a; // unary', 1, '-() => null', 1); +- assertHasOperatorRegion('--a;', 2, '-(other) => null', 1); +- assertHasOperatorRegion('++a;', 2, '+(other) => null', 1); +- assertHasOperatorRegion('--; // mm', 2, '-(other) => null', 1); +- assertHasOperatorRegion('++; // pp', 2, '+(other) => null', 1); +- assertHasOperatorRegion('-= 3', 2, '-(other) => null', 1); +- assertHasOperatorRegion('+= 4', 2, '+(other) => null', 1); +- assertHasOperatorRegion('*= 5', 2, '*(other) => null', 1); +- assertHasOperatorRegion('/= 6', 2, '/(other) => null', 1); +- } +- +- test_operator_index() async { +- addTestFile(''' +-class A { +- A operator +(other) => null; +-} +-class B { +- A operator [](index) => null; +- operator []=(index, A value) {} +-} +-main() { +- var b = new B(); +- b[0] // []; +- b[1] = 1; // []=; +- b[2] += 2; +-} +-'''); +- await prepareNavigation(); +- assertHasOperatorRegion('[0', 1, '[](index)', 2); +- assertHasOperatorRegion('] // []', 1, '[](index)', 2); +- assertHasOperatorRegion('[1', 1, '[]=(index,', 3); +- assertHasOperatorRegion('] = 1;', 1, '[]=(index,', 3); +- assertHasOperatorRegion('[2', 1, '[]=(index,', 3); +- assertHasOperatorRegion('] += 2;', 1, '[]=(index,', 3); +- assertHasOperatorRegion('+= 2;', 2, '+(other)', 1); +- } +- +- test_partOf() async { +- var libCode = 'library lib; part "test.dart";'; +- var libFile = addFile('$projectPath/bin/lib.dart', libCode); +- addTestFile('part of lib;'); +- await prepareNavigation(); +- assertHasRegionString('lib'); +- assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length); +- } +- +- test_redirectingConstructorInvocation() async { +- addTestFile(''' +-class A { +- A() {} +- A.foo() : this(); +- A.bar() : this.foo(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegion('this();'); +- assertHasTarget('A() {}', 0); +- } +- { +- assertHasRegion('this.foo'); +- assertHasTarget('foo() :'); +- } +- { +- assertHasRegion('foo();'); +- assertHasTarget('foo() :'); +- } +- } +- +- test_string_export() async { +- var libCode = 'library lib;'; +- var libFile = addFile('$projectPath/bin/lib.dart', libCode); +- addTestFile('export "lib.dart";'); +- await prepareNavigation(); +- assertHasRegionString('"lib.dart"'); +- assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length); +- } +- +- test_string_export_unresolvedUri() async { +- addTestFile('export "no.dart";'); +- await prepareNavigation(); +- assertNoRegionString('"no.dart"'); +- } +- +- test_string_import() async { +- var libCode = 'library lib;'; +- var libFile = addFile('$projectPath/bin/lib.dart', libCode); +- addTestFile('import "lib.dart";'); +- await prepareNavigation(); +- assertHasRegionString('"lib.dart"'); +- assertHasFileTarget(libFile, libCode.indexOf('lib;'), 'lib'.length); +- } +- +- test_string_import_noUri() async { +- addTestFile('import ;'); +- await prepareNavigation(); +- assertNoRegionAt('import ;'); +- } +- +- test_string_import_unresolvedUri() async { +- addTestFile('import "no.dart";'); +- await prepareNavigation(); +- assertNoRegionString('"no.dart"'); +- } +- +- test_string_part() async { +- var unitCode = 'part of lib; f() {}'; +- var unitFile = addFile('$projectPath/bin/test_unit.dart', unitCode); +- addTestFile(''' +-library lib; +-part "test_unit.dart"; +-'''); +- await prepareNavigation(); +- assertHasRegionString('"test_unit.dart"'); +- assertHasFileTarget(unitFile, 0, 0); +- } +- +- test_string_part_unresolvedUri() async { +- addTestFile(''' +-library lib; +-part "test_unit.dart"; +-'''); +- await prepareNavigation(); +- assertNoRegionString('"test_unit.dart"'); +- } +- +- test_superConstructorInvocation() async { +- addTestFile(''' +-class A { +- A() {} +- A.named() {} +-} +-class B extends A { +- B() : super(); +- B.named() : super.named(); +-} +-'''); +- await prepareNavigation(); +- { +- assertHasRegionString('super'); +- assertHasTarget('A() {}', 0); +- } +- { +- assertHasRegion('super.named'); +- assertHasTarget('named() {}'); +- } +- { +- assertHasRegion('named();'); +- assertHasTarget('named() {}'); +- } +- } +- +- test_superConstructorInvocation_synthetic() async { +- addTestFile(''' +-class A { +-} +-class B extends A { +- B() : super(); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionString('super'); +- assertHasTarget('A {'); +- } +- +- test_targetElement() async { +- addTestFile(''' +-class AAA {} +-main() { +- AAA aaa = null; +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('AAA aaa', 'AAA {}'); +- expect(testTarget.kind, ElementKind.CLASS); +- } +- +- test_type_dynamic() async { +- addTestFile(''' +-main() { +- dynamic v = null; +-} +-'''); +- await prepareNavigation(); +- assertNoRegionAt('dynamic'); +- } +- +- test_type_void() async { +- addTestFile(''' +-void main() { +-} +-'''); +- await prepareNavigation(); +- assertNoRegionAt('void'); +- } +- +- test_var_declaredVariable() async { +- addTestFile(''' +-class C {} +-f(List items) { +- for (var item in items) {} +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('var', 'C {}'); +- expect(testTarget.kind, ElementKind.CLASS); +- } +- +- test_var_localVariable_multiple_inferred_different() async { +- addTestFile(''' +-class A {} +-class B {} +-void f() { +- var a = new A(), b = new B(); +-} +-'''); +- await prepareNavigation(); +- assertNoRegionAt('var'); +- } +- +- test_var_localVariable_multiple_inferred_same() async { +- addTestFile(''' +-class C {} +-void f() { +- var a = new C(), b = new C(); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('var', 'C {}'); +- expect(testTarget.kind, ElementKind.CLASS); +- } +- +- test_var_localVariable_single_inferred() async { +- addTestFile(''' +-class C {} +-f() { +- var c = new C(); +-} +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('var', 'C {}'); +- expect(testTarget.kind, ElementKind.CLASS); +- } +- +- test_var_localVariable_single_notInferred() async { +- addTestFile(''' +-f() { +- var x; +-} +-'''); +- await prepareNavigation(); +- assertNoRegionAt('var'); +- } +- +- test_var_topLevelVariable_multiple_inferred_different() async { +- addTestFile(''' +-class A {} +-class B {} +-var a = new A(), b = new B(); +-'''); +- await prepareNavigation(); +- assertNoRegionAt('var'); +- } +- +- test_var_topLevelVariable_multiple_inferred_same() async { +- addTestFile(''' +-class C {} +-var a = new C(), b = new C(); +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('var', 'C {}'); +- expect(testTarget.kind, ElementKind.CLASS); +- } +- +- test_var_topLevelVariable_single_inferred() async { +- addTestFile(''' +-class C {} +-var c = new C(); +-'''); +- await prepareNavigation(); +- assertHasRegionTarget('var', 'C {}'); +- expect(testTarget.kind, ElementKind.CLASS); +- } +- +- test_var_topLevelVariable_single_notInferred() async { +- addTestFile(''' +-var x; +-'''); +- await prepareNavigation(); +- assertNoRegionAt('var'); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart +deleted file mode 100644 +index df66d76d1eb..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart ++++ /dev/null +@@ -1,257 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationOccurrencesTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNotificationOccurrencesTest extends AbstractAnalysisTest { +- List occurrencesList; +- Occurrences testOccurrences; +- +- Completer _resultsAvailable = new Completer(); +- +- /** +- * Asserts that there is an offset of [search] in [testOccurrences]. +- */ +- void assertHasOffset(String search) { +- int offset = findOffset(search); +- expect(testOccurrences.offsets, contains(offset)); +- } +- +- /** +- * Validates that there is a region at the offset of [search] in [testFile]. +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertHasRegion(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- findRegion(offset, length, true); +- } +- +- /** +- * Finds an [Occurrences] with the given [offset] and [length]. +- * +- * If [exists] is `true`, then fails if such [Occurrences] does not exist. +- * Otherwise remembers this it into [testOccurrences]. +- * +- * If [exists] is `false`, then fails if such [Occurrences] exists. +- */ +- void findRegion(int offset, int length, [bool exists]) { +- for (Occurrences occurrences in occurrencesList) { +- if (occurrences.length != length) { +- continue; +- } +- for (int occurrenceOffset in occurrences.offsets) { +- if (occurrenceOffset == offset) { +- if (exists == false) { +- fail('Not expected to find (offset=$offset; length=$length) in\n' +- '${occurrencesList.join('\n')}'); +- } +- testOccurrences = occurrences; +- return; +- } +- } +- } +- if (exists == true) { +- fail('Expected to find (offset=$offset; length=$length) in\n' +- '${occurrencesList.join('\n')}'); +- } +- } +- +- Future prepareOccurrences() { +- addAnalysisSubscription(AnalysisService.OCCURRENCES, testFile); +- return _resultsAvailable.future; +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_OCCURRENCES) { +- var params = new AnalysisOccurrencesParams.fromNotification(notification); +- if (params.file == testFile) { +- occurrencesList = params.occurrences; +- _resultsAvailable.complete(null); +- } +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- test_afterAnalysis() async { +- addTestFile(''' +-main() { +- var vvv = 42; +- print(vvv); +-} +-'''); +- await waitForTasksFinished(); +- await prepareOccurrences(); +- assertHasRegion('vvv ='); +- expect(testOccurrences.element.kind, ElementKind.LOCAL_VARIABLE); +- expect(testOccurrences.element.name, 'vvv'); +- assertHasOffset('vvv = 42'); +- assertHasOffset('vvv);'); +- } +- +- test_field() async { +- addTestFile(''' +-class A { +- int fff; +- A(this.fff); // constructor +- main() { +- fff = 42; +- print(fff); // print +- } +-} +-'''); +- await prepareOccurrences(); +- assertHasRegion('fff;'); +- expect(testOccurrences.element.kind, ElementKind.FIELD); +- assertHasOffset('fff); // constructor'); +- assertHasOffset('fff = 42;'); +- assertHasOffset('fff); // print'); +- } +- +- test_field_unresolved() async { +- addTestFile(''' +-class A { +- A(this.noSuchField); +-} +-'''); +- // no checks for occurrences, just ensure that there is no NPE +- await prepareOccurrences(); +- } +- +- test_localVariable() async { +- addTestFile(''' +-main() { +- var vvv = 42; +- vvv += 5; +- print(vvv); +-} +-'''); +- await prepareOccurrences(); +- assertHasRegion('vvv ='); +- expect(testOccurrences.element.kind, ElementKind.LOCAL_VARIABLE); +- expect(testOccurrences.element.name, 'vvv'); +- assertHasOffset('vvv = 42'); +- assertHasOffset('vvv += 5'); +- assertHasOffset('vvv);'); +- } +- +- test_memberField() async { +- addTestFile(''' +-class A { +- T fff; +-} +-main() { +- var a = new A(); +- var b = new A(); +- a.fff = 1; +- b.fff = 2; +-} +-'''); +- await prepareOccurrences(); +- assertHasRegion('fff;'); +- expect(testOccurrences.element.kind, ElementKind.FIELD); +- assertHasOffset('fff = 1;'); +- assertHasOffset('fff = 2;'); +- } +- +- test_memberMethod() async { +- addTestFile(''' +-class A { +- T mmm() {} +-} +-main() { +- var a = new A(); +- var b = new A(); +- a.mmm(); // a +- b.mmm(); // b +-} +-'''); +- await prepareOccurrences(); +- assertHasRegion('mmm() {}'); +- expect(testOccurrences.element.kind, ElementKind.METHOD); +- assertHasOffset('mmm(); // a'); +- assertHasOffset('mmm(); // b'); +- } +- +- test_topLevelVariable() async { +- addTestFile(''' +-var VVV = 1; +-main() { +- VVV = 2; +- print(VVV); +-} +-'''); +- await prepareOccurrences(); +- assertHasRegion('VVV = 1;'); +- expect(testOccurrences.element.kind, ElementKind.TOP_LEVEL_VARIABLE); +- assertHasOffset('VVV = 2;'); +- assertHasOffset('VVV);'); +- } +- +- test_type_class() async { +- addTestFile(''' +-main() { +- int a = 1; +- int b = 2; +- int c = 3; +-} +-int VVV = 4; +-'''); +- await prepareOccurrences(); +- assertHasRegion('int a'); +- expect(testOccurrences.element.kind, ElementKind.CLASS); +- expect(testOccurrences.element.name, 'int'); +- assertHasOffset('int a'); +- assertHasOffset('int b'); +- assertHasOffset('int c'); +- assertHasOffset('int VVV'); +- } +- +- test_type_dynamic() async { +- addTestFile(''' +-main() { +- dynamic a = 1; +- dynamic b = 2; +-} +-dynamic V = 3; +-'''); +- await prepareOccurrences(); +- int offset = findOffset('dynamic a'); +- findRegion(offset, 'dynamic'.length, false); +- } +- +- test_type_void() async { +- addTestFile(''' +-void main() { +-} +-'''); +- await prepareOccurrences(); +- int offset = findOffset('void main()'); +- findRegion(offset, 'void'.length, false); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart +deleted file mode 100644 +index f3e6f4f34d7..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_outline_test.dart ++++ /dev/null +@@ -1,135 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(_AnalysisNotificationOutlineTest); +- }); +-} +- +-@reflectiveTest +-class _AnalysisNotificationOutlineTest extends AbstractAnalysisTest { +- FileKind fileKind; +- String libraryName; +- Outline outline; +- +- Completer _outlineReceived = new Completer(); +- Completer _highlightsReceived = new Completer(); +- +- Future prepareOutline() { +- addAnalysisSubscription(AnalysisService.OUTLINE, testFile); +- return _outlineReceived.future; +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_OUTLINE) { +- var params = new AnalysisOutlineParams.fromNotification(notification); +- if (params.file == testFile) { +- fileKind = params.kind; +- libraryName = params.libraryName; +- outline = params.outline; +- _outlineReceived.complete(null); +- } +- } +- if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) { +- var params = new AnalysisHighlightsParams.fromNotification(notification); +- if (params.file == testFile) { +- _highlightsReceived?.complete(null); +- _highlightsReceived = null; +- } +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- test_afterAnalysis() async { +- addTestFile(''' +-class AAA { +-} +-class BBB { +-} +-'''); +- await waitForTasksFinished(); +- expect(outline, isNull); +- await prepareOutline(); +- Outline unitOutline = outline; +- List outlines = unitOutline.children; +- expect(outlines, hasLength(2)); +- } +- +- test_libraryName_hasLibraryDirective() async { +- addTestFile(''' +-library my.lib; +-'''); +- await prepareOutline(); +- expect(fileKind, FileKind.LIBRARY); +- expect(libraryName, 'my.lib'); +- } +- +- @failingTest +- test_libraryName_hasLibraryPartOfDirectives() async { +- // This appears to have broken with the move to the new analysis driver. +- addTestFile(''' +-part of lib.in.part.of; +-library my.lib; +-'''); +- await prepareOutline(); +- expect(fileKind, FileKind.LIBRARY); +- expect(libraryName, 'my.lib'); +- } +- +- test_libraryName_hasPartOfDirective() async { +- addTestFile(''' +-part of my.lib; +-'''); +- await prepareOutline(); +- expect(fileKind, FileKind.PART); +- expect(libraryName, 'my.lib'); +- } +- +- test_libraryName_noDirectives() async { +- addTestFile(''' +-class A {} +-'''); +- await prepareOutline(); +- expect(fileKind, FileKind.LIBRARY); +- expect(libraryName, isNull); +- } +- +- test_subscribeWhenCachedResultIsAvailable() async { +- // https://github.com/dart-lang/sdk/issues/30238 +- // We need to get notifications for new subscriptions even when the +- // file is a priority file, and there is a cached result available. +- addTestFile(''' +-class A {} +-class B {} +-'''); +- +- // Make the file a priority one and subscribe for other notification. +- // This will pre-cache the analysis result for the file. +- setPriorityFiles([testFile]); +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile); +- await _highlightsReceived.future; +- +- // Now subscribe for outline notification, we must get it even though +- // the result which is used is pre-cached, and not a newly computed. +- await prepareOutline(); +- expect(outline.children, hasLength(2)); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart +deleted file mode 100644 +index 10abe239f0e..00000000000 +--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart ++++ /dev/null +@@ -1,577 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNotificationOverridesTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNotificationOverridesTest extends AbstractAnalysisTest { +- List overridesList; +- Override override; +- +- Completer _resultsAvailable = new Completer(); +- +- /** +- * Asserts that there is an overridden interface [OverriddenMember] at the +- * offset of [search] in [override]. +- */ +- void assertHasInterfaceMember(String search) { +- int offset = findOffset(search); +- for (OverriddenMember member in override.interfaceMembers) { +- if (member.element.location.offset == offset) { +- return; +- } +- } +- fail('Expect to find an overridden interface members at $offset in ' +- '${override.interfaceMembers.join('\n')}'); +- } +- +- /** +- * Validates that there is an [Override] at the offset of [search]. +- * +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertHasOverride(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- findOverride(offset, length, true); +- } +- +- /** +- * Asserts that there is an overridden superclass [OverriddenMember] at the +- * offset of [search] in [override]. +- */ +- void assertHasSuperElement(String search) { +- int offset = findOffset(search); +- OverriddenMember member = override.superclassMember; +- expect(member.element.location.offset, offset); +- } +- +- /** +- * Asserts that there are no overridden members from interfaces. +- */ +- void assertNoInterfaceMembers() { +- expect(override.interfaceMembers, isNull); +- } +- +- /** +- * Validates that there is no [Override] at the offset of [search]. +- * +- * If [length] is not specified explicitly, then length of an identifier +- * from [search] is used. +- */ +- void assertNoOverride(String search, [int length = -1]) { +- int offset = findOffset(search); +- if (length == -1) { +- length = findIdentifierLength(search); +- } +- findOverride(offset, length, false); +- } +- +- /** +- * Asserts that there are no overridden member from the superclass. +- */ +- void assertNoSuperMember() { +- expect(override.superclassMember, isNull); +- } +- +- /** +- * Finds an [Override] with the given [offset] and [length]. +- * +- * If [exists] is `true`, then fails if such [Override] does not exist. +- * Otherwise remembers this it into [override]. +- * +- * If [exists] is `false`, then fails if such [Override] exists. +- */ +- void findOverride(int offset, int length, [bool exists]) { +- for (Override override in overridesList) { +- if (override.offset == offset && override.length == length) { +- if (exists == false) { +- fail('Not expected to find (offset=$offset; length=$length) in\n' +- '${overridesList.join('\n')}'); +- } +- this.override = override; +- return; +- } +- } +- if (exists == true) { +- fail('Expected to find (offset=$offset; length=$length) in\n' +- '${overridesList.join('\n')}'); +- } +- } +- +- Future prepareOverrides() { +- addAnalysisSubscription(AnalysisService.OVERRIDES, testFile); +- return _resultsAvailable.future; +- } +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_OVERRIDES) { +- var params = new AnalysisOverridesParams.fromNotification(notification); +- if (params.file == testFile) { +- overridesList = params.overrides; +- _resultsAvailable.complete(null); +- } +- } +- } +- +- void setUp() { +- super.setUp(); +- createProject(); +- } +- +- test_afterAnalysis() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B implements A { +- m() {} // in B +-} +-'''); +- await waitForTasksFinished(); +- await prepareOverrides(); +- assertHasOverride('m() {} // in B'); +- assertNoSuperMember(); +- assertHasInterfaceMember('m() {} // in A'); +- } +- +- test_BAD_fieldByMethod() async { +- addTestFile(''' +-class A { +- int fff; // in A +-} +-class B extends A { +- fff() {} // in B +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff() {} // in B'); +- } +- +- test_BAD_getterByMethod() async { +- addTestFile(''' +-class A { +- get fff => null; +-} +-class B extends A { +- fff() {} +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff() {}'); +- } +- +- test_BAD_getterBySetter() async { +- addTestFile(''' +-class A { +- get fff => null; +-} +-class B extends A { +- set fff(x) {} +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff(x) {}'); +- } +- +- test_BAD_methodByField() async { +- addTestFile(''' +-class A { +- fff() {} // in A +-} +-class B extends A { +- int fff; // in B +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff; // in B'); +- } +- +- test_BAD_methodByGetter() async { +- addTestFile(''' +-class A { +- fff() {} +-} +-class B extends A { +- int get fff => null; +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff => null'); +- } +- +- test_BAD_methodBySetter() async { +- addTestFile(''' +-class A { +- fff(x) {} // A +-} +-class B extends A { +- set fff(x) {} // B +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff(x) {} // B'); +- } +- +- test_BAD_privateByPrivate_inDifferentLib() async { +- addFile('$testFolder/lib.dart', r''' +-class A { +- void _m() {} +-} +-'''); +- addTestFile(''' +-import 'lib.dart'; +-class B extends A { +- void _m() {} // in B +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('_m() {} // in B'); +- } +- +- test_BAD_setterByGetter() async { +- addTestFile(''' +-class A { +- set fff(x) {} +-} +-class B extends A { +- get fff => null; +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff => null;'); +- } +- +- test_BAD_setterByMethod() async { +- addTestFile(''' +-class A { +- set fff(x) {} // A +-} +-class B extends A { +- fff(x) {} // B +-} +-'''); +- await prepareOverrides(); +- assertNoOverride('fff(x) {} // B'); +- } +- +- test_definedInInterface_ofInterface() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B implements A {} +-class C implements B { +- m() {} // in C +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in C'); +- assertNoSuperMember(); +- assertHasInterfaceMember('m() {} // in A'); +- } +- +- test_definedInInterface_ofSuper() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B implements A {} +-class C extends B { +- m() {} // in C +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in C'); +- assertNoSuperMember(); +- assertHasInterfaceMember('m() {} // in A'); +- } +- +- test_interface_method_direct_multiple() async { +- addTestFile(''' +-class IA { +- m() {} // in IA +-} +-class IB { +- m() {} // in IB +-} +-class A implements IA, IB { +- m() {} // in A +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in A'); +- assertNoSuperMember(); +- assertHasInterfaceMember('m() {} // in IA'); +- assertHasInterfaceMember('m() {} // in IB'); +- } +- +- test_interface_method_direct_single() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B implements A { +- m() {} // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in B'); +- assertNoSuperMember(); +- assertHasInterfaceMember('m() {} // in A'); +- } +- +- test_interface_method_indirect_single() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B extends A { +-} +-class C implements B { +- m() {} // in C +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in C'); +- assertNoSuperMember(); +- assertHasInterfaceMember('m() {} // in A'); +- } +- +- test_interface_stopWhenFound() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B extends A { +- m() {} // in B +-} +-class C implements B { +- m() {} // in C +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in C'); +- expect(override.interfaceMembers, hasLength(2)); +- assertHasInterfaceMember('m() {} // in B'); +- } +- +- test_mix_sameMethod() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-abstract class B extends A { +-} +-class C extends A implements A { +- m() {} // in C +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in C'); +- assertHasSuperElement('m() {} // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_mix_sameMethod_Object_hashCode() async { +- addTestFile(''' +-class A {} +-abstract class B {} +-class C extends A implements A { +- int get hashCode => 42; +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('hashCode => 42;'); +- expect(override.superclassMember, isNotNull); +- expect(override.interfaceMembers, isNull); +- } +- +- test_staticMembers() async { +- addTestFile(''' +-class A { +- static int F = 0; +- static void M() {} +- static int get G => 0; +- static void set S(int v) {} +-} +-class B extends A { +- static int F = 0; +- static void M() {} +- static int get G => 0; +- static void set S(int v) {} +-} +-'''); +- await prepareOverrides(); +- expect(overridesList, isEmpty); +- } +- +- test_super_fieldByField() async { +- addTestFile(''' +-class A { +- int fff; // in A +-} +-class B extends A { +- int fff; // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('fff; // in B'); +- assertHasSuperElement('fff; // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_fieldByGetter() async { +- addTestFile(''' +-class A { +- int fff; // in A +-} +-class B extends A { +- get fff => 0; // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('fff => 0; // in B'); +- assertHasSuperElement('fff; // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_fieldBySetter() async { +- addTestFile(''' +-class A { +- int fff; // in A +-} +-class B extends A { +- set fff(x) {} // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('fff(x) {} // in B'); +- assertHasSuperElement('fff; // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_getterByField() async { +- addTestFile(''' +-class A { +- get fff => 0; // in A +- set fff(x) {} // in A +-} +-class B extends A { +- int fff; // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('fff; // in B'); +- assertHasSuperElement('fff => 0; // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_getterByGetter() async { +- addTestFile(''' +-class A { +- get fff => 0; // in A +-} +-class B extends A { +- get fff => 0; // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('fff => 0; // in B'); +- assertHasSuperElement('fff => 0; // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_method_direct() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B extends A { +- m() {} // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in B'); +- assertHasSuperElement('m() {} // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_method_indirect() async { +- addTestFile(''' +-class A { +- m() {} // in A +-} +-class B extends A { +-} +-class C extends B { +- m() {} // in C +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('m() {} // in C'); +- assertHasSuperElement('m() {} // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_method_privateByPrivate() async { +- addTestFile(''' +-class A { +- _m() {} // in A +-} +-class B extends A { +- _m() {} // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('_m() {} // in B'); +- assertHasSuperElement('_m() {} // in A'); +- assertNoInterfaceMembers(); +- } +- +- test_super_method_superTypeCycle() async { +- addTestFile(''' +-class A extends B { +- m() {} // in A +-} +-class B extends A { +- m() {} // in B +-} +-'''); +- await prepareOverrides(); +- // must finish +- } +- +- test_super_setterBySetter() async { +- addTestFile(''' +-class A { +- set fff(x) {} // in A +-} +-class B extends A { +- set fff(x) {} // in B +-} +-'''); +- await prepareOverrides(); +- assertHasOverride('fff(x) {} // in B'); +- assertHasSuperElement('fff(x) {} // in A'); +- assertNoInterfaceMembers(); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/reanalyze_test.dart b/pkg/analysis_server/test/analysis/reanalyze_test.dart +deleted file mode 100644 +index c78dd97f87c..00000000000 +--- a/pkg/analysis_server/test/analysis/reanalyze_test.dart ++++ /dev/null +@@ -1,75 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ReanalyzeTest); +- }); +-} +- +-@reflectiveTest +-class ReanalyzeTest extends AbstractAnalysisTest { +- Map> filesErrors = {}; +- +- Completer _resultsAvailable = new Completer(); +- +- @override +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { +- var decoded = new AnalysisErrorsParams.fromNotification(notification); +- filesErrors[decoded.file] = decoded.errors; +- _resultsAvailable.complete(null); +- } +- } +- +- test_reanalyze() { +- createProject(); +- Map drivers = server.driverMap; +- expect(drivers, hasLength(1)); +- Request request = new Request("0", ANALYSIS_REQUEST_REANALYZE); +- handleSuccessfulRequest(request); +- drivers = server.driverMap; +- expect(drivers, hasLength(1)); +- } +- +- test_reanalyze_with_overlay() async { +- createProject(); +- resourceProvider.newFolder(testFolder); +- resourceProvider.newFile(testFile, 'main() {}'); +- // Update the content with an overlay that contains a syntax error. +- server.updateContent('1', {testFile: new AddContentOverlay('main() {')}); +- await _resultsAvailable.future; +- // Verify that the syntax error was detected. +- { +- List errors = filesErrors[testFile]; +- expect(errors, hasLength(1)); +- } +- // Remove testFile from filesErrors so that we'll notice when the file is +- // re-analyzed. +- filesErrors.remove(testFile); +- // Reanalyze. +- _resultsAvailable = new Completer(); +- server.reanalyze(null); +- await _resultsAvailable.future; +- // The file should have been reanalyzed. +- expect(filesErrors, contains(testFile)); +- // Verify that the syntax error is present (this indicates that the +- // content introduced by the call to updateContent is still in effect). +- { +- List errors = filesErrors[testFile]; +- expect(errors, hasLength(1)); +- } +- } +-} +diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart +deleted file mode 100644 +index 1de25bf77ee..00000000000 +--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart ++++ /dev/null +@@ -1,131 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetPriorityFilesTest); +- }); +-} +- +-@reflectiveTest +-class SetPriorityFilesTest extends AbstractAnalysisTest { +- @override +- void setUp() { +- super.setUp(); +- server.handlers = [ +- new AnalysisDomainHandler(server), +- ]; +- createProject(); +- } +- +- test_fileDoesNotExist() async { +- String file = '$projectPath/doesNotExist.dart'; +- Response response = await _setPriorityFile(file); +- expect(response, isResponseSuccess('0')); +- } +- +- test_fileInAnalysisRoot() async { +- addTestFile(''); +- // set priority files +- Response response = await _setPriorityFile(testFile); +- expect(response, isResponseSuccess('0')); +- // verify +- _verifyPriorityFiles(testFile); +- } +- +- test_fileInSdk() async { +- addTestFile(''); +- // set priority files +- String filePath = '/lib/convert/convert.dart'; +- Response response = await _setPriorityFile(filePath); +- expect(response, isResponseSuccess('0')); +- // verify +- _verifyPriorityFiles(filePath); +- } +- +- test_fileNotInAnalysisRoot() async { +- String path = '/other/file.dart'; +- addFile(path, ''); +- await _setPriorityFile(path); +- _verifyPriorityFiles(path); +- } +- +- test_ignoredInAnalysisOptions() async { +- String sampleFile = '$projectPath/samples/sample.dart'; +- addFile('$projectPath/.analysis_options', r''' +-analyzer: +- exclude: +- - 'samples/**' +-'''); +- addFile(sampleFile, ''); +- // attempt to set priority file +- await _setPriorityFile(sampleFile); +- _verifyPriorityFiles(sampleFile); +- } +- +- test_ignoredInAnalysisOptions_inChildContext() async { +- addFile('$projectPath/.packages', ''); +- addFile('$projectPath/child/.packages', ''); +- String sampleFile = '$projectPath/child/samples/sample.dart'; +- addFile('$projectPath/child/.analysis_options', r''' +-analyzer: +- exclude: +- - 'samples/**' +-'''); +- addFile(sampleFile, ''); +- // attempt to set priority file +- await _setPriorityFile(sampleFile); +- _verifyPriorityFiles(sampleFile); +- } +- +- test_ignoredInAnalysisOptions_inRootContext() async { +- addFile('$projectPath/.packages', ''); +- addFile('$projectPath/child/.packages', ''); +- String sampleFile = '$projectPath/child/samples/sample.dart'; +- addFile('$projectPath/.analysis_options', r''' +-analyzer: +- exclude: +- - 'child/samples/**' +-'''); +- addFile(sampleFile, ''); +- // attempt to set priority file +- await _setPriorityFile(sampleFile); +- _verifyPriorityFiles(sampleFile); +- } +- +- test_sentToPlugins() async { +- addTestFile(''); +- // set priority files +- Response response = await _setPriorityFile(testFile); +- expect(response, isResponseSuccess('0')); +- // verify +- plugin.AnalysisSetPriorityFilesParams params = +- pluginManager.analysisSetPriorityFilesParams; +- expect(params, isNotNull); +- expect(params.files, [testFile]); +- } +- +- _setPriorityFile(String file) async { +- Request request = +- new AnalysisSetPriorityFilesParams([file]).toRequest('0'); +- return await serverChannel.sendRequest(request); +- } +- +- void _verifyPriorityFiles(String path) { +- AnalysisDriver driver = server.getAnalysisDriver(path); +- List prioritySources = driver.priorityFiles; +- expect(prioritySources, [path]); +- } +-} +diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart +deleted file mode 100644 +index 76e1f5b6061..00000000000 +--- a/pkg/analysis_server/test/analysis/test_all.dart ++++ /dev/null +@@ -1,51 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'get_errors_test.dart' as get_errors_test; +-import 'get_hover_test.dart' as get_hover_test; +-import 'get_navigation_test.dart' as get_navigation_test; +-import 'notification_analysis_options_test.dart' +- as notification_analysis_options_test; +-import 'notification_analyzedFiles_test.dart' +- as notification_analyzedFiles_test; +-import 'notification_closingLabels_test.dart' +- as notification_closingLabels_test; +-import 'notification_errors_test.dart' as notification_errors_test; +-import 'notification_highlights_test.dart' as notification_highlights_test; +-import 'notification_highlights_test2.dart' as notification_highlights_test2; +-import 'notification_implemented_test.dart' as notification_implemented_test; +-import 'notification_navigation_test.dart' as notification_navigation_test; +-import 'notification_occurrences_test.dart' as notification_occurrences_test; +-import 'notification_outline_test.dart' as notification_outline_test; +-import 'notification_overrides_test.dart' as notification_overrides_test; +-import 'reanalyze_test.dart' as reanalyze_test; +-import 'set_priority_files_test.dart' as set_priority_files_test; +-import 'update_content_test.dart' as update_content_test; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- defineReflectiveSuite(() { +- get_errors_test.main(); +- get_hover_test.main(); +- get_navigation_test.main(); +- notification_analysis_options_test.main(); +- notification_analyzedFiles_test.main(); +- notification_closingLabels_test.main(); +- notification_errors_test.main(); +- notification_highlights_test.main(); +- notification_highlights_test2.main(); +- notification_implemented_test.main(); +- notification_navigation_test.main(); +- notification_occurrences_test.main(); +- notification_outline_test.main(); +- notification_overrides_test.main(); +- reanalyze_test.main(); +- set_priority_files_test.main(); +- update_content_test.main(); +- }, name: 'analysis'); +-} +diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart +deleted file mode 100644 +index f2733f8e1e1..00000000000 +--- a/pkg/analysis_server/test/analysis/update_content_test.dart ++++ /dev/null +@@ -1,266 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(UpdateContentTest); +- }); +-} +- +-@reflectiveTest +-class UpdateContentTest extends AbstractAnalysisTest { +- Map> filesErrors = {}; +- int serverErrorCount = 0; +- int navigationCount = 0; +- +- @override +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { +- var decoded = new AnalysisErrorsParams.fromNotification(notification); +- String _format(AnalysisError e) => +- "${e.location.startLine}: ${e.message}"; +- filesErrors[decoded.file] = decoded.errors.map(_format).toList(); +- } +- if (notification.event == ANALYSIS_NOTIFICATION_NAVIGATION) { +- navigationCount++; +- } +- if (notification.event == SERVER_NOTIFICATION_ERROR) { +- serverErrorCount++; +- } +- } +- +- test_illegal_ChangeContentOverlay() { +- // It should be illegal to send a ChangeContentOverlay for a file that +- // doesn't have an overlay yet. +- createProject(); +- addTestFile('library foo;'); +- String id = 'myId'; +- try { +- server.updateContent(id, { +- testFile: new ChangeContentOverlay([new SourceEdit(8, 3, 'bar')]) +- }); +- fail('Expected an exception to be thrown'); +- } on RequestFailure catch (e) { +- expect(e.response.id, id); +- expect(e.response.error.code, RequestErrorCode.INVALID_OVERLAY_CHANGE); +- } +- } +- +- test_multiple_contexts() async { +- String fooPath = '/project1/foo.dart'; +- resourceProvider.newFile(fooPath, ''' +-library foo; +-import '../project2/baz.dart'; +-main() { f(); }'''); +- String barPath = '/project2/bar.dart'; +- resourceProvider.newFile(barPath, ''' +-library bar; +-import 'baz.dart'; +-main() { f(); }'''); +- String bazPath = '/project2/baz.dart'; +- resourceProvider.newFile(bazPath, ''' +-library baz; +-f(int i) {} +-'''); +- Request request = +- new AnalysisSetAnalysisRootsParams(['/project1', '/project2'], []) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- { +- await server.onAnalysisComplete; +- // Files foo.dart and bar.dart should both have errors, since they both +- // call f() with the wrong number of arguments. +- expect(filesErrors[fooPath], hasLength(1)); +- expect(filesErrors[barPath], hasLength(1)); +- // Overlay the content of baz.dart to eliminate the errors. +- server.updateContent('1', { +- bazPath: new AddContentOverlay(''' +-library baz; +-f() {} +-''') +- }); +- } +- { +- await server.onAnalysisComplete; +- // The overlay should have been propagated to both contexts, causing both +- // foo.dart and bar.dart to be reanalyzed and found to be free of errors. +- expect(filesErrors[fooPath], isEmpty); +- expect(filesErrors[barPath], isEmpty); +- } +- } +- +- @failingTest +- test_overlay_addPreviouslyImported() async { +- // The list of errors doesn't include errors for '/project/target.dart'. +- Folder project = resourceProvider.newFolder('/project'); +- handleSuccessfulRequest( +- new AnalysisSetAnalysisRootsParams([project.path], []).toRequest('0')); +- +- server.updateContent('1', +- {'/project/main.dart': new AddContentOverlay('import "target.dart";')}); +- await server.onAnalysisComplete; +- expect(filesErrors, { +- '/project/main.dart': ["1: Target of URI doesn't exist: 'target.dart'."], +- '/project/target.dart': [] +- }); +- +- server.updateContent('1', +- {'/project/target.dart': new AddContentOverlay('import "none.dart";')}); +- await server.onAnalysisComplete; +- expect(filesErrors, { +- '/project/main.dart': ["1: Unused import."], +- '/project/target.dart': ["1: Target of URI doesn't exist: 'none.dart'."], +- '/project/none.dart': [] +- }); +- } +- +- test_overlayOnly() async { +- String filePath = '/User/project1/test.dart'; +- Folder folder1 = resourceProvider.newFolder('/User/project1'); +- Folder folder2 = resourceProvider.newFolder('/User/project2'); +- Request request = +- new AnalysisSetAnalysisRootsParams([folder1.path, folder2.path], []) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- // exactly 2 contexts +- expect(server.driverMap, hasLength(2)); +- AnalysisDriver driver1 = server.driverMap[folder1]; +- AnalysisDriver driver2 = server.driverMap[folder2]; +- // no sources +- expect(_getUserSources(driver1), isEmpty); +- expect(_getUserSources(driver2), isEmpty); +- // add an overlay - new Source in context1 +- server.updateContent('1', {filePath: new AddContentOverlay('')}); +- { +- List paths = _getUserSources(driver1); +- expect(paths, hasLength(1)); +- expect(paths[0], filePath); +- } +- expect(_getUserSources(driver2), isEmpty); +- // remove the overlay - no sources +- server.updateContent('2', {filePath: new RemoveContentOverlay()}); +- // The file isn't removed from the list of added sources. +-// expect(_getUserSources(driver1), isEmpty); +- expect(_getUserSources(driver2), isEmpty); +- } +- +- @failingTest +- test_sendNoticesAfterNopChange() async { +- // The errors are empty on the last line. +- createProject(); +- addTestFile(''); +- await server.onAnalysisComplete; +- // add an overlay +- server.updateContent( +- '1', {testFile: new AddContentOverlay('main() {} main() {}')}); +- await server.onAnalysisComplete; +- // clear errors and make a no-op change +- filesErrors.clear(); +- server.updateContent('2', { +- testFile: new ChangeContentOverlay([new SourceEdit(0, 4, 'main')]) +- }); +- await server.onAnalysisComplete; +- // errors should have been resent +- expect(filesErrors, isNotEmpty); +- } +- +- @failingTest +- test_sendNoticesAfterNopChange_flushedUnit() async { +- // The list of errors is empty on the last line. +- createProject(); +- addTestFile(''); +- await server.onAnalysisComplete; +- // add an overlay +- server.updateContent( +- '1', {testFile: new AddContentOverlay('main() {} main() {}')}); +- await server.onAnalysisComplete; +- // clear errors and make a no-op change +- filesErrors.clear(); +- server.updateContent('2', { +- testFile: new ChangeContentOverlay([new SourceEdit(0, 4, 'main')]) +- }); +- await server.onAnalysisComplete; +- // errors should have been resent +- expect(filesErrors, isNotEmpty); +- } +- +- test_sentToPlugins() { +- String filePath = '/project/target.dart'; +- String fileContent = 'import "none.dart";'; +- // +- // Add +- // +- handleSuccessfulRequest(new AnalysisUpdateContentParams( +- {filePath: new AddContentOverlay(fileContent)}) +- .toRequest('0')); +- plugin.AnalysisUpdateContentParams params = +- pluginManager.analysisUpdateContentParams; +- expect(params, isNotNull); +- Map files = params.files; +- expect(files, hasLength(1)); +- Object overlay = files[filePath]; +- expect(overlay, new isInstanceOf()); +- plugin.AddContentOverlay addOverlay = overlay; +- expect(addOverlay.content, fileContent); +- // +- // Change +- // +- pluginManager.analysisUpdateContentParams = null; +- handleSuccessfulRequest(new AnalysisUpdateContentParams({ +- filePath: new ChangeContentOverlay( +- [new SourceEdit(8, 1, "'"), new SourceEdit(18, 1, "'")]) +- }).toRequest('1')); +- params = pluginManager.analysisUpdateContentParams; +- expect(params, isNotNull); +- files = params.files; +- expect(files, hasLength(1)); +- overlay = files[filePath]; +- expect(overlay, new isInstanceOf()); +- plugin.ChangeContentOverlay changeOverlay = overlay; +- expect(changeOverlay.edits, hasLength(2)); +- // +- // Remove +- // +- pluginManager.analysisUpdateContentParams = null; +- handleSuccessfulRequest(new AnalysisUpdateContentParams( +- {filePath: new RemoveContentOverlay()}) +- .toRequest('2')); +- params = pluginManager.analysisUpdateContentParams; +- expect(params, isNotNull); +- files = params.files; +- expect(files, hasLength(1)); +- overlay = files[filePath]; +- expect(overlay, new isInstanceOf()); +- } +- +-// CompilationUnit _getTestUnit() { +-// ContextSourcePair pair = server.getContextSourcePair(testFile); +-// AnalysisContext context = pair.context; +-// Source source = pair.source; +-// return context.getResolvedCompilationUnit2(source, source); +-// } +- +- List _getUserSources(AnalysisDriver driver) { +- List sources = []; +- driver.addedFiles.forEach((path) { +- if (path.startsWith('/User/')) { +- sources.add(path); +- } +- }); +- return sources; +- } +-} +diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart +deleted file mode 100644 +index 2546cd894e3..00000000000 +--- a/pkg/analysis_server/test/analysis_abstract.dart ++++ /dev/null +@@ -1,367 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart' +- hide AnalysisOptions; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analyzer/context/context_root.dart' as analyzer; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin; +-import 'package:plugin/manager.dart'; +-import 'package:test/test.dart'; +-import 'package:watcher/watcher.dart'; +- +-import 'mock_sdk.dart'; +-import 'mocks.dart'; +- +-int findIdentifierLength(String search) { +- int length = 0; +- while (length < search.length) { +- int c = search.codeUnitAt(length); +- if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) || +- c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) || +- c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0) || +- c == '_'.codeUnitAt(0))) { +- break; +- } +- length++; +- } +- return length; +-} +- +-/** +- * An abstract base for all 'analysis' domain tests. +- */ +-class AbstractAnalysisTest { +- bool generateSummaryFiles = false; +- MockServerChannel serverChannel; +- MemoryResourceProvider resourceProvider; +- MockPackageMapProvider packageMapProvider; +- TestPluginManager pluginManager; +- AnalysisServer server; +- RequestHandler handler; +- +- final List serverErrors = []; +- final List generalServices = +- []; +- final Map> analysisSubscriptions = {}; +- +- String projectPath; +- String testFolder; +- String testFile; +- String testCode; +- +- AbstractAnalysisTest(); +- +- AnalysisDomainHandler get analysisHandler => server.handlers +- .singleWhere((handler) => handler is AnalysisDomainHandler); +- +- AnalysisOptions get analysisOptions => testDiver.analysisOptions; +- +- AnalysisDriver get testDiver => server.getAnalysisDriver(testFile); +- +- void addAnalysisSubscription(AnalysisService service, String file) { +- // add file to subscription +- var files = analysisSubscriptions[service]; +- if (files == null) { +- files = []; +- analysisSubscriptions[service] = files; +- } +- files.add(file); +- // set subscriptions +- Request request = new AnalysisSetSubscriptionsParams(analysisSubscriptions) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- String addFile(String path, String content) { +- path = resourceProvider.convertPath(path); +- resourceProvider.newFile(path, content); +- return path; +- } +- +- void addGeneralAnalysisSubscription(GeneralAnalysisService service) { +- generalServices.add(service); +- Request request = new AnalysisSetGeneralSubscriptionsParams(generalServices) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- String addTestFile(String content) { +- addFile(testFile, content); +- this.testCode = content; +- return testFile; +- } +- +- AnalysisServer createAnalysisServer() { +- // +- // Process plugins +- // +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- // +- // Create an SDK in the mock file system. +- // +- new MockSdk( +- generateSummaryFiles: generateSummaryFiles, +- resourceProvider: resourceProvider); +- // +- // Create server +- // +- AnalysisServerOptions options = new AnalysisServerOptions(); +- return new AnalysisServer( +- serverChannel, +- resourceProvider, +- packageMapProvider, +- options, +- new DartSdkManager(resourceProvider.convertPath('/'), true), +- InstrumentationService.NULL_SERVICE); +- } +- +- /** +- * Creates a project `/project`. +- */ +- void createProject({Map packageRoots}) { +- resourceProvider.newFolder(projectPath); +- Request request = new AnalysisSetAnalysisRootsParams([projectPath], [], +- packageRoots: packageRoots) +- .toRequest('0'); +- handleSuccessfulRequest(request, handler: analysisHandler); +- } +- +- /** +- * Returns the offset of [search] in [testCode]. +- * Fails if not found. +- */ +- int findFileOffset(String path, String search) { +- File file = resourceProvider.getResource(path) as File; +- String code = file.createSource().contents.data; +- int offset = code.indexOf(search); +- expect(offset, isNot(-1), reason: '"$search" in\n$code'); +- return offset; +- } +- +- /** +- * Returns the offset of [search] in [testCode]. +- * Fails if not found. +- */ +- int findOffset(String search) { +- int offset = testCode.indexOf(search); +- expect(offset, isNot(-1)); +- return offset; +- } +- +- /** +- * Validates that the given [request] is handled successfully. +- */ +- Response handleSuccessfulRequest(Request request, {RequestHandler handler}) { +- handler ??= this.handler; +- Response response = handler.handleRequest(request); +- expect(response, isResponseSuccess(request.id)); +- return response; +- } +- +- String modifyTestFile(String content) { +- String path = resourceProvider.convertPath(testFile); +- resourceProvider.updateFile(path, content); +- this.testCode = content; +- return testFile; +- } +- +- void processNotification(Notification notification) { +- if (notification.event == SERVER_NOTIFICATION_ERROR) { +- var params = new ServerErrorParams.fromNotification(notification); +- serverErrors.add(params); +- } +- } +- +- void removeGeneralAnalysisSubscription(GeneralAnalysisService service) { +- generalServices.remove(service); +- Request request = new AnalysisSetGeneralSubscriptionsParams(generalServices) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- void setPriorityFiles(List files) { +- var request = new AnalysisSetPriorityFilesParams(files).toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- void setUp() { +- serverChannel = new MockServerChannel(); +- resourceProvider = new MemoryResourceProvider(); +- projectPath = resourceProvider.convertPath('/project'); +- testFolder = resourceProvider.convertPath('/project/bin'); +- testFile = resourceProvider.convertPath('/project/bin/test.dart'); +- packageMapProvider = new MockPackageMapProvider(); +- pluginManager = new TestPluginManager(); +- server = createAnalysisServer(); +- server.pluginManager = pluginManager; +- handler = analysisHandler; +- // listen for notifications +- Stream notificationStream = +- serverChannel.notificationController.stream; +- notificationStream.listen((Notification notification) { +- processNotification(notification); +- }); +- } +- +- void tearDown() { +- server.done(); +- handler = null; +- server = null; +- resourceProvider = null; +- serverChannel = null; +- } +- +- /** +- * Returns a [Future] that completes when the server's analysis is complete. +- */ +- Future waitForTasksFinished() { +- return server.onAnalysisComplete; +- } +- +- /** +- * Completes with a successful [Response] for the given [request]. +- * Otherwise fails. +- */ +- Future waitResponse(Request request) async { +- return serverChannel.sendRequest(request); +- } +-} +- +-/** +- * A plugin manager that simulates broadcasting requests to plugins by +- * hard-coding the responses. +- */ +-class TestPluginManager implements PluginManager { +- plugin.AnalysisSetPriorityFilesParams analysisSetPriorityFilesParams; +- plugin.AnalysisSetSubscriptionsParams analysisSetSubscriptionsParams; +- plugin.AnalysisUpdateContentParams analysisUpdateContentParams; +- plugin.RequestParams broadcastedRequest; +- Map> broadcastResults; +- +- @override +- String get byteStorePath { +- fail('Unexpected invocation of byteStorePath'); +- return null; +- } +- +- @override +- InstrumentationService get instrumentationService { +- fail('Unexpected invocation of instrumentationService'); +- return null; +- } +- +- @override +- NotificationManager get notificationManager { +- fail('Unexpected invocation of notificationManager'); +- return null; +- } +- +- @override +- List get plugins { +- fail('Unexpected invocation of plugins'); +- return null; +- } +- +- @override +- ResourceProvider get resourceProvider { +- fail('Unexpected invocation of resourceProvider'); +- return null; +- } +- +- @override +- String get sdkPath { +- fail('Unexpected invocation of sdkPath'); +- return null; +- } +- +- @override +- Future addPluginToContextRoot( +- analyzer.ContextRoot contextRoot, String path) async { +- fail('Unexpected invocation of addPluginToContextRoot'); +- return null; +- } +- +- @override +- Map> broadcastRequest( +- plugin.RequestParams params, +- {analyzer.ContextRoot contextRoot}) { +- broadcastedRequest = params; +- return broadcastResults ?? >{}; +- } +- +- @override +- Future>> broadcastWatchEvent( +- WatchEvent watchEvent) async { +- return >[]; +- } +- +- @override +- List pathsFor(String pluginPath) { +- fail('Unexpected invocation of pathsFor'); +- return null; +- } +- +- @override +- List pluginsForContextRoot(analyzer.ContextRoot contextRoot) { +- fail('Unexpected invocation of pluginsForContextRoot'); +- return null; +- } +- +- @override +- void recordPluginFailure(String hostPackageName, String message) { +- fail('Unexpected invocation of recordPluginFailure'); +- } +- +- @override +- void removedContextRoot(analyzer.ContextRoot contextRoot) { +- fail('Unexpected invocation of removedContextRoot'); +- } +- +- @override +- Future restartPlugins() async { +- // Nothing to restart. +- return null; +- } +- +- @override +- void setAnalysisSetPriorityFilesParams( +- plugin.AnalysisSetPriorityFilesParams params) { +- analysisSetPriorityFilesParams = params; +- } +- +- @override +- void setAnalysisSetSubscriptionsParams( +- plugin.AnalysisSetSubscriptionsParams params) { +- analysisSetSubscriptionsParams = params; +- } +- +- @override +- void setAnalysisUpdateContentParams( +- plugin.AnalysisUpdateContentParams params) { +- analysisUpdateContentParams = params; +- } +- +- @override +- Future> stopAll() async { +- fail('Unexpected invocation of stopAll'); +- return null; +- } +-} +diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart +deleted file mode 100644 +index 31c8a50253e..00000000000 +--- a/pkg/analysis_server/test/analysis_server_test.dart ++++ /dev/null +@@ -1,210 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/domain_server.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:plugin/manager.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'mock_sdk.dart'; +-import 'mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisServerTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisServerTest { +- MockServerChannel channel; +- AnalysisServer server; +- MemoryResourceProvider resourceProvider; +- MockPackageMapProvider packageMapProvider; +- +- /** +- * Test that having multiple analysis contexts analyze the same file doesn't +- * cause that file to receive duplicate notifications when it's modified. +- */ +- Future do_not_test_no_duplicate_notifications() async { +- // Subscribe to STATUS so we'll know when analysis is done. +- server.serverServices = [ServerService.STATUS].toSet(); +- resourceProvider.newFolder('/foo'); +- resourceProvider.newFolder('/bar'); +- resourceProvider.newFile('/foo/foo.dart', 'import "../bar/bar.dart";'); +- File bar = resourceProvider.newFile('/bar/bar.dart', 'library bar;'); +- server.setAnalysisRoots('0', ['/foo', '/bar'], [], {}); +- Map> subscriptions = +- >{}; +- for (AnalysisService service in AnalysisService.VALUES) { +- subscriptions[service] = [bar.path].toSet(); +- } +- // The following line causes the isolate to continue running even though the +- // test completes. +- server.setAnalysisSubscriptions(subscriptions); +- await server.onAnalysisComplete; +- expect(server.statusAnalyzing, isFalse); +- channel.notificationsReceived.clear(); +- server.updateContent( +- '0', {bar.path: new AddContentOverlay('library bar; void f() {}')}); +- await server.onAnalysisComplete; +- expect(server.statusAnalyzing, isFalse); +- expect(channel.notificationsReceived, isNotEmpty); +- Set notificationTypesReceived = new Set(); +- for (Notification notification in channel.notificationsReceived) { +- String notificationType = notification.event; +- switch (notificationType) { +- case 'server.status': +- case 'analysis.errors': +- // It's normal for these notifications to be sent multiple times. +- break; +- case 'analysis.outline': +- // It's normal for this notification to be sent twice. +- // TODO(paulberry): why? +- break; +- default: +- if (!notificationTypesReceived.add(notificationType)) { +- fail('Notification type $notificationType received more than once'); +- } +- break; +- } +- } +- } +- +- void processRequiredPlugins() { +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- } +- +- void setUp() { +- processRequiredPlugins(); +- channel = new MockServerChannel(); +- resourceProvider = new MemoryResourceProvider(); +- // Create an SDK in the mock file system. +- new MockSdk(resourceProvider: resourceProvider); +- packageMapProvider = new MockPackageMapProvider(); +- server = new AnalysisServer( +- channel, +- resourceProvider, +- packageMapProvider, +- new AnalysisServerOptions(), +- new DartSdkManager('/', false), +- InstrumentationService.NULL_SERVICE); +- } +- +- Future test_echo() { +- server.handlers = [new EchoHandler()]; +- var request = new Request('my22', 'echo'); +- return channel.sendRequest(request).then((Response response) { +- expect(response.id, equals('my22')); +- expect(response.error, isNull); +- }); +- } +- +- Future test_serverStatusNotifications() { +- server.serverServices.add(ServerService.STATUS); +- resourceProvider.newFolder('/pkg'); +- resourceProvider.newFolder('/pkg/lib'); +- resourceProvider.newFile('/pkg/lib/test.dart', 'class C {}'); +- server.setAnalysisRoots('0', ['/pkg'], [], {}); +- // Pump the event queue to make sure the server has finished any +- // analysis. +- return pumpEventQueue().then((_) { +- List notifications = channel.notificationsReceived; +- expect(notifications, isNotEmpty); +- // expect at least one notification indicating analysis is in progress +- expect(notifications.any((Notification notification) { +- if (notification.event == SERVER_NOTIFICATION_STATUS) { +- var params = new ServerStatusParams.fromNotification(notification); +- if (params.analysis != null) { +- return params.analysis.isAnalyzing; +- } +- } +- return false; +- }), isTrue); +- // the last notification should indicate that analysis is complete +- Notification notification = notifications[notifications.length - 1]; +- var params = new ServerStatusParams.fromNotification(notification); +- expect(params.analysis.isAnalyzing, isFalse); +- }); +- } +- +- test_setAnalysisSubscriptions_fileInIgnoredFolder_newOptions() async { +- String path = '/project/samples/sample.dart'; +- resourceProvider.newFile(path, ''); +- resourceProvider.newFile('/project/analysis_options.yaml', r''' +-analyzer: +- exclude: +- - 'samples/**' +-'''); +- server.setAnalysisRoots('0', ['/project'], [], {}); +- server.setAnalysisSubscriptions(>{ +- AnalysisService.NAVIGATION: new Set.from([path]) +- }); +- // the file is excluded, so no navigation notification +- await server.onAnalysisComplete; +- expect(channel.notificationsReceived.any((notification) { +- return notification.event == ANALYSIS_NOTIFICATION_NAVIGATION; +- }), isFalse); +- } +- +- test_setAnalysisSubscriptions_fileInIgnoredFolder_oldOptions() async { +- String path = '/project/samples/sample.dart'; +- resourceProvider.newFile(path, ''); +- resourceProvider.newFile('/project/.analysis_options', r''' +-analyzer: +- exclude: +- - 'samples/**' +-'''); +- server.setAnalysisRoots('0', ['/project'], [], {}); +- server.setAnalysisSubscriptions(>{ +- AnalysisService.NAVIGATION: new Set.from([path]) +- }); +- // the file is excluded, so no navigation notification +- await server.onAnalysisComplete; +- expect(channel.notificationsReceived.any((notification) { +- return notification.event == ANALYSIS_NOTIFICATION_NAVIGATION; +- }), isFalse); +- } +- +- Future test_shutdown() { +- server.handlers = [new ServerDomainHandler(server)]; +- var request = new Request('my28', SERVER_REQUEST_SHUTDOWN); +- return channel.sendRequest(request).then((Response response) { +- expect(response.id, equals('my28')); +- expect(response.error, isNull); +- }); +- } +- +- Future test_unknownRequest() { +- server.handlers = [new EchoHandler()]; +- var request = new Request('my22', 'randomRequest'); +- return channel.sendRequest(request).then((Response response) { +- expect(response.id, equals('my22')); +- expect(response.error, isNotNull); +- }); +- } +-} +- +-class EchoHandler implements RequestHandler { +- @override +- Response handleRequest(Request request) { +- if (request.method == 'echo') { +- return new Response(request.id, result: {'echo': true}); +- } +- return null; +- } +-} +diff --git a/pkg/analysis_server/test/benchmarks_test.dart b/pkg/analysis_server/test/benchmarks_test.dart +deleted file mode 100644 +index 4cd4a46426a..00000000000 +--- a/pkg/analysis_server/test/benchmarks_test.dart ++++ /dev/null +@@ -1,76 +0,0 @@ +-// Copyright (c) 2014, 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.=> defineTests(); +- +-/// This tests the benchmarks in benchmark/benchmark.test, and ensures that our +-/// benchmarks can run. +- +-import 'dart:convert'; +-import 'dart:io'; +- +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +- +-void main() => defineTests(); +- +-void defineTests() { +- group('benchmarks', () { +- final List benchmarks = _listBenchmarks(); +- +- test('can list', () { +- expect(benchmarks, isNotEmpty); +- }); +- +- for (String benchmarkId in benchmarks) { +- test(benchmarkId, () { +- ProcessResult r = Process.runSync( +- Platform.resolvedExecutable, +- [ +- path.join('benchmark', 'benchmarks.dart'), +- 'run', +- '--repeat=1', +- '--quick', +- benchmarkId +- ], +- workingDirectory: _serverSourcePath, +- ); +- expect(r.exitCode, 0, +- reason: 'exit: ${r.exitCode}\n${r.stdout}\n${r.stderr}'); +- }); +- +- test('$benchmarkId-preview-dart-2', () { +- ProcessResult r = Process.runSync( +- Platform.resolvedExecutable, +- [ +- path.join('benchmark', 'benchmarks.dart'), +- 'run', +- '--repeat=1', +- '--quick', +- '--preview-dart-2', +- benchmarkId +- ], +- workingDirectory: _serverSourcePath, +- ); +- expect(r.exitCode, 0, +- reason: 'exit: ${r.exitCode}\n${r.stdout}\n${r.stderr}'); +- }); +- } +- }); +-} +- +-List _listBenchmarks() { +- ProcessResult result = Process.runSync( +- Platform.resolvedExecutable, +- [path.join('benchmark', 'benchmarks.dart'), 'list', '--machine'], +- workingDirectory: _serverSourcePath, +- ); +- Map m = JSON.decode(result.stdout); +- List benchmarks = m['benchmarks']; +- return benchmarks.map((b) => b['id']).toList(); +-} +- +-String get _serverSourcePath { +- String script = Platform.script.toFilePath(windows: Platform.isWindows); +- String pkgPath = path.normalize(path.join(path.dirname(script), '..', '..')); +- return path.join(pkgPath, 'analysis_server'); +-} +diff --git a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart +deleted file mode 100644 +index 4395c7ab08d..00000000000 +--- a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart ++++ /dev/null +@@ -1,272 +0,0 @@ +-// Copyright (c) 2014, 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:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/src/channel/byte_stream_channel.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:mockito/mockito.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ByteStreamClientChannelTest); +- defineReflectiveTests(ByteStreamServerChannelTest); +- }); +-} +- +-@reflectiveTest +-class ByteStreamClientChannelTest { +- ByteStreamClientChannel channel; +- +- /** +- * Sink that may be used to deliver data to the channel, as though it's +- * coming from the server. +- */ +- IOSink inputSink; +- +- /** +- * Sink through which the channel delivers data to the server. +- */ +- IOSink outputSink; +- +- /** +- * Stream of lines sent back to the client by the channel. +- */ +- Stream outputLineStream; +- +- void setUp() { +- var inputStream = new StreamController>(); +- inputSink = new IOSink(inputStream); +- var outputStream = new StreamController>(); +- outputLineStream = outputStream.stream +- .transform((new Utf8Codec()).decoder) +- .transform(new LineSplitter()); +- outputSink = new IOSink(outputStream); +- channel = new ByteStreamClientChannel(inputStream.stream, outputSink); +- } +- +- test_close() { +- bool doneCalled = false; +- bool closeCalled = false; +- // add listener so that outputSink will trigger done/close futures +- outputLineStream.listen((_) {/* no-op */}); +- outputSink.done.then((_) { +- doneCalled = true; +- }); +- channel.close().then((_) { +- closeCalled = true; +- }); +- return pumpEventQueue().then((_) { +- expect(doneCalled, isTrue); +- expect(closeCalled, isTrue); +- }); +- } +- +- test_listen_notification() { +- List notifications = []; +- channel.notificationStream.forEach((n) => notifications.add(n)); +- inputSink.writeln('{"event":"server.connected"}'); +- return pumpEventQueue().then((_) { +- expect(notifications.length, equals(1)); +- expect(notifications[0].event, equals('server.connected')); +- }); +- } +- +- test_listen_response() { +- List responses = []; +- channel.responseStream.forEach((n) => responses.add(n)); +- inputSink.writeln('{"id":"72"}'); +- return pumpEventQueue().then((_) { +- expect(responses.length, equals(1)); +- expect(responses[0].id, equals('72')); +- }); +- } +- +- test_sendRequest() { +- int assertCount = 0; +- Request request = new Request('72', 'foo.bar'); +- outputLineStream.first.then((line) => JSON.decode(line)).then((json) { +- expect(json[Request.ID], equals('72')); +- expect(json[Request.METHOD], equals('foo.bar')); +- inputSink.writeln('{"id":"73"}'); +- inputSink.writeln('{"id":"72"}'); +- assertCount++; +- }); +- channel.sendRequest(request).then((Response response) { +- expect(response.id, equals('72')); +- assertCount++; +- }); +- return pumpEventQueue().then((_) => expect(assertCount, equals(2))); +- } +-} +- +-@reflectiveTest +-class ByteStreamServerChannelTest { +- ByteStreamServerChannel channel; +- +- /** +- * Sink that may be used to deliver data to the channel, as though it's +- * coming from the client. +- */ +- IOSink inputSink; +- +- /** +- * Stream of lines sent back to the client by the channel. +- */ +- Stream outputLineStream; +- +- /** +- * Stream of requests received from the channel via [listen()]. +- */ +- Stream requestStream; +- +- /** +- * Stream of errors received from the channel via [listen()]. +- */ +- Stream errorStream; +- +- /** +- * Future which is completed when then [listen()] reports [onDone]. +- */ +- Future doneFuture; +- +- void setUp() { +- StreamController> inputStream = new StreamController>(); +- inputSink = new IOSink(inputStream); +- StreamController> outputStream = +- new StreamController>(); +- outputLineStream = outputStream.stream +- .transform((new Utf8Codec()).decoder) +- .transform(new LineSplitter()); +- IOSink outputSink = new IOSink(outputStream); +- channel = new ByteStreamServerChannel( +- inputStream.stream, outputSink, InstrumentationService.NULL_SERVICE); +- StreamController requestStreamController = +- new StreamController(); +- requestStream = requestStreamController.stream; +- StreamController errorStreamController = new StreamController(); +- errorStream = errorStreamController.stream; +- Completer doneCompleter = new Completer(); +- doneFuture = doneCompleter.future; +- channel.listen((Request request) { +- requestStreamController.add(request); +- }, onError: (error) { +- errorStreamController.add(error); +- }, onDone: () { +- doneCompleter.complete(); +- }); +- } +- +- test_closed() { +- return inputSink +- .close() +- .then((_) => channel.closed.timeout(new Duration(seconds: 1))); +- } +- +- test_listen_invalidJson() { +- inputSink.writeln('{"id":'); +- return inputSink +- .flush() +- .then((_) => outputLineStream.first.timeout(new Duration(seconds: 1))) +- .then((String response) { +- var jsonResponse = new JsonCodec().decode(response); +- expect(jsonResponse, isMap); +- expect(jsonResponse, contains('error')); +- expect(jsonResponse['error'], isNotNull); +- }); +- } +- +- test_listen_invalidRequest() { +- inputSink.writeln('{"id":"0"}'); +- return inputSink +- .flush() +- .then((_) => outputLineStream.first.timeout(new Duration(seconds: 1))) +- .then((String response) { +- var jsonResponse = new JsonCodec().decode(response); +- expect(jsonResponse, isMap); +- expect(jsonResponse, contains('error')); +- expect(jsonResponse['error'], isNotNull); +- }); +- } +- +- test_listen_streamDone() { +- return inputSink +- .close() +- .then((_) => doneFuture.timeout(new Duration(seconds: 1))); +- } +- +- test_listen_streamError() { +- var error = new Error(); +- inputSink.addError(error); +- return inputSink +- .flush() +- .then((_) => errorStream.first.timeout(new Duration(seconds: 1))) +- .then((var receivedError) { +- expect(receivedError, same(error)); +- }); +- } +- +- test_listen_wellFormedRequest() { +- inputSink.writeln('{"id":"0","method":"server.version"}'); +- return inputSink +- .flush() +- .then((_) => requestStream.first.timeout(new Duration(seconds: 1))) +- .then((Request request) { +- expect(request.id, equals("0")); +- expect(request.method, equals("server.version")); +- }); +- } +- +- test_sendNotification() { +- channel.sendNotification(new Notification('foo')); +- return outputLineStream.first +- .timeout(new Duration(seconds: 1)) +- .then((String notification) { +- var jsonNotification = new JsonCodec().decode(notification); +- expect(jsonNotification, isMap); +- expect(jsonNotification, contains('event')); +- expect(jsonNotification['event'], equals('foo')); +- }); +- } +- +- test_sendNotification_exceptionInSink() async { +- // This IOSink asynchronously throws an exception on any writeln(). +- var outputSink = new _IOSinkMock(); +- when(outputSink.writeln(any)).thenAnswer((answer) { +- new Timer(new Duration(milliseconds: 10), () { +- throw '42'; +- }); +- }); +- +- var channel = new ByteStreamServerChannel( +- null, outputSink, InstrumentationService.NULL_SERVICE); +- +- // Attempt to send a notification. +- channel.sendNotification(new Notification('foo')); +- +- // An exception was thrown, it did not leak, but the channel was closed. +- await channel.closed; +- } +- +- test_sendResponse() { +- channel.sendResponse(new Response('foo')); +- return outputLineStream.first +- .timeout(new Duration(seconds: 1)) +- .then((String response) { +- var jsonResponse = new JsonCodec().decode(response); +- expect(jsonResponse, isMap); +- expect(jsonResponse, contains('id')); +- expect(jsonResponse['id'], equals('foo')); +- }); +- } +-} +- +-class _IOSinkMock extends Mock implements IOSink {} +diff --git a/pkg/analysis_server/test/channel/test_all.dart b/pkg/analysis_server/test/channel/test_all.dart +deleted file mode 100644 +index ce5e85a3ace..00000000000 +--- a/pkg/analysis_server/test/channel/test_all.dart ++++ /dev/null +@@ -1,16 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test/test.dart'; +- +-import 'byte_stream_channel_test.dart' as byte_stream_channel_test; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- group('computer', () { +- byte_stream_channel_test.main(); +- }); +-} +diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart +deleted file mode 100644 +index e6201b5ce65..00000000000 +--- a/pkg/analysis_server/test/completion_test.dart ++++ /dev/null +@@ -1,2517 +0,0 @@ +-// 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;}}''', +- ["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);}}''', +- ["1+length", "2+x", "3+n"]); +- +- buildTests('testCommentSnippets004', ''' +-class A {!1int x; !2mth() {!3int y = this.!5x!6;}}class B{}''', +- ["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; }}''', +- ["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{}''', +- ["1+bool", "2+bool", "3+int", "4+Arrays"]); +- +- buildTests('testCommentSnippets008', ''' +-class Date{}final num M = Dat!1''', ["1+Date"]); +- +- // space, char, eol are important +- buildTests( +- 'testCommentSnippets009', +- ''' +-class Maps{}class x extends!5 !2M!3 !4implements!6 !1\n{}''', +- [ +- "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{}''', ["1+Map"]); +- +- // space, char, eol are important +- buildTests('testCommentSnippets011', ''' +-class x implements M!1{}''', ["1+Map"]); +- +- // space, char, eol are important +- buildTests('testCommentSnippets012', ''' +-class x implements M!1\n{}''', ["1+Map"]); +- +- buildTests('testCommentSnippets013', ''' +-class x !2{!1}!3''', ["1+num", "2-num", "3+num"]); +- +- // trailing space is important +- buildTests('testCommentSnippets014', ''' +-typedef n!1 ;''', ["1+num"]); +- +- buildTests('testCommentSnippets015', ''' +-class D {f(){} g(){f!1(f!2);}}''', ["1+f", "2+f"]); +- +- buildTests('testCommentSnippets016', ''' +-class F {m() { m(); !1}}''', ["1+m"]); +- +- buildTests('testCommentSnippets017', ''' +-class F {var x = !1false;}''', ["1+true"]); +- +- buildTests('testCommentSnippets018', ''' +-class Map{}class Arrays{}class C{ m(!1){} n(!2 x, q)''', +- ["1+Map", "1-void", "1-null", "2+Arrays", "2-void", "2-null"]); +- +- buildTests('testCommentSnippets019', ''' +-class A{m(){Object x;x.!1/**/clear()''', ["1+toString"]); +- +- buildTests('testCommentSnippets020', ''' +-classMap{}class tst {var newt;void newf(){}test() {var newz;new!1/**/;}}''', +- ["1+newt", "1+newf", "1+newz", "1-Map"]); +- +- buildTests('testCommentSnippets021', ''' +-class Map{}class tst {var newt;void newf(){}test() {var newz;new !1/**/;}}''', +- ["1+Map", "1-newt"]); +- +- buildTests('testCommentSnippets022', ''' +-class Map{}class F{m(){new !1;}}''', ["1+Map"]); +- +- buildTests('testCommentSnippets022a', ''' +-class Map{}class F{m(){new !1''', ["1+Map"]); +- +- buildTests('testCommentSnippets022b', ''' +-class Map{factory Map.qq(){return null;}}class F{m(){new Map.!1qq();}}''', +- ["1+qq"]); +- +- buildTests('testCommentSnippets023', ''' +-class X {X c; X(this.!1c!3) : super() {c.!2}}''', +- ["1+c", "2+c", "3+c"]); +- +- buildTests('testCommentSnippets024', ''' +-class q {m(Map q){var x;m(!1)}n(){var x;n(!2)}}''', ["1+x", "2+x"]); +- +- buildTests('testCommentSnippets025', ''' +-class q {num m() {var q; num x=!1 q!3 + !2/**/;}}''', +- ["1+q", "2+q", "3+q"]); +- +- buildTests('testCommentSnippets026', ''' +-class List{}class a implements !1{}''', ["1+List"]); +- +- buildTests('testCommentSnippets027', ''' +-class String{}class List{}class test {}''', +- ["1+List", "2+String", "2-List"]); +- +- buildTests('testCommentSnippets028', ''' +-class String{}class List{}class DateTime{}typedef T Y(List input);''', +- ["1+DateTime", "1+String"]); +- +- buildTests('testCommentSnippets029', ''' +-interface A default B {}''', +- ["1+DateTime", "2+List"]); +- +- buildTests( +- 'testCommentSnippets030', +- ''' +-class Bar {const Bar(!1T!2 k);T!3 m(T!4 a, T!5 b){}final T!6 f = null;}''', +- ["1+T", "2+T", "3+T", "4+T", "5+T", "6+T"], +- failingTests: '123456'); +- +- buildTests( +- 'testCommentSnippets031', +- ''' +-class Bar {m(x){if (x is !1) return;if (x is!!!2)}}''', +- ["1+Bar", "1+T", "2+T", "2+Bar"], +- failingTests: '12'); +- +- buildTests( +- 'testCommentSnippets032', +- ''' +-class Fit{}class Bar {const !2F!1ara();}''', +- ["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);}}''', +- ["1+add", "1+length"]); +- +- // Type propagation +- buildTests('testCommentSnippets035', ''' +-class List{clear(){}length(){}}t3() {var x=new List(), y=x.!1length();x.!2clear();}''', +- ["1+length", "2+clear"]); +- +- buildTests('testCommentSnippets036', ''' +-class List{}t3() {var x=new List!1}''', ["1+List"]); +- +- buildTests('testCommentSnippets037', ''' +-class List{factory List.from(){}}t3() {var x=new List.!1}''', +- ["1+from"]); +- +- buildTests('testCommentSnippets038', ''' +-f(){int xa; String s = '\$x!1';}''', ["1+xa"]); +- +- buildTests('testCommentSnippets038a', ''' +-int xa; String s = '\$x!1\'''', ["1+xa"]); +- +- buildTests('testCommentSnippets039', ''' +-f(){int xa; String s = '\$!1';}''', ["1+xa"]); +- +- buildTests('testCommentSnippets039a', ''' +-int xa; String s = '\$!1\'''', ["1+xa"]); +- +- buildTests('testCommentSnippets040', ''' +-class List{add(){}}class Map{}class X{m(){List list; list.!1 Map map;}}''', +- ["1+add"]); +- +- buildTests('testCommentSnippets041', ''' +-class List{add(){}length(){}}class X{m(){List list; list.!1 zox();}}''', +- ["1+add"]); +- +- buildTests('testCommentSnippets042', ''' +-class DateTime{static const int WED=3;int get day;}fd(){DateTime d=new DateTime.now();d.!1WED!2;}''', +- ["1+day", "2-WED"]); +- +- buildTests('testCommentSnippets043', ''' +-class L{var k;void.!1}''', ["1-k"]); +- +- buildTests('testCommentSnippets044', ''' +-class List{}class XXX {XXX.fisk();}main() {main(); new !1}}''', +- ["1+List", "1+XXX.fisk"]); +- +- buildTests('testCommentSnippets047', ''' +-f(){int x;int y=!1;}''', ["1+x"]); +- +- buildTests('testCommentSnippets048', ''' +-import 'dart:convert' as json;f() {var x=new js!1}''', ["1+json"]); +- +- buildTests('testCommentSnippets049', ''' +-import 'dart:convert' as json; +-import 'dart:convert' as jxx; +-class JsonDecoderX{} +-f1() {var x=new !2j!1s!3}''', [ +- "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); +-}''', [ +- "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; +- } +-}''', ["1+length", "2-getKeys"]); +- +- // Type propagation. +- buildTests('testCommentSnippets052', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void r() { +- List values = ['a','b','c']; +- for (var v in values) { +- v.!1toUpperCase; +- v.!2getKeys; +- } +-}''', ["1+toUpperCase", "2-getKeys"]); +- +- // Type propagation. +- buildTests('testCommentSnippets053', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void r() { +- var v; +- while (v is String) { +- v.!1toUpperCase; +- v.!2getKeys; +- } +-}''', ["1+toUpperCase", "2-getKeys"]); +- +- buildTests('testCommentSnippets054', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void r() { +- var v; +- for (; v is String; v.!1isEmpty) { +- v.!2toUpperCase; +- v.!3getKeys; +- } +-}''', ["1+isEmpty", "2+toUpperCase", "3-getKeys"]); +- +- buildTests('testCommentSnippets055', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void r() { +- String v; +- if (v is Object) { +- v.!1toUpperCase; +- } +-}''', ["1+toUpperCase"]); +- +- // Type propagation. +- buildTests('testCommentSnippets056', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void f(var v) { +- if (v is!! String) { +- return; +- } +- v.!1toUpperCase; +-}''', ["1+toUpperCase"]); +- +- // Type propagation. +- buildTests('testCommentSnippets057', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void f(var v) { +- if ((v as String).!2length == 0) { +- v.!1toUpperCase; +- } +-}''', ["1+toUpperCase", "2+length"]); +- +- buildTests( +- 'testCommentSnippets058', +- ''' +-typedef vo!2id callback(int k); +-void x(callback q){} +-void r() { +- callback v; +- x(!1); +-}''', +- ["1+v", "2+void"], +- failingTests: '2'); +- +- buildTests('testCommentSnippets059', ''' +-f(){((int x) => x+4).!1call(1);}''', ["1-call"]); +- +- buildTests('testCommentSnippets060', ''' +-class Map{} +-abstract class MM extends Map{factory MM() => new Map();} +-class Z { +- MM x; +- f() { +- x!1 +- } +-}''', ["1+x", "1-x[]"]); +- +- buildTests('testCommentSnippets061', ''' +-class A{m(){!1f(3);!2}}n(){!3f(3);!4}f(x)=>x*3;''', +- ["1+f", "1+n", "2+f", "2+n", "3+f", "3+n", "4+f", "4+n"]); +- +- // Type propagation. +- buildTests('testCommentSnippets063', ''' +-class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}} +-void r(var v) { +- v.!1toUpperCase; +- assert(v is String); +- v.!2toUpperCase; +-}''', ["1-toUpperCase", "2+toUpperCase"]); +- +- 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; +- } +-}''', [ +- "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; +- } +-}''', ["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; +- } +-}''', ["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; +- } +-}''', ["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; +- } +-}''', ["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; +- } +-}''', ["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; +- } +-}''', ["1+b"]); +- +- buildTests('testCommentSnippets072', ''' +-class X { +- int _p; +- set p(int x) => _p = x; +-} +-f() { +- X x = new X(); +- x.!1p = 3; +-}''', ["1+p"]); +- +- buildTests('testCommentSnippets073', ''' +-class X { +- m() { +- JSON.stri!1; +- X f = null; +- } +-} +-class JSON { +- static stringify() {} +-}''', ["1+stringify"]); +- +- buildTests('testCommentSnippets074', ''' +-class X { +- m() { +- _x!1 +- } +- _x1(){} +-}''', ["1+_x1"]); +- +- buildTests('testCommentSnippets075', ''' +-p(x)=>0;var E;f(q)=>!1p(!2E);''', ["1+p", "2+E"]); +- +- buildTests('testCommentSnippets076', ''' +-class Map{}class List{}class int{}main() {var m=new Map>,List>();}''', +- ["1+List", "2+int", "3+int"]); +- +- buildTests('testCommentSnippets076a', ''' +-class Map{}class List{}class int{}main() {var m=new Map>,List>();}''', +- ["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''', [ +- "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 }''', +- ["1+from", "1-clear"]); // static method, instance method +- +- buildTests('testCommentSnippets079', ''' +-class Map{static from()=>null;clear(){}}void main() { Map s; s.!1 }''', +- ["1-from", "1+clear"]); // static method, instance method +- +- buildTests('testCommentSnippets080', ''' +-class RuntimeError{var message;}void main() { RuntimeError.!1 }''', +- ["1-message"]); // field +- +- buildTests( +- 'testCommentSnippets081', +- ''' +-class Foo {this.!1}''', +- ["1-Object"], +- failingTests: '1'); +- +- buildTests('testCommentSnippets082', ''' +- class HttpRequest {} +- class HttpResponse {} +- main() { +- var v = (HttpRequest req, HttpResp!1) +- }''', ["1+HttpResponse"]); +- +- buildTests('testCommentSnippets083', ''' +-main() {(.!1)}''', ["1-toString"]); +- +- buildTests('testCommentSnippets083a', ''' +-main() { .!1 }''', ["1-toString"]); +- +- buildTests('testCommentSnippets083b', ''' +-main() { null.!1 }''', ["1+toString"]); +- +- buildTests('testCommentSnippets085', ''' +-class List{}class Map{}class Z extends List with !1Ma!2p {}''', +- ["1+List", "1+Map", "2+Map", "2-List"]); +- +- buildTests( +- 'testCommentSnippets086', +- ''' +-class Q{f(){xy() {!2};x!1y();}}''', +- ["1+xy", "2+f", "2-xy"], +- failingTests: '2'); +- +- buildTests('testCommentSnippets087', ''' +-class Map{}class Q extends Object with !1Map {}''', +- ["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} +-}''', ["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 +- } +-}''', +- [ +- "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 }}''', ["1+length"]); +- } +- +- void buildCompletionTests() { +- buildTests('testCompletion_alias_field', ''' +-typedef int fnint(int k); fn!1int x;''', ["1+fnint"]); +- +- buildTests( +- 'testCompletion_annotation_argumentList', +- ''' +-class AAA {", +- const AAA({int aaa, int bbb});", +-}", +-", +-@AAA(!1) +-main() { +-}''', +- [ +- "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() { +-}''', +- ["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() { +-}''', +- [ +- "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/, +- "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/ +- ], +- failingTests: '1'); +- +- buildTests('testCompletion_annotation_type_inClass_withoutMember', ''' +-class AAA { +- const AAA(); +-} +- +-class C { +- @A!1 +-}''', ["1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/]); +- +- buildTests('testCompletion_argument_typeName', ''' +-class Enum { +- static Enum FOO = new Enum(); +-} +-f(Enum e) {} +-main() { +- f(En!1); +-}''', ["1+Enum"]); +- +- buildTests('testCompletion_arguments_ignoreEmpty', ''' +-class A { +- test() {} +-} +-main(A a) { +- a.test(!1); +-}''', ["1-test"]); +- +- buildTests('testCompletion_as_asIdentifierPrefix', ''' +-main(p) { +- var asVisible; +- var v = as!1; +-}''', ["1+asVisible"]); +- +- buildTests('testCompletion_as_asPrefixedIdentifierStart', ''' +-class A { +- var asVisible; +-} +- +-main(A p) { +- var v = p.as!1; +-}''', ["1+asVisible"]); +- +- buildTests('testCompletion_as_incompleteStatement', ''' +-class MyClass {} +-main(p) { +- var justSomeVar; +- var v = p as !1 +-}''', ["1+MyClass", "1-justSomeVar"]); +- +- buildTests('testCompletion_cascade', ''' +-class A { +- aaa() {} +-} +- +- +-main(A a) { +- a..!1 aaa(); +-}''', ["1+aaa", "1-main"]); +- +- buildTests('testCompletion_combinator_afterComma', ''' +-import 'dart:math' show cos, !1;''', +- ["1+PI", "1+sin", "1+Random", "1-String"]); +- +- buildTests('testCompletion_combinator_ended', ''' +-import 'dart:math' show !1;"''', +- ["1+PI", "1+sin", "1+Random", "1-String"]); +- +- buildTests('testCompletion_combinator_export', ''' +-export 'dart:math' show !1;"''', +- ["1+PI", "1+sin", "1+Random", "1-String"]); +- +- buildTests('testCompletion_combinator_hide', ''' +-import 'dart:math' hide !1;"''', +- ["1+PI", "1+sin", "1+Random", "1-String"]); +- +- buildTests('testCompletion_combinator_notEnded', ''' +-import 'dart:math' show !1"''', +- ["1+PI", "1+sin", "1+Random", "1-String"]); +- +- buildTests('testCompletion_combinator_usePrefix', ''' +-import 'dart:math' show s!1"''', +- ["1+sin", "1+sqrt", "1-cos", "1-String"]); +- +- buildTests( +- 'testCompletion_constructor_field', +- ''' +-class X { X(this.field); int f!1ield;}''', +- ["1+field"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_constructorArguments_showOnlyCurrent', +- ''' +-class A { +- A.first(int p); +- A.second(double p); +-} +-main() { +- new A.first(!1); +-}''', +- ["1+A.first", "1-A.second"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_constructorArguments_whenPrefixedType', +- ''' +-import 'dart:math' as m; +-main() { +- new m.Random(!1); +-}''', +- ["1+Random:ARGUMENT_LIST"], +- failingTests: '1'); +- +- buildTests('testCompletion_dartDoc_reference_forClass', ''' +-/** +- * [int!1] +- * [method!2] +- */ +-class AAA { +- methodA() {} +-}''', ["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() {} +-}''', ["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() {}''', +- [ +- "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() {}''', +- [ +- "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() {} +-}''', [ +- "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 {}''', [ +- "1+double", +- "1-int", +- "2+int", +- "2+String", +- "3+int", +- "3+String" +- ]); +- +- buildTests('testCompletion_double_inFractionPart', ''' +-main() { +- 1.0!1 +-}''', ["1-abs", "1-main"]); +- +- buildTests('testCompletion_enum', ''' +-enum MyEnum {A, B, C} +-main() { +- MyEnum.!1; +-}''', ["1+values", "1+A", "1+B", "1+C"]); +- +- buildTests('testCompletion_exactPrefix_hasHigherRelevance', ''' +-var STR; +-main(p) { +- var str; +- str!1; +- STR!2; +- Str!3; +-}''', [ +- "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''', [ +- "1+dart:core", +- "1+dart:math", +- "1-dart:_chrome", +- "1-dart:_collection.dev" +- ]); +- +- buildTests( +- 'testCompletion_export_noStringLiteral_noSemicolon', +- ''' +-import !1 +- +-class A {}''', +- ["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++); }}''', +- ["1+int", "2+i", "3+i"]); +- +- buildTests('testCompletion_function', ''' +-class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1) => a.compareTo(b)); }}''', +- ["1+String"]); +- +- buildTests('testCompletion_function_partial', ''' +-class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1)); }}''', +- ["1+String"]); +- +- buildTests( +- 'testCompletion_functionTypeParameter_namedArgument', +- ''' +-typedef FFF(a, b, {x1, x2, y}); +-main(FFF fff) { +- fff(1, 2, !1)!2; +-}''', +- ["1+x1", "2-x2"], +- failingTests: '1'); +- +- buildTests('testCompletion_ifStmt_field1', ''' +-class Foo { int myField = 7; mth() { if (!1) {}}}''', ["1+myField"]); +- +- buildTests('testCompletion_ifStmt_field1a', ''' +-class Foo { int myField = 7; mth() { if (!1) }}''', ["1+myField"]); +- +- buildTests('testCompletion_ifStmt_field2', ''' +-class Foo { int myField = 7; mth() { if (m!1) {}}}''', ["1+myField"]); +- +- buildTests('testCompletion_ifStmt_field2a', ''' +-class Foo { int myField = 7; mth() { if (m!1) }}''', ["1+myField"]); +- +- buildTests('testCompletion_ifStmt_field2b', ''' +-class Foo { myField = 7; mth() { if (m!1) {}}}''', ["1+myField"]); +- +- buildTests('testCompletion_ifStmt_localVar', ''' +-class Foo { mth() { int value = 7; if (v!1) {}}}''', ["1+value"]); +- +- buildTests('testCompletion_ifStmt_localVara', ''' +-class Foo { mth() { value = 7; if (v!1) {}}}''', ["1-value"]); +- +- buildTests('testCompletion_ifStmt_topLevelVar', ''' +-int topValue = 7; class Foo { mth() { if (t!1) {}}}''', ["1+topValue"]); +- +- buildTests('testCompletion_ifStmt_topLevelVara', ''' +-topValue = 7; class Foo { mth() { if (t!1) {}}}''', ["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; +-}''', +- ["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; +-}''', +- ["1+a", "1-x", "1-y"], +- failingTests: '1'); +- +- buildTests('testCompletion_import', ''' +-import '!1';''', ["1+dart:!", "1+package:!"]); +- +- buildTests('testCompletion_import_dart', ''' +-import 'dart:math +-import 'dart:_chrome +-import 'dart:_collection.dev +-import 'dart:!1''', [ +- "1+dart:core", +- "1+dart:math", +- "1-dart:_chrome", +- "1-dart:_collection.dev" +- ]); +- +- buildTests('testCompletion_import_hasStringLiteral_noSemicolon', ''' +-import '!1' +- +-class A {}''', ["1+dart:!", "1+package:!"]); +- +- buildTests( +- 'testCompletion_import_noSpace', +- ''' +-import!1''', +- ["1+ 'dart:!';", "1+ 'package:!';"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_import_noStringLiteral', +- ''' +-import !1;''', +- ["1+'dart:!'", "1+'package:!'"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_import_noStringLiteral_noSemicolon', +- ''' +-import !1 +- +-class A {}''', +- ["1+'dart:!';", "1+'package:!';"], +- failingTests: '1'); +- +- buildTests('testCompletion_incompleteClassMember', ''' +-class A { +- Str!1 +- final f = null; +-}''', ["1+String", "1-bool"]); +- +- buildTests('testCompletion_incompleteClosure_parameterType', ''' +-f1(cb(String s)) {} +-f2(String s) {} +-main() { +- f1((Str!1)); +- f2((Str!2)); +-}''', ["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; +-}''', +- ["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); +-}''', ["1+int", "2+int"]); +- +- buildTests( +- 'testCompletion_import_lib', +- ''' +-import '!1''', +- ["1+my_lib.dart"], +- extraFiles: {"/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; +-}''', [ +- "1+MyClass", +- "2+MyClass", +- "3+MyClass", +- "3-v1", +- "4+is", +- "4-isVariable" +- ]); +- +- buildTests('testCompletion_is_asIdentifierStart', ''' +-main(p) { +- var isVisible; +- var v1 = is!1; +- var v2 = is!2 +-}''', ["1+isVisible", "2+isVisible"]); +- +- buildTests('testCompletion_is_asPrefixedIdentifierStart', ''' +-class A { +- var isVisible; +-} +- +-main(A p) { +- var v1 = p.is!1; +- var v2 = p.is!2 +-}''', ["1+isVisible", "2+isVisible"]); +- +- buildTests('testCompletion_is_incompleteStatement1', ''' +-class MyClass {} +-main(p) { +- var justSomeVar; +- var v = p is !1 +-}''', ["1+MyClass", "1-justSomeVar"]); +- +- buildTests('testCompletion_is_incompleteStatement2', ''' +-class MyClass {} +-main(p) { +- var isVariable; +- var v = p is!1 +-}''', ["1+is", "1-isVariable"]); +- +- buildTests('testCompletion_keyword_in', ''' +-class Foo { int input = 7; mth() { if (in!1) {}}}''', ["1+input"]); +- +- buildTests('testCompletion_keyword_syntheticIdentifier', ''' +-main() { +- var caseVar; +- var otherVar; +- var v = case!1 +-}''', ["1+caseVar", "1-otherVar"]); +- +- buildTests('testCompletion_libraryIdentifier_atEOF', ''' +-library int.!1''', ["1-parse", "1-bool"]); +- +- buildTests('testCompletion_libraryIdentifier_notEOF', ''' +-library int.!1''', ["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; ); +-}''', +- [ +- "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; ); +-}''', +- [ +- "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); +-}''', [ +- "1+myFunc" /*":" + ProposalKind.METHOD*/, +- "1+myFunc" /*":" + ProposalKind.METHOD_NAME*/ +- ]); +- +- buildTests('testCompletion_namedArgument_alreadyUsed', ''' +-func({foo}) {} main() { func(foo: 0, fo!1); }''', ["1-foo"]); +- +- buildTests( +- 'testCompletion_namedArgument_constructor', +- ''' +-class A {A({foo, bar}) {}} main() { new A(fo!1); }''', +- ["1+foo", "1-bar"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_namedArgument_empty', +- ''' +-func({foo, bar}) {} main() { func(!1); }''', +- [ +- "1+foo" /*":" + ProposalKind.NAMED_ARGUMENT*/, +- "1-foo" /*":" + ProposalKind.OPTIONAL_ARGUMENT*/ +- ], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_namedArgument_function', +- ''' +-func({foo, bar}) {} main() { func(fo!1); }''', +- ["1+foo", "1-bar"], +- failingTests: '1'); +- +- buildTests('testCompletion_namedArgument_notNamed', ''' +-func([foo]) {} main() { func(fo!1); }''', ["1-foo"]); +- +- buildTests('testCompletion_namedArgument_unresolvedFunction', ''' +-main() { func(fo!1); }''', ["1-foo"]); +- +- buildTests('testCompletion_newMemberType1', ''' +-class Collection{}class List extends Collection{}class Foo { !1 }''', +- ["1+Collection", "1+List"]); +- +- buildTests('testCompletion_newMemberType2', ''' +-class Collection{}class List extends Collection{}class Foo {!1}''', +- ["1+Collection", "1+List"]); +- +- buildTests('testCompletion_newMemberType3', ''' +-class Collection{}class List extends Collection{}class Foo {L!1}''', +- ["1-Collection", "1+List"]); +- +- buildTests('testCompletion_newMemberType4', ''' +-class Collection{}class List extends Collection{}class Foo {C!1}''', +- ["1+Collection", "1-List"]); +- +- buildTests( +- 'testCompletion_positionalArgument_constructor', +- ''' +-class A { +- A([foo, bar]); +-} +-main() { +- new A(!1); +- new A(0, !2); +-}''', +- [ +- "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); +-}''', +- [ +- "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 +-}''', +- [ +- "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 +-}''', ["1+_c", "1+c"]); +- +- buildTests('testCompletion_privateElement_sameLibrary_member', ''' +-class A { +- _m() {} +- m() {} +-} +-main(A a) { +- a.!1 +-}''', ["1+_m", "1+m"]); +- +- buildTests('testCompletion_propertyAccess_whenClassTarget', ''' +-class A { +- static int FIELD; +- int field; +-} +-main() { +- A.!1 +-}''', ["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; +-}''', ["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; +-}''', ["1-FIELD", "1+fieldA", "2+fieldC", "2+fieldA"]); +- +- buildTests('testCompletion_return_withIdentifierPrefix', ''' +-f() { var vvv = 42; return v!1 }''', ["1+vvv"]); +- +- buildTests('testCompletion_return_withoutExpression', ''' +-f() { var vvv = 42; return !1 }''', ["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 }}''', +- ["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 +- } +-}''', ["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 +-}''', +- ["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 +-}''', +- ["1+fooA", "1+fooB", "1-bar"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_this_bad_inConstructorInitializer', +- ''' +-class A { +- var f; +- A() : f = this.!1; +-}''', +- ["1-toString"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_this_bad_inFieldDeclaration', +- ''' +-class A { +- var f = this.!1; +-}''', +- ["1-toString"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_this_bad_inStaticMethod', +- ''' +-class A { +- static m() { +- this.!1; +- } +-}''', +- ["1-toString"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_this_bad_inTopLevelFunction', +- ''' +-main() { +- this.!1; +-}''', +- ["1-toString"], +- failingTests: '1'); +- +- buildTests( +- 'testCompletion_this_bad_inTopLevelVariableDeclaration', +- ''' +-var v = this.!1;''', +- ["1-toString"], +- failingTests: '1'); +- +- buildTests('testCompletion_this_OK_inConstructorBody', ''' +-class A { +- var f; +- m() {} +- A() { +- this.!1; +- } +-}''', ["1+f", "1+m"]); +- +- buildTests('testCompletion_this_OK_localAndSuper', ''' +-class A { +- var fa; +- ma() {} +-} +-class B extends A { +- var fb; +- mb() {} +- main() { +- this.!1 +- } +-}''', ["1+fa", "1+fb", "1+ma", "1+mb"]); +- +- buildTests('testCompletion_topLevelField_init2', ''' +-class DateTime{static var JUN;}final num M = Dat!1eTime.JUN;''', +- ["1+DateTime", "1-void"]); +- +- buildTests('testCompletion_while', ''' +-class Foo { int boo = 7; mth() { while (b!1) {} }}''', ["1+boo"]); +- } +- +- void buildLibraryTests() { +- Map sources = new HashMap(); +- +- buildTests('test_export_ignoreIfThisLibraryExports', ''' +-export 'dart:math'; +-libFunction() {}; +-main() { +- !1 +-}''', ["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 +-}''', +- ["1+cos", "1-sin", "1+libFunction"], +- extraFiles: sources, +- failingTests: '1'); +- +- buildTests( +- 'test_importPrefix_hideCombinator', +- ''' +-import 'dart:math' as math hide PI; +-main() { +- math.!1 +-}''', +- ["1-PI", "1+LN10"], +- failingTests: '1'); +- +- buildTests( +- 'test_importPrefix_showCombinator', +- ''' +-import 'dart:math' as math show PI; +-main() { +- math.!1 +-}''', +- ["1+PI", "1-LN10"], +- failingTests: '1'); +- +- 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 +-}''', +- ["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 +-}''', +- ["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 +- }''', +- ["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();}''', +- ["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();}''', +- ["1+length", "1+isEmpty", "2+clear"], +- failingTests: '1'); +- +- // TODO Include corelib analysis +- buildTests('testLibrary003', '''class X{var q; f() {q.!1a!2}}''', +- ["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}''', [ +- "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;}''', ["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(); +-}''', +- ["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 +-}''', +- ["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 +- } +-}''', +- ["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 +-}''', +- [ +- "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 +-}''', [ +- "1+toString", +- "1-==", +- "2+toString", +- "3+hashCode", +- "3+toString", +- "4+hashCode", +- "4-toString" +- ]); +- +- buildTests('test002', ''' +-void r2(var vim) { +- v!1.toString() +-}''', ["1+vim"]); +- +- buildTests('test003', ''' +-class A { +- int a() => 3; +- int b() => this.!1a(); +-}''', ["1+a"]); +- +- buildTests( +- 'test004', +- ''' +-class A { +- int x; +- A() : this.!1x = 1; +- A.b() : this(); +- A.c() : this.!2b(); +- g() => new A.!3c(); +-}''', +- ["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(); +-}''', +- [ +- "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() +-}''', ["1+va", "1-b"]); +- +- buildTests('test007', ''' +-void r2(var vim, [va: 2, b: 3]) { +- v!1.toString() +-}''', ["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 {}''', +- [ +- "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''', +- [ +- "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!7 {} +-class tezetst !9!A {}''', +- [ +- "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);''', +- ["1+object2"], +- failingTests: '1'); +- +- // reserved words +- buildTests( +- 'test012', +- ''' +-class X { +- f() { +- g(!1var!2 z) {!3true.!4toString();}; +- } +-}''', +- [ +- "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 {}; +- } +-}''', +- [ +- "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; +- } +-}''', +- [ +- "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;''', ["1+=="], +- failingTests: '1'); +- +- // operators in return +- buildTests( +- 'test016', +- '''class X {dynamic f(a,b,c) {return a + b * c !1;}}''', +- ["1+=="], +- failingTests: '1'); +- +- // keywords +- buildTests( +- 'test017', +- ''' +-!1!2import 'x' !5as r; +-!3export '!8uri' !6hide Q !7show X; +-!4part 'x';''', +- [ +- "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;''', ["1+part", "2+of"], +- failingTests: '12'); +- +- buildTests('test019', ''' +-var truefalse = 0; +-var falsetrue = 1; +-main() { +- var foo = true!1 +-}''', ["1+true", "1+truefalse", "1-falsetrue"]); +- +- buildTests('test020', '''var x = null.!1''', ["1+toString"]); +- +- buildTests('test021', '''var x = .!1''', ["1-toString"]); +- +- buildTests('test022', '''var x = .!1;''', ["1-toString"]); +- +- buildTests('test023', ''' +-class Map{getKeys(){}} +-class X { +- static x1(Map m) { +- m.!1getKeys; +- } +- x2(Map m) { +- m.!2getKeys; +- } +-}''', ["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 +- } +-}''', ["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(); +- } +-}''', [ +- "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''', ["1+aBcD"]); +- +- buildTests( +- 'test027', '''m(){try{}catch(eeee,ssss){s!1}''', ["1+ssss"]); +- +- buildTests('test028', '''m(){var isX=3;if(is!1)''', ["1+isX"]); +- +- buildTests('test029', '''m(){[1].forEach((x)=>!1x);}''', ["1+x"]); +- +- buildTests('test030', '''n(){[1].forEach((x){!1});}''', ["1+x"]); +- +- buildTests( +- 'test031', +- '''class Caster {} m() {try {} on Cas!1ter catch (CastBlock) {!2}}''', +- ["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; +- } +-}''', [ +- "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}}''', +- ["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(); +- } +-}''', +- ["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;}}''', +- ["1+length"], +- 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( +- 'test036', +- ''' +-class A1 { +- var field; +- A1() : field = 0; +- q() { +- A1 a = new A1(); +- a.field.!1 +- } +-} +-main() { +- A1 a = new A1(); +- a.field.!2 +-}''', +- ["1+round", "2+round"], +- failingTests: '12'); +- +- buildTests( +- 'test037', +- ''' +-class HttpServer{} +-class HttpClient{} +-main() { +- new HtS!1 +-}''', +- ["1+HttpServer", "1-HttpClient"], +- failingTests: '1'); +- +- buildTests( +- 'test038', +- ''' +-class X { +- x(){} +-} +-class Y { +- y(){} +-} +-class A { +- Y ay; +- Z az; +- A(this.ay, this.az) { +- ay.!1y; +- az.!2x; +- } +-}''', +- ["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;''', ["1-void"]); +- +- // test arg lists with named params +- buildTests('test040', '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1)!2;}''', +- ["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''', +- ["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''', +- ["1+x1", "1+x2", "2-y"], +- failingTests: '1'); +- } +- +- void buildOtherTests() { +- buildTests('test_classMembers_inGetter', +- '''class A { var fff; get z {ff!1}}''', ["1+fff"]); +- +- buildTests( +- 'testSingle', +- '''class A {int x; !2mth() {int y = this.x;}}class B{}''', +- ["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 sould be used to mark known completion bugs that +- * have not yet been fixed. +- */ +- void buildTests(String baseName, String originalSource, List results, +- {Map extraFiles, String failingTests: ''}) { +- List 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 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); +- }); +- } +- } +- } +-} +diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart +deleted file mode 100644 +index af602208b02..00000000000 +--- a/pkg/analysis_server/test/completion_test_support.dart ++++ /dev/null +@@ -1,203 +0,0 @@ +-// Copyright (c) 2014, 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:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +- +-import 'domain_completion_test.dart'; +- +-/** +- * A base class for classes containing completion tests. +- */ +-class CompletionTestCase extends CompletionDomainHandlerTest { +- static const String CURSOR_MARKER = '!'; +- +- List get suggestedCompletions => suggestions +- .map((CompletionSuggestion suggestion) => suggestion.completion) +- .toList(); +- +- void assertHasCompletion(String completion) { +- int expectedOffset = completion.indexOf(CURSOR_MARKER); +- if (expectedOffset >= 0) { +- if (completion.indexOf(CURSOR_MARKER, expectedOffset + 1) >= 0) { +- fail( +- "Invalid completion, contains multiple cursor positions: '$completion'"); +- } +- completion = completion.replaceFirst(CURSOR_MARKER, ''); +- } else { +- expectedOffset = completion.length; +- } +- CompletionSuggestion matchingSuggestion; +- suggestions.forEach((CompletionSuggestion suggestion) { +- if (suggestion.completion == completion) { +- if (matchingSuggestion == null) { +- matchingSuggestion = suggestion; +- } else { +- fail( +- "Expected exactly one '$completion' but found multiple:\n $suggestedCompletions"); +- } +- } +- }); +- if (matchingSuggestion == null) { +- fail("Expected '$completion' but found none:\n $suggestedCompletions"); +- } +- expect(matchingSuggestion.selectionOffset, equals(expectedOffset)); +- expect(matchingSuggestion.selectionLength, equals(0)); +- } +- +- void assertHasNoCompletion(String completion) { +- if (suggestions.any((CompletionSuggestion suggestion) => +- suggestion.completion == completion)) { +- fail( +- "Did not expect completion '$completion' but found:\n $suggestedCompletions"); +- } +- } +- +- /** +- * Discard any results that do not start with the characters the user has +- * "already typed". +- */ +- void filterResults(String content) { +- String charsAlreadyTyped = +- content.substring(replacementOffset, completionOffset).toLowerCase(); +- suggestions = suggestions +- .where((CompletionSuggestion suggestion) => +- suggestion.completion.toLowerCase().startsWith(charsAlreadyTyped)) +- .toList(); +- } +- +- runTest(LocationSpec spec, [Map extraFiles]) { +- super.setUp(); +- return new Future(() { +- String content = spec.source; +- addFile(testFile, content); +- this.testCode = content; +- completionOffset = spec.testLocation; +- if (extraFiles != null) { +- extraFiles.forEach((String fileName, String content) { +- addFile(fileName, content); +- }); +- } +- }).then((_) => getSuggestions()).then((_) { +- filterResults(spec.source); +- for (String result in spec.positiveResults) { +- assertHasCompletion(result); +- } +- for (String result in spec.negativeResults) { +- assertHasNoCompletion(result); +- } +- }).whenComplete(() { +- super.tearDown(); +- }); +- } +-} +- +-/** +- * A specification of the completion results expected at a given location. +- */ +-class LocationSpec { +- String id; +- int testLocation = -1; +- List positiveResults = []; +- List negativeResults = []; +- String source; +- +- LocationSpec(this.id); +- +- /** +- * Parse a set of tests from the given `originalSource`. Return a list of the +- * specifications that were parsed. +- * +- * The source string has test locations 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. If logical not is needed in the source it +- * can be represented by '!!'. +- * +- * The [originalSource] is the source for a test that contains test locations. +- * The [validationStrings] are the positive and negative predictions. +- */ +- static List from( +- String originalSource, List validationStrings) { +- Map tests = new HashMap(); +- String modifiedSource = originalSource; +- int modifiedPosition = 0; +- while (true) { +- int index = modifiedSource.indexOf('!', modifiedPosition); +- if (index < 0) { +- break; +- } +- int n = 1; // only delete one char for double-bangs +- String id = modifiedSource.substring(index + 1, index + 2); +- if (id != '!') { +- n = 2; +- LocationSpec test = new LocationSpec(id); +- tests[id] = test; +- test.testLocation = index; +- } else { +- modifiedPosition = index + 1; +- } +- modifiedSource = modifiedSource.substring(0, index) + +- modifiedSource.substring(index + n); +- } +- if (modifiedSource == originalSource) { +- throw new StateError("No tests in source: " + originalSource); +- } +- for (String result in validationStrings) { +- if (result.length < 3) { +- throw new StateError("Invalid location result: " + result); +- } +- String id = result.substring(0, 1); +- String sign = result.substring(1, 2); +- String value = result.substring(2); +- LocationSpec test = tests[id]; +- if (test == null) { +- throw new StateError("Invalid location result id: $id for: $result"); +- } +- test.source = modifiedSource; +- if (sign == '+') { +- test.positiveResults.add(value); +- } else if (sign == '-') { +- test.negativeResults.add(value); +- } else { +- String err = "Invalid location result sign: $sign for: $result"; +- throw new StateError(err); +- } +- } +- List badPoints = []; +- List badResults = []; +- for (LocationSpec test in tests.values) { +- if (test.testLocation == -1) { +- badPoints.add(test.id); +- } +- if (test.positiveResults.isEmpty && test.negativeResults.isEmpty) { +- badResults.add(test.id); +- } +- } +- if (!(badPoints.isEmpty && badResults.isEmpty)) { +- StringBuffer err = new StringBuffer(); +- if (!badPoints.isEmpty) { +- err.write("No test location for tests:"); +- for (String ch in badPoints) { +- err..write(' ')..write(ch); +- } +- err.write(' '); +- } +- if (!badResults.isEmpty) { +- err.write("No results for tests:"); +- for (String ch in badResults) { +- err..write(' ')..write(ch); +- } +- } +- throw new StateError(err.toString()); +- } +- return tests.values.toList(); +- } +-} +diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart +deleted file mode 100644 +index f63eaf8a7b3..00000000000 +--- a/pkg/analysis_server/test/context_manager_test.dart ++++ /dev/null +@@ -1,2695 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library test.context.directory.manager; +- +-import 'dart:async'; +- +-import 'package:analysis_server/src/context_manager.dart'; +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analysis_server/src/utilities/null_string_sink.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/source/error_processor.dart'; +-import 'package:analyzer/src/context/builder.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/file_state.dart'; +-import 'package:analyzer/src/error/codes.dart'; +-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/source_io.dart'; +-import 'package:analyzer/src/services/lint.dart'; +-import 'package:analyzer/src/summary/summary_file_builder.dart'; +-import 'package:analyzer/src/util/glob.dart'; +-import 'package:front_end/byte_store.dart'; +-import 'package:front_end/src/base/performance_logger.dart'; +-import 'package:linter/src/rules.dart'; +-import 'package:linter/src/rules/avoid_as.dart'; +-import 'package:path/path.dart' as path; +-import 'package:plugin/manager.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +-import 'package:watcher/watcher.dart'; +- +-import 'mock_sdk.dart'; +-import 'mocks.dart'; +-import 'src/plugin/plugin_manager_test.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AbstractContextManagerTest); +- defineReflectiveTests(ContextManagerWithNewOptionsTest); +- defineReflectiveTests(ContextManagerWithOldOptionsTest); +- }); +-} +- +-@reflectiveTest +-class AbstractContextManagerTest extends ContextManagerTest { +- void test_contextsInAnalysisRoot_nestedContext() { +- String subProjPath = path.posix.join(projPath, 'subproj'); +- Folder subProjFolder = resourceProvider.newFolder(subProjPath); +- resourceProvider.newFile( +- path.posix.join(subProjPath, 'pubspec.yaml'), 'contents'); +- String subProjFilePath = path.posix.join(subProjPath, 'file.dart'); +- resourceProvider.newFile(subProjFilePath, 'contents'); +- manager.setRoots([projPath], [], {}); +- // Make sure that there really are contexts for both the main project and +- // the subproject. +- Folder projectFolder = resourceProvider.getFolder(projPath); +- ContextInfo projContextInfo = manager.getContextInfoFor(projectFolder); +- expect(projContextInfo, isNotNull); +- expect(projContextInfo.folder, projectFolder); +- ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder); +- expect(subProjContextInfo, isNotNull); +- expect(subProjContextInfo.folder, subProjFolder); +- expect(projContextInfo.analysisDriver, +- isNot(equals(subProjContextInfo.analysisDriver))); +- // Check that getDriversInAnalysisRoot() works. +- List drivers = +- manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, isNotNull); +- expect(drivers, hasLength(2)); +- expect(drivers, contains(projContextInfo.analysisDriver)); +- expect(drivers, contains(subProjContextInfo.analysisDriver)); +- } +- +- @failingTest +- test_embedder_added() async { +- // NoSuchMethodError: The getter 'apiSignature' was called on null. +- // Receiver: null +- // Tried calling: apiSignature +- // dart:core Object.noSuchMethod +- // package:analyzer/src/dart/analysis/driver.dart 460:20 AnalysisDriver.configure +- // package:analysis_server/src/context_manager.dart 1043:16 ContextManagerImpl._checkForPackagespecUpdate +- // package:analysis_server/src/context_manager.dart 1553:5 ContextManagerImpl._handleWatchEvent +- //return super.test_embedder_added(); +- fail('NoSuchMethodError'); +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'nope.dart']); +- String embedderPath = newFolder([projPath, 'embedder']); +- newFile([embedderPath, 'entry.dart']); +- String embedderSrcPath = newFolder([projPath, 'embedder', 'src']); +- newFile([embedderSrcPath, 'part.dart']); +- +- // Setup _embedder.yaml. +- newFile([libPath, '_embedder.yaml'], r''' +-embedded_libs: +- "dart:foobar": "../embedder/entry.dart" +- "dart:typed_data": "../embedder/src/part" +- '''); +- +- Folder projectFolder = resourceProvider.newFolder(projPath); +- +- // NOTE that this is Not in our package path yet. +- +- // Setup context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- // Confirm that one driver / context was created. +- List drivers = +- manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, isNotNull); +- expect(drivers, hasLength(1)); +- +- // No embedded libs yet. +- expect(sourceFactory.forUri('dart:typed_data'), isNull); +- +- // Add .packages file that introduces a dependency with embedded libs. +- newFile([projPath, '.packages'], r''' +-test_pack:lib/'''); +- +- await pumpEventQueue(); +- +- // Confirm that we still have just one driver / context. +- drivers = manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, isNotNull); +- expect(drivers, hasLength(1)); +- +- // Embedded lib should be defined now. +- expect(sourceFactory.forUri('dart:typed_data'), isNotNull); +- } +- +- test_embedder_packagespec() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'nope.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Setup _embedder.yaml. +- newFile([libPath, '_embedder.yaml'], r''' +-embedded_libs: +- "dart:foobar": "../sdk_ext/entry.dart" +- "dart:typed_data": "../sdk_ext/src/part" +- '''); +- // Setup .packages file +- newFile([projPath, '.packages'], r''' +-test_pack:lib/'''); +- // Setup context. +- +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- // Confirm that one context was created. +- int count = manager +- .numberOfContextsInAnalysisRoot(resourceProvider.newFolder(projPath)); +- expect(count, equals(1)); +- var source = sourceFactory.forUri('dart:foobar'); +- expect(source, isNotNull); +- expect(source.fullName, '/my/proj/sdk_ext/entry.dart'); +- // We can't find dart:core because we didn't list it in our +- // embedded_libs map. +- expect(sourceFactory.forUri('dart:core'), isNull); +- // We can find dart:typed_data because we listed it in our +- // embedded_libs map. +- expect(sourceFactory.forUri('dart:typed_data'), isNotNull); +- } +- +- test_ignoreFilesInPackagesFolder() { +- // create a context with a pubspec.yaml file +- String pubspecPath = path.posix.join(projPath, 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'pubspec'); +- // create a file in the "packages" folder +- String filePath1 = path.posix.join(projPath, 'packages', 'file1.dart'); +- resourceProvider.newFile(filePath1, 'contents'); +- // "packages" files are ignored initially +- manager.setRoots([projPath], [], {}); +- expect(callbacks.currentFilePaths, isEmpty); +- // "packages" files are ignored during watch +- String filePath2 = path.posix.join(projPath, 'packages', 'file2.dart'); +- resourceProvider.newFile(filePath2, 'contents'); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentFilePaths, isEmpty); +- }); +- } +- +- void test_isInAnalysisRoot_excluded() { +- // prepare paths +- String project = '/project'; +- String excludedFolder = '$project/excluded'; +- // set roots +- resourceProvider.newFolder(project); +- resourceProvider.newFolder(excludedFolder); +- manager.setRoots( +- [project], [excludedFolder], {}); +- // verify +- expect(manager.isInAnalysisRoot('$excludedFolder/test.dart'), isFalse); +- } +- +- void test_isInAnalysisRoot_inNestedContext() { +- String subProjPath = path.posix.join(projPath, 'subproj'); +- Folder subProjFolder = resourceProvider.newFolder(subProjPath); +- resourceProvider.newFile( +- path.posix.join(subProjPath, 'pubspec.yaml'), 'contents'); +- String subProjFilePath = path.posix.join(subProjPath, 'file.dart'); +- resourceProvider.newFile(subProjFilePath, 'contents'); +- manager.setRoots([projPath], [], {}); +- // Make sure that there really is a context for the subproject. +- ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder); +- expect(subProjContextInfo, isNotNull); +- expect(subProjContextInfo.folder, subProjFolder); +- // Check that isInAnalysisRoot() works. +- expect(manager.isInAnalysisRoot(subProjFilePath), isTrue); +- } +- +- void test_isInAnalysisRoot_inRoot() { +- manager.setRoots([projPath], [], {}); +- expect(manager.isInAnalysisRoot('$projPath/test.dart'), isTrue); +- } +- +- void test_isInAnalysisRoot_notInRoot() { +- manager.setRoots([projPath], [], {}); +- expect(manager.isInAnalysisRoot('/test.dart'), isFalse); +- } +- +- test_path_filter() async { +- // Setup context. +- Folder root = resourceProvider.newFolder(projPath); +- manager.setRoots([projPath], [], {}); +- expect(callbacks.currentFilePaths, isEmpty); +- // Set ignore patterns for context. +- ContextInfo rootInfo = manager.getContextInfoFor(root); +- manager.setIgnorePatternsForContext( +- rootInfo, ['sdk_ext/**', 'lib/ignoreme.dart']); +- // Start creating files. +- newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]); +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'ignoreme.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Pump event loop so new files are discovered and added to context. +- await pumpEventQueue(); +- // Verify that ignored files were ignored. +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains('/my/proj/lib/main.dart')); +- } +- +- test_refresh_folder_with_packagespec() { +- // create a context with a .packages file +- String packagespecFile = path.posix.join(projPath, '.packages'); +- resourceProvider.newFile(packagespecFile, ''); +- manager.setRoots([projPath], [], {}); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- callbacks.now++; +- manager.refresh(null); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- expect(callbacks.currentContextTimestamps[projPath], callbacks.now); +- }); +- }); +- } +- +- // TODO(paulberry): This test only tests PackagesFileDisposition. +- // Once http://dartbug.com/23909 is fixed, add a test for sdk extensions +- // and PackageMapDisposition. +- test_refresh_folder_with_packagespec_subfolders() { +- // Create a folder with no .packages file, containing two subfolders with +- // .packages files. +- String subdir1Path = path.posix.join(projPath, 'subdir1'); +- String subdir2Path = path.posix.join(projPath, 'subdir2'); +- String packagespec1Path = path.posix.join(subdir1Path, '.packages'); +- String packagespec2Path = path.posix.join(subdir2Path, '.packages'); +- resourceProvider.newFile(packagespec1Path, ''); +- resourceProvider.newFile(packagespec2Path, ''); +- manager.setRoots([projPath], [], {}); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, +- unorderedEquals([subdir1Path, subdir2Path, projPath])); +- callbacks.now++; +- manager.refresh(null); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, +- unorderedEquals([subdir1Path, subdir2Path, projPath])); +- expect(callbacks.currentContextTimestamps[projPath], callbacks.now); +- expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now); +- expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now); +- }); +- }); +- } +- +- test_refresh_folder_with_pubspec() { +- // create a context with a pubspec.yaml file +- String pubspecPath = path.posix.join(projPath, 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'pubspec'); +- manager.setRoots([projPath], [], {}); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- callbacks.now++; +- manager.refresh(null); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- expect(callbacks.currentContextTimestamps[projPath], callbacks.now); +- }); +- }); +- } +- +- test_refresh_folder_with_pubspec_subfolders() { +- // Create a folder with no pubspec.yaml, containing two subfolders with +- // pubspec.yaml files. +- String subdir1Path = path.posix.join(projPath, 'subdir1'); +- String subdir2Path = path.posix.join(projPath, 'subdir2'); +- String pubspec1Path = path.posix.join(subdir1Path, 'pubspec.yaml'); +- String pubspec2Path = path.posix.join(subdir2Path, 'pubspec.yaml'); +- resourceProvider.newFile(pubspec1Path, 'pubspec'); +- resourceProvider.newFile(pubspec2Path, 'pubspec'); +- manager.setRoots([projPath], [], {}); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, +- unorderedEquals([subdir1Path, subdir2Path, projPath])); +- callbacks.now++; +- manager.refresh(null); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, +- unorderedEquals([subdir1Path, subdir2Path, projPath])); +- expect(callbacks.currentContextTimestamps[projPath], callbacks.now); +- expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now); +- expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now); +- }); +- }); +- } +- +- test_refresh_oneContext() { +- // create two contexts with pubspec.yaml files +- String pubspecPath = path.posix.join(projPath, 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'pubspec1'); +- +- String proj2Path = '/my/proj2'; +- resourceProvider.newFolder(proj2Path); +- String pubspec2Path = path.posix.join(proj2Path, 'pubspec.yaml'); +- resourceProvider.newFile(pubspec2Path, 'pubspec2'); +- +- List roots = [projPath, proj2Path]; +- manager.setRoots(roots, [], {}); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, unorderedEquals(roots)); +- int then = callbacks.now; +- callbacks.now++; +- manager.refresh([resourceProvider.getResource(proj2Path)]); +- return pumpEventQueue().then((_) { +- expect(callbacks.currentContextRoots, unorderedEquals(roots)); +- expect(callbacks.currentContextTimestamps[projPath], then); +- expect(callbacks.currentContextTimestamps[proj2Path], callbacks.now); +- }); +- }); +- } +- +- test_sdk_ext_packagespec() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'nope.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Setup sdk extension mapping. +- newFile([libPath, '_sdkext'], r''' +-{ +- "dart:foobar": "../sdk_ext/entry.dart" +-} +-'''); +- // Setup .packages file +- newFile([projPath, '.packages'], r''' +-test_pack:lib/'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- // Confirm that one context was created. +- int count = manager +- .numberOfContextsInAnalysisRoot(resourceProvider.newFolder(projPath)); +- expect(count, equals(1)); +- var source = sourceFactory.forUri('dart:foobar'); +- expect(source.fullName, equals('/my/proj/sdk_ext/entry.dart')); +- } +- +- void test_setRoots_addFolderWithDartFile() { +- String filePath = path.posix.join(projPath, 'foo.dart'); +- resourceProvider.newFile(filePath, 'contents'); +- manager.setRoots([projPath], [], {}); +- // verify +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- List drivers = +- manager.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath)); +- expect(drivers, hasLength(1)); +- expect(drivers[0], isNotNull); +- Source result = sourceFactory.forUri('dart:async'); +- expect(result, isNotNull); +- } +- +- void test_setRoots_addFolderWithDartFileInSubfolder() { +- String filePath = path.posix.join(projPath, 'foo', 'bar.dart'); +- resourceProvider.newFile(filePath, 'contents'); +- manager.setRoots([projPath], [], {}); +- // verify +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- } +- +- void test_setRoots_addFolderWithDummyLink() { +- String filePath = path.posix.join(projPath, 'foo.dart'); +- resourceProvider.newDummyLink(filePath); +- manager.setRoots([projPath], [], {}); +- // verify +- expect(callbacks.currentFilePaths, isEmpty); +- } +- +- void test_setRoots_addFolderWithNestedPackageSpec() { +- String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]); +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([examplePath, ContextManagerImpl.PACKAGE_SPEC_NAME]); +- newFile([examplePath, 'example.dart']); +- +- packageMapProvider.packageMap['proj'] = [ +- resourceProvider.getResource(libPath) +- ]; +- +- manager.setRoots([projPath], [], {}); +- +- expect(callbacks.currentContextRoots, hasLength(2)); +- +- expect(callbacks.currentContextRoots, contains(projPath)); +- Iterable projSources = callbacks.currentFileSources(projPath); +- expect(projSources, hasLength(1)); +- expect(projSources.first.uri.toString(), 'file:///my/proj/lib/main.dart'); +- +- expect(callbacks.currentContextRoots, contains(examplePath)); +- Iterable exampleSources = callbacks.currentFileSources(examplePath); +- expect(exampleSources, hasLength(1)); +- expect(exampleSources.first.uri.toString(), +- 'file:///my/proj/example/example.dart'); +- } +- +- void test_setRoots_addFolderWithNestedPubspec() { +- String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]); +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- +- newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]); +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/'); +- newFile([libPath, 'main.dart']); +- newFile([examplePath, ContextManagerImpl.PUBSPEC_NAME]); +- newFile([examplePath, 'example.dart']); +- +- manager.setRoots([projPath], [], {}); +- +- expect(callbacks.currentContextRoots, hasLength(2)); +- +- expect(callbacks.currentContextRoots, contains(projPath)); +- Iterable projSources = callbacks.currentFileSources(projPath); +- expect(projSources, hasLength(1)); +- expect(projSources.first.uri.toString(), 'package:proj/main.dart'); +- +- expect(callbacks.currentContextRoots, contains(examplePath)); +- Iterable exampleSources = callbacks.currentFileSources(examplePath); +- expect(exampleSources, hasLength(1)); +- expect(exampleSources.first.uri.toString(), +- 'file:///my/proj/example/example.dart'); +- } +- +- void test_setRoots_addFolderWithoutPubspec() { +- packageMapProvider.packageMap = null; +- manager.setRoots([projPath], [], {}); +- // verify +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_addFolderWithPackagespec() { +- String packagespecPath = path.posix.join(projPath, '.packages'); +- resourceProvider.newFile(packagespecPath, +- 'unittest:file:///home/somebody/.pub/cache/unittest-0.9.9/lib/'); +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- File mainFile = +- resourceProvider.newFile(path.posix.join(libPath, 'main.dart'), ''); +- Source source = mainFile.createSource(); +- +- manager.setRoots([projPath], [], {}); +- +- // verify +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- expect(callbacks.currentFilePaths, hasLength(1)); +- +- // smoketest resolution +- Source resolvedSource = +- sourceFactory.resolveUri(source, 'package:unittest/unittest.dart'); +- expect(resolvedSource, isNotNull); +- expect(resolvedSource.fullName, +- equals('/home/somebody/.pub/cache/unittest-0.9.9/lib/unittest.dart')); +- } +- +- void test_setRoots_addFolderWithPackagespecAndPackageRoot() { +- // The package root should take priority. +- String packagespecPath = path.posix.join(projPath, '.packages'); +- resourceProvider.newFile(packagespecPath, +- 'unittest:file:///home/somebody/.pub/cache/unittest-0.9.9/lib/'); +- String packageRootPath = '/package/root/'; +- manager.setRoots([projPath], [], +- {projPath: packageRootPath}); +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- _checkPackageRoot(projPath, packageRootPath); +- } +- +- void test_setRoots_addFolderWithPubspec() { +- String pubspecPath = path.posix.join(projPath, 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'pubspec'); +- manager.setRoots([projPath], [], {}); +- // verify +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_addFolderWithPubspec_andPackagespec() { +- String pubspecPath = path.posix.join(projPath, 'pubspec.yaml'); +- String packagespecPath = path.posix.join(projPath, '.packages'); +- resourceProvider.newFile(pubspecPath, 'pubspec'); +- resourceProvider.newFile(packagespecPath, ''); +- manager.setRoots([projPath], [], {}); +- // verify +- callbacks.assertContextPaths([projPath]); +- } +- +- void test_setRoots_addFolderWithPubspecAndLib() { +- String binPath = newFolder([projPath, ContextManagerTest.BIN_NAME]); +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- String srcPath = newFolder([libPath, ContextManagerTest.SRC_NAME]); +- String testPath = newFolder([projPath, ContextManagerTest.TEST_NAME]); +- +- newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]); +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/'); +- String appPath = newFile([binPath, 'app.dart']); +- newFile([libPath, 'main.dart']); +- newFile([srcPath, 'internal.dart']); +- String testFilePath = newFile([testPath, 'main_test.dart']); +- +- manager.setRoots([projPath], [], {}); +- Iterable sources = callbacks.currentFileSources(projPath); +- +- expect(callbacks.currentContextRoots, unorderedEquals([projPath])); +- expect(sources, hasLength(4)); +- List uris = +- sources.map((Source source) => source.uri.toString()).toList(); +- expect(uris, contains('file://$appPath')); +- expect(uris, contains('package:proj/main.dart')); +- expect(uris, contains('package:proj/src/internal.dart')); +- expect(uris, contains('file://$testFilePath')); +- } +- +- void test_setRoots_addFolderWithPubspecAndPackagespecFolders() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProjectA = '$root/sub/aaa'; +- String subProjectB = '$root/sub/sub2/bbb'; +- String subProjectA_file = '$subProjectA/bin/a.dart'; +- String subProjectB_file = '$subProjectB/bin/b.dart'; +- // create files +- resourceProvider.newFile('$subProjectA/pubspec.yaml', 'pubspec'); +- resourceProvider.newFile('$subProjectB/pubspec.yaml', 'pubspec'); +- resourceProvider.newFile('$subProjectA/.packages', ''); +- resourceProvider.newFile('$subProjectB/.packages', ''); +- +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subProjectA_file, 'library a;'); +- resourceProvider.newFile(subProjectB_file, 'library b;'); +- +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProjectA, subProjectB]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProjectA, [subProjectA_file]); +- callbacks.assertContextFiles(subProjectB, [subProjectB_file]); +- } +- +- void test_setRoots_addFolderWithPubspecFolders() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String projectA = '$root/sub/aaa'; +- String projectALib = '$root/sub/aaa/lib'; +- String subProjectA_file = '$projectA/bin/a.dart'; +- String projectB = '$root/sub/sub2/bbb'; +- String projectBLib = '$root/sub/sub2/bbb/lib'; +- String subProjectB_file = '$projectB/bin/b.dart'; +- // create files +- newFile([projectA, ContextManagerImpl.PUBSPEC_NAME]); +- newFile([projectA, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/'); +- newFile([projectB, ContextManagerImpl.PUBSPEC_NAME]); +- newFile([projectB, ContextManagerImpl.PACKAGE_SPEC_NAME], 'bar:lib/'); +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subProjectA_file, 'library a;'); +- resourceProvider.newFile(subProjectB_file, 'library b;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, projectA, projectB]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(projectA, [subProjectA_file]); +- callbacks.assertContextFiles(projectB, [subProjectB_file]); +- // verify package maps +- expect(_packageMap(root), isEmpty); +- expect( +- _packageMap(projectA), +- equals({ +- 'foo': [resourceProvider.getFolder(projectALib)] +- })); +- expect( +- _packageMap(projectB), +- equals({ +- 'bar': [resourceProvider.getFolder(projectBLib)] +- })); +- } +- +- void test_setRoots_addPackageRoot() { +- String packagePathFoo = '/package1/foo'; +- String packageRootPath = '/package2/foo'; +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], +- 'foo:file:///package1/foo'); +- Folder packageFolder = resourceProvider.newFolder(packagePathFoo); +- List includedPaths = [projPath]; +- List excludedPaths = []; +- manager.setRoots(includedPaths, excludedPaths, {}); +- expect( +- _currentPackageMap, +- equals({ +- 'foo': [packageFolder] +- })); +- manager.setRoots(includedPaths, excludedPaths, +- {projPath: packageRootPath}); +- _checkPackageRoot(projPath, equals(packageRootPath)); +- } +- +- void test_setRoots_changePackageRoot() { +- String packageRootPath1 = '/package1'; +- String packageRootPath2 = '/package2'; +- List includedPaths = [projPath]; +- List excludedPaths = []; +- manager.setRoots(includedPaths, excludedPaths, +- {projPath: packageRootPath1}); +- _checkPackageRoot(projPath, equals(packageRootPath1)); +- manager.setRoots(includedPaths, excludedPaths, +- {projPath: packageRootPath2}); +- _checkPackageRoot(projPath, equals(packageRootPath2)); +- } +- +- void test_setRoots_exclude_newRoot_withExcludedFile() { +- // prepare paths +- String project = '/project'; +- String file1 = '$project/file1.dart'; +- String file2 = '$project/file2.dart'; +- // create files +- resourceProvider.newFile(file1, '// 1'); +- resourceProvider.newFile(file2, '// 2'); +- // set roots +- manager.setRoots([project], [file1], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file2]); +- } +- +- void test_setRoots_exclude_newRoot_withExcludedFolder() { +- // prepare paths +- String project = '/project'; +- String folderA = '$project/aaa'; +- String folderB = '$project/bbb'; +- String fileA = '$folderA/a.dart'; +- String fileB = '$folderB/b.dart'; +- // create files +- resourceProvider.newFile(fileA, 'library a;'); +- resourceProvider.newFile(fileB, 'library b;'); +- // set roots +- manager.setRoots([project], [folderB], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- } +- +- void test_setRoots_exclude_sameRoot_addExcludedFile() { +- // prepare paths +- String project = '/project'; +- String file1 = '$project/file1.dart'; +- String file2 = '$project/file2.dart'; +- // create files +- resourceProvider.newFile(file1, '// 1'); +- resourceProvider.newFile(file2, '// 2'); +- // set roots +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file1, file2]); +- // exclude "2" +- manager.setRoots([project], [file2], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file1]); +- } +- +- void test_setRoots_exclude_sameRoot_addExcludedFolder() { +- // prepare paths +- String project = '/project'; +- String folderA = '$project/aaa'; +- String folderB = '$project/bbb'; +- String fileA = '$folderA/a.dart'; +- String fileB = '$folderB/b.dart'; +- // create files +- resourceProvider.newFile(fileA, 'library a;'); +- resourceProvider.newFile(fileB, 'library b;'); +- // initially both "aaa/a" and "bbb/b" are included +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA, fileB]); +- // exclude "bbb/" +- manager.setRoots([project], [folderB], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- } +- +- void test_setRoots_exclude_sameRoot_removeExcludedFile() { +- // prepare paths +- String project = '/project'; +- String file1 = '$project/file1.dart'; +- String file2 = '$project/file2.dart'; +- // create files +- resourceProvider.newFile(file1, '// 1'); +- resourceProvider.newFile(file2, '// 2'); +- // set roots +- manager.setRoots([project], [file2], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file1]); +- // stop excluding "2" +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file1, file2]); +- } +- +- void test_setRoots_exclude_sameRoot_removeExcludedFile_inFolder() { +- // prepare paths +- String project = '/project'; +- String file1 = '$project/bin/file1.dart'; +- String file2 = '$project/bin/file2.dart'; +- // create files +- resourceProvider.newFile(file1, '// 1'); +- resourceProvider.newFile(file2, '// 2'); +- // set roots +- manager.setRoots([project], [file2], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file1]); +- // stop excluding "2" +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [file1, file2]); +- } +- +- void test_setRoots_exclude_sameRoot_removeExcludedFolder() { +- // prepare paths +- String project = '/project'; +- String folderA = '$project/aaa'; +- String folderB = '$project/bbb'; +- String fileA = '$folderA/a.dart'; +- String fileB = '$folderB/b.dart'; +- // create files +- resourceProvider.newFile(fileA, 'library a;'); +- resourceProvider.newFile(fileB, 'library b;'); +- // exclude "bbb/" +- manager.setRoots([project], [folderB], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- // stop excluding "bbb/" +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA, fileB]); +- } +- +- void test_setRoots_ignoreDocFolder() { +- String project = '/project'; +- String fileA = '$project/foo.dart'; +- String fileB = '$project/lib/doc/bar.dart'; +- String fileC = '$project/doc/bar.dart'; +- resourceProvider.newFile(fileA, ''); +- resourceProvider.newFile(fileB, ''); +- resourceProvider.newFile(fileC, ''); +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA, fileB]); +- } +- +- void test_setRoots_nested_includedByOuter_innerFirst() { +- String project = '/project'; +- String projectPubspec = '$project/pubspec.yaml'; +- String example = '$project/example'; +- String examplePubspec = '$example/pubspec.yaml'; +- // create files +- resourceProvider.newFile(projectPubspec, 'name: project'); +- resourceProvider.newFile(examplePubspec, 'name: example'); +- manager +- .setRoots([example, project], [], {}); +- // verify +- { +- ContextInfo rootInfo = manager.rootInfo; +- expect(rootInfo.children, hasLength(1)); +- { +- ContextInfo projectInfo = rootInfo.children[0]; +- expect(projectInfo.folder.path, project); +- expect(projectInfo.children, hasLength(1)); +- { +- ContextInfo exampleInfo = projectInfo.children[0]; +- expect(exampleInfo.folder.path, example); +- expect(exampleInfo.children, isEmpty); +- } +- } +- } +- expect(callbacks.currentContextRoots, unorderedEquals([project, example])); +- } +- +- void test_setRoots_nested_includedByOuter_outerPubspec() { +- String project = '/project'; +- String projectPubspec = '$project/pubspec.yaml'; +- String example = '$project/example'; +- // create files +- resourceProvider.newFile(projectPubspec, 'name: project'); +- resourceProvider.newFolder(example); +- manager +- .setRoots([project, example], [], {}); +- // verify +- { +- ContextInfo rootInfo = manager.rootInfo; +- expect(rootInfo.children, hasLength(1)); +- { +- ContextInfo projectInfo = rootInfo.children[0]; +- expect(projectInfo.folder.path, project); +- expect(projectInfo.children, isEmpty); +- } +- } +- expect(callbacks.currentContextRoots, unorderedEquals([project])); +- } +- +- void test_setRoots_nested_includedByOuter_twoPubspecs() { +- String project = '/project'; +- String projectPubspec = '$project/pubspec.yaml'; +- String example = '$project/example'; +- String examplePubspec = '$example/pubspec.yaml'; +- // create files +- resourceProvider.newFile(projectPubspec, 'name: project'); +- resourceProvider.newFile(examplePubspec, 'name: example'); +- manager +- .setRoots([project, example], [], {}); +- // verify +- { +- ContextInfo rootInfo = manager.rootInfo; +- expect(rootInfo.children, hasLength(1)); +- { +- ContextInfo projectInfo = rootInfo.children[0]; +- expect(projectInfo.folder.path, project); +- expect(projectInfo.children, hasLength(1)); +- { +- ContextInfo exampleInfo = projectInfo.children[0]; +- expect(exampleInfo.folder.path, example); +- expect(exampleInfo.children, isEmpty); +- } +- } +- } +- expect(callbacks.currentContextRoots, unorderedEquals([project, example])); +- } +- +- void test_setRoots_newFolderWithPackageRoot() { +- String packageRootPath = '/package'; +- manager.setRoots([projPath], [], +- {projPath: packageRootPath}); +- _checkPackageRoot(projPath, equals(packageRootPath)); +- } +- +- void test_setRoots_newlyAddedFoldersGetProperPackageMap() { +- String packagePath = '/package/foo'; +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], +- 'foo:file:///package/foo'); +- Folder packageFolder = resourceProvider.newFolder(packagePath); +- manager.setRoots([projPath], [], {}); +- expect( +- _currentPackageMap, +- equals({ +- 'foo': [packageFolder] +- })); +- } +- +- void test_setRoots_noContext_excludedFolder() { +- // prepare paths +- String project = '/project'; +- String excludedFolder = '$project/excluded'; +- String excludedPubspec = '$excludedFolder/pubspec.yaml'; +- // create files +- resourceProvider.newFile(excludedPubspec, 'name: ignore-me'); +- // set "/project", and exclude "/project/excluded" +- manager.setRoots( +- [project], [excludedFolder], {}); +- callbacks.assertContextPaths([project]); +- } +- +- void test_setRoots_noContext_inDotFolder() { +- String pubspecPath = path.posix.join(projPath, '.pub', 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'name: test'); +- manager.setRoots([projPath], [], {}); +- // verify +- expect(callbacks.currentContextRoots, hasLength(1)); +- expect(callbacks.currentContextRoots, contains(projPath)); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_noContext_inPackagesFolder() { +- String pubspecPath = path.posix.join(projPath, 'packages', 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'name: test'); +- manager.setRoots([projPath], [], {}); +- // verify +- expect(callbacks.currentContextRoots, hasLength(1)); +- expect(callbacks.currentContextRoots, contains(projPath)); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_packageResolver() { +- String filePath = path.posix.join(projPath, 'lib', 'foo.dart'); +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/'); +- resourceProvider.newFile(filePath, 'contents'); +- manager.setRoots([projPath], [], {}); +- +- var drivers = +- manager.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath)); +- expect(drivers, hasLength(1)); +- expect(drivers[0], isNotNull); +- Source result = sourceFactory.forUri('package:foo/foo.dart'); +- expect(result.fullName, filePath); +- } +- +- void test_setRoots_pathContainsDotFile() { +- // If the path to a file (relative to the context root) contains a folder +- // whose name begins with '.', then the file is ignored. +- String project = '/project'; +- String fileA = '$project/foo.dart'; +- String fileB = '$project/.pub/bar.dart'; +- resourceProvider.newFile(fileA, ''); +- resourceProvider.newFile(fileB, ''); +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- } +- +- void test_setRoots_removeFolderWithoutPubspec() { +- packageMapProvider.packageMap = null; +- // add one root - there is a context +- manager.setRoots([projPath], [], {}); +- expect(callbacks.currentContextRoots, hasLength(1)); +- // set empty roots - no contexts +- manager.setRoots([], [], {}); +- expect(callbacks.currentContextRoots, hasLength(0)); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_removeFolderWithPackagespec() { +- // create a pubspec +- String pubspecPath = path.posix.join(projPath, '.packages'); +- resourceProvider.newFile(pubspecPath, ''); +- // add one root - there is a context +- manager.setRoots([projPath], [], {}); +- expect(manager.changeSubscriptions, hasLength(1)); +- expect(callbacks.currentContextRoots, hasLength(1)); +- // set empty roots - no contexts +- manager.setRoots([], [], {}); +- expect(manager.changeSubscriptions, hasLength(0)); +- expect(callbacks.currentContextRoots, hasLength(0)); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_removeFolderWithPackagespecFolder() { +- // prepare paths +- String projectA = '/projectA'; +- String projectB = '/projectB'; +- String subProjectA = '$projectA/sub'; +- String subProjectB = '$projectB/sub'; +- String projectA_file = '$projectA/a.dart'; +- String projectB_file = '$projectB/a.dart'; +- String subProjectA_pubspec = '$subProjectA/.packages'; +- String subProjectB_pubspec = '$subProjectB/.packages'; +- String subProjectA_file = '$subProjectA/bin/sub_a.dart'; +- String subProjectB_file = '$subProjectB/bin/sub_b.dart'; +- // create files +- resourceProvider.newFile(projectA_file, '// a'); +- resourceProvider.newFile(projectB_file, '// b'); +- resourceProvider.newFile(subProjectA_pubspec, ''); +- resourceProvider.newFile(subProjectB_pubspec, ''); +- resourceProvider.newFile(subProjectA_file, '// sub-a'); +- resourceProvider.newFile(subProjectB_file, '// sub-b'); +- // set roots +- manager +- .setRoots([projectA, projectB], [], {}); +- callbacks +- .assertContextPaths([projectA, subProjectA, projectB, subProjectB]); +- callbacks.assertContextFiles(projectA, [projectA_file]); +- callbacks.assertContextFiles(projectB, [projectB_file]); +- callbacks.assertContextFiles(subProjectA, [subProjectA_file]); +- callbacks.assertContextFiles(subProjectB, [subProjectB_file]); +- // remove "projectB" +- manager.setRoots([projectA], [], {}); +- callbacks.assertContextPaths([projectA, subProjectA]); +- callbacks.assertContextFiles(projectA, [projectA_file]); +- callbacks.assertContextFiles(subProjectA, [subProjectA_file]); +- } +- +- void test_setRoots_removeFolderWithPubspec() { +- // create a pubspec +- String pubspecPath = path.posix.join(projPath, 'pubspec.yaml'); +- resourceProvider.newFile(pubspecPath, 'pubspec'); +- // add one root - there is a context +- manager.setRoots([projPath], [], {}); +- expect(callbacks.currentContextRoots, hasLength(1)); +- // set empty roots - no contexts +- manager.setRoots([], [], {}); +- expect(callbacks.currentContextRoots, hasLength(0)); +- expect(callbacks.currentFilePaths, hasLength(0)); +- } +- +- void test_setRoots_removeFolderWithPubspecFolder() { +- // prepare paths +- String projectA = '/projectA'; +- String projectB = '/projectB'; +- String subProjectA = '$projectA/sub'; +- String subProjectB = '$projectB/sub'; +- String projectA_file = '$projectA/a.dart'; +- String projectB_file = '$projectB/a.dart'; +- String subProjectA_pubspec = '$subProjectA/pubspec.yaml'; +- String subProjectB_pubspec = '$subProjectB/pubspec.yaml'; +- String subProjectA_file = '$subProjectA/bin/sub_a.dart'; +- String subProjectB_file = '$subProjectB/bin/sub_b.dart'; +- // create files +- resourceProvider.newFile(projectA_file, '// a'); +- resourceProvider.newFile(projectB_file, '// b'); +- resourceProvider.newFile(subProjectA_pubspec, 'pubspec'); +- resourceProvider.newFile(subProjectB_pubspec, 'pubspec'); +- resourceProvider.newFile(subProjectA_file, '// sub-a'); +- resourceProvider.newFile(subProjectB_file, '// sub-b'); +- // set roots +- manager +- .setRoots([projectA, projectB], [], {}); +- callbacks +- .assertContextPaths([projectA, subProjectA, projectB, subProjectB]); +- callbacks.assertContextFiles(projectA, [projectA_file]); +- callbacks.assertContextFiles(projectB, [projectB_file]); +- callbacks.assertContextFiles(subProjectA, [subProjectA_file]); +- callbacks.assertContextFiles(subProjectB, [subProjectB_file]); +- // remove "projectB" +- manager.setRoots([projectA], [], {}); +- callbacks.assertContextPaths([projectA, subProjectA]); +- callbacks.assertContextFiles(projectA, [projectA_file]); +- callbacks.assertContextFiles(subProjectA, [subProjectA_file]); +- } +- +- void test_setRoots_removePackageRoot() { +- String packagePathFoo = '/package1/foo'; +- String packageRootPath = '/package2/foo'; +- Folder packageFolder = resourceProvider.newFolder(packagePathFoo); +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], +- 'foo:file:///package1/foo'); +- List includedPaths = [projPath]; +- List excludedPaths = []; +- manager.setRoots(includedPaths, excludedPaths, +- {projPath: packageRootPath}); +- _checkPackageRoot(projPath, equals(packageRootPath)); +- manager.setRoots(includedPaths, excludedPaths, {}); +- expect( +- _currentPackageMap, +- equals({ +- 'foo': [packageFolder] +- })); +- } +- +- void test_setRoots_rootPathContainsDotFile() { +- // If the path to the context root itself contains a folder whose name +- // begins with '.', then that is not sufficient to cause any files in the +- // context to be ignored. +- String project = '/.pub/project'; +- String fileA = '$project/foo.dart'; +- resourceProvider.newFile(fileA, ''); +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- } +- +- test_watch_addDummyLink() { +- manager.setRoots([projPath], [], {}); +- // empty folder initially +- expect(callbacks.currentFilePaths, isEmpty); +- // add link +- String filePath = path.posix.join(projPath, 'foo.dart'); +- resourceProvider.newDummyLink(filePath); +- // the link was ignored +- return pumpEventQueue().then((_) { +- expect(callbacks.currentFilePaths, isEmpty); +- }); +- } +- +- test_watch_addFile() { +- manager.setRoots([projPath], [], {}); +- // empty folder initially +- expect(callbacks.currentFilePaths, hasLength(0)); +- // add file +- String filePath = path.posix.join(projPath, 'foo.dart'); +- resourceProvider.newFile(filePath, 'contents'); +- // the file was added +- return pumpEventQueue().then((_) { +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- }); +- } +- +- test_watch_addFile_excluded() { +- // prepare paths +- String project = '/project'; +- String folderA = '$project/aaa'; +- String folderB = '$project/bbb'; +- String fileA = '$folderA/a.dart'; +- String fileB = '$folderB/b.dart'; +- // create files +- resourceProvider.newFile(fileA, 'library a;'); +- // set roots +- manager.setRoots([project], [folderB], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- // add a file, ignored as excluded +- resourceProvider.newFile(fileB, 'library b;'); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- }); +- } +- +- test_watch_addFile_inDocFolder_inner() { +- // prepare paths +- String project = '/project'; +- String fileA = '$project/a.dart'; +- String fileB = '$project/lib/doc/b.dart'; +- // create files +- resourceProvider.newFile(fileA, ''); +- // set roots +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- // add a "lib/doc" file, it is not ignored +- resourceProvider.newFile(fileB, ''); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA, fileB]); +- }); +- } +- +- test_watch_addFile_inDocFolder_topLevel() { +- // prepare paths +- String project = '/project'; +- String fileA = '$project/a.dart'; +- String fileB = '$project/doc/b.dart'; +- // create files +- resourceProvider.newFile(fileA, ''); +- // set roots +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- // add a "doc" file, it is ignored +- resourceProvider.newFile(fileB, ''); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- }); +- } +- +- test_watch_addFile_pathContainsDotFile() async { +- // If a file is added and the path to it (relative to the context root) +- // contains a folder whose name begins with '.', then the file is ignored. +- String project = '/project'; +- String fileA = '$project/foo.dart'; +- String fileB = '$project/.pub/bar.dart'; +- resourceProvider.newFile(fileA, ''); +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- resourceProvider.newFile(fileB, ''); +- await pumpEventQueue(); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- } +- +- test_watch_addFile_rootPathContainsDotFile() async { +- // If a file is added and the path to the context contains a folder whose +- // name begins with '.', then the file is not ignored. +- String project = '/.pub/project'; +- String fileA = '$project/foo.dart'; +- String fileB = '$project/bar/baz.dart'; +- resourceProvider.newFile(fileA, ''); +- manager.setRoots([project], [], {}); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA]); +- resourceProvider.newFile(fileB, ''); +- await pumpEventQueue(); +- callbacks.assertContextPaths([project]); +- callbacks.assertContextFiles(project, [fileA, fileB]); +- } +- +- test_watch_addFileInSubfolder() { +- manager.setRoots([projPath], [], {}); +- // empty folder initially +- expect(callbacks.currentFilePaths, hasLength(0)); +- // add file in subfolder +- String filePath = path.posix.join(projPath, 'foo', 'bar.dart'); +- resourceProvider.newFile(filePath, 'contents'); +- // the file was added +- return pumpEventQueue().then((_) { +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- }); +- } +- +- test_watch_addPackagespec_toRoot() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String rootPackagespec = '$root/.packages'; +- // create files +- resourceProvider.newFile(rootFile, 'library root;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- // add packagespec - still just one root +- resourceProvider.newFile(rootPackagespec, ''); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile]); +- // TODO(pquitslund): verify that a new source factory is created -- +- // likely this will need to happen in a corresponding ServerContextManagerTest. +- }); +- } +- +- test_watch_addPackagespec_toSubFolder() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub/aaa'; +- String subPubspec = '$subProject/.packages'; +- String subFile = '$subProject/bin/a.dart'; +- // create files +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subFile, 'library a;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile, subFile]); +- // add .packages +- resourceProvider.newFile(subPubspec, ''); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- }); +- } +- +- test_watch_addPackagespec_toSubFolder_ofSubFolder() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub'; +- String subPubspec = '$subProject/.packages'; +- String subFile = '$subProject/bin/sub.dart'; +- String subSubPubspec = '$subProject/subsub/.packages'; +- // create files +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subPubspec, ''); +- resourceProvider.newFile(subFile, 'library sub;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- // add pubspec - ignore, because is already in a packagespec-based context +- resourceProvider.newFile(subSubPubspec, ''); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- }); +- } +- +- test_watch_addPackagespec_toSubFolder_withPubspec() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub/aaa'; +- String subPackagespec = '$subProject/.packages'; +- String subPubspec = '$subProject/pubspec.yaml'; +- String subFile = '$subProject/bin/a.dart'; +- // create files +- resourceProvider.newFile(subPubspec, 'pubspec'); +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subFile, 'library a;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProject]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- +- // add .packages +- resourceProvider.newFile(subPackagespec, ''); +- return pumpEventQueue().then((_) { +- // Should NOT create another context. +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- }); +- } +- +- test_watch_addPubspec_toRoot() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String rootPubspec = '$root/pubspec.yaml'; +- // create files +- resourceProvider.newFile(rootFile, 'library root;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- // add pubspec - still just one root +- resourceProvider.newFile(rootPubspec, 'pubspec'); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile]); +- }); +- } +- +- test_watch_addPubspec_toSubFolder() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub/aaa'; +- String subPubspec = '$subProject/pubspec.yaml'; +- String subFile = '$subProject/bin/a.dart'; +- // create files +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subFile, 'library a;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile, subFile]); +- // add pubspec +- resourceProvider.newFile(subPubspec, 'pubspec'); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- }); +- } +- +- test_watch_addPubspec_toSubFolder_ofSubFolder() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub'; +- String subPubspec = '$subProject/pubspec.yaml'; +- String subFile = '$subProject/bin/sub.dart'; +- String subSubPubspec = '$subProject/subsub/pubspec.yaml'; +- // create files +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subPubspec, 'pubspec'); +- resourceProvider.newFile(subFile, 'library sub;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- // add pubspec - ignore, because is already in a pubspec-based context +- resourceProvider.newFile(subSubPubspec, 'pubspec'); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- }); +- } +- +- test_watch_deleteFile() { +- String filePath = path.posix.join(projPath, 'foo.dart'); +- // add root with a file +- File file = resourceProvider.newFile(filePath, 'contents'); +- Folder projFolder = file.parent; +- manager.setRoots([projPath], [], {}); +- // the file was added +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- expect(file.exists, isTrue); +- expect(projFolder.exists, isTrue); +- // delete the file +- resourceProvider.deleteFile(filePath); +- return pumpEventQueue().then((_) { +- expect(file.exists, isFalse); +- expect(projFolder.exists, isTrue); +- return expect(callbacks.currentFilePaths, hasLength(0)); +- }); +- } +- +- test_watch_deleteFolder() { +- String filePath = path.posix.join(projPath, 'foo.dart'); +- // add root with a file +- File file = resourceProvider.newFile(filePath, 'contents'); +- Folder projFolder = file.parent; +- manager.setRoots([projPath], [], {}); +- // the file was added +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- expect(file.exists, isTrue); +- expect(projFolder.exists, isTrue); +- // delete the folder +- resourceProvider.deleteFolder(projPath); +- return pumpEventQueue().then((_) { +- expect(file.exists, isFalse); +- expect(projFolder.exists, isFalse); +- return expect(callbacks.currentFilePaths, hasLength(0)); +- }); +- } +- +- test_watch_deletePackagespec_fromRoot() { +- // prepare paths +- String root = '/root'; +- String rootPubspec = '$root/.packages'; +- String rootFile = '$root/root.dart'; +- // create files +- resourceProvider.newFile(rootPubspec, ''); +- resourceProvider.newFile(rootFile, 'library root;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile]); +- // delete the pubspec +- resourceProvider.deleteFile(rootPubspec); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile]); +- }); +- } +- +- test_watch_deletePackagespec_fromSubFolder() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub/aaa'; +- String subPubspec = '$subProject/.packages'; +- String subFile = '$subProject/bin/a.dart'; +- // create files +- resourceProvider.newFile(subPubspec, ''); +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subFile, 'library a;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProject]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- // delete the pubspec +- resourceProvider.deleteFile(subPubspec); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile, subFile]); +- }); +- } +- +- test_watch_deletePackagespec_fromSubFolder_withPubspec() { +- // prepare paths: +- // +- // root +- // root.dart +- // sub +- // aaa +- // .packages +- // pubspec.yaml +- // bin +- // a.dart +- // +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub/aaa'; +- String subPackagespec = '$subProject/.packages'; +- String subPubspec = '$subProject/pubspec.yaml'; +- String subFile = '$subProject/bin/a.dart'; +- // create files +- resourceProvider.newFile(subPackagespec, ''); +- resourceProvider.newFile(subPubspec, 'pubspec'); +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subFile, 'library a;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProject]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- // delete the packagespec +- resourceProvider.deleteFile(subPackagespec); +- return pumpEventQueue().then((_) { +- // Should NOT merge +- callbacks.assertContextPaths([root, subProject]); +- callbacks.assertContextFiles(subProject, [subFile]); +- }); +- } +- +- test_watch_deletePubspec_fromRoot() { +- // prepare paths +- String root = '/root'; +- String rootPubspec = '$root/pubspec.yaml'; +- String rootFile = '$root/root.dart'; +- // create files +- resourceProvider.newFile(rootPubspec, 'pubspec'); +- resourceProvider.newFile(rootFile, 'library root;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile]); +- // delete the pubspec +- resourceProvider.deleteFile(rootPubspec); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile]); +- }); +- } +- +- test_watch_deletePubspec_fromSubFolder() { +- // prepare paths +- String root = '/root'; +- String rootFile = '$root/root.dart'; +- String subProject = '$root/sub/aaa'; +- String subPubspec = '$subProject/pubspec.yaml'; +- String subFile = '$subProject/bin/a.dart'; +- // create files +- resourceProvider.newFile(subPubspec, 'pubspec'); +- resourceProvider.newFile(rootFile, 'library root;'); +- resourceProvider.newFile(subFile, 'library a;'); +- // set roots +- manager.setRoots([root], [], {}); +- callbacks.assertContextPaths([root, subProject]); +- // verify files +- callbacks.assertContextFiles(root, [rootFile]); +- callbacks.assertContextFiles(subProject, [subFile]); +- // delete the pubspec +- resourceProvider.deleteFile(subPubspec); +- return pumpEventQueue().then((_) { +- callbacks.assertContextPaths([root]); +- callbacks.assertContextFiles(root, [rootFile, subFile]); +- }); +- } +- +- test_watch_modifyFile() { +- String filePath = path.posix.join(projPath, 'foo.dart'); +- // add root with a file +- resourceProvider.newFile(filePath, 'contents'); +- manager.setRoots([projPath], [], {}); +- // the file was added +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- // TODO(brianwilkerson) Test when the file was modified +- // update the file +- callbacks.now++; +- resourceProvider.modifyFile(filePath, 'new contents'); +- return pumpEventQueue().then((_) { +- // TODO(brianwilkerson) Test when the file was modified +- }); +- } +- +- test_watch_modifyPackageMapDependency_fail() async { +- // create a dependency file +- String dependencyPath = path.posix.join(projPath, 'dep'); +- resourceProvider.newFile(dependencyPath, 'contents'); +- packageMapProvider.dependencies.add(dependencyPath); +- // create a Dart file +- String dartFilePath = path.posix.join(projPath, 'main.dart'); +- resourceProvider.newFile(dartFilePath, 'contents'); +- // the created context has the expected empty package map +- manager.setRoots([projPath], [], {}); +- expect(_currentPackageMap, isEmpty); +- // Change the package map dependency so that the packageMapProvider is +- // re-run, and arrange for it to return null from computePackageMap(). +- packageMapProvider.packageMap = null; +- resourceProvider.modifyFile(dependencyPath, 'new contents'); +- await pumpEventQueue(); +- // The package map should have been changed to null. +- expect(_currentPackageMap, isEmpty); +- } +- +- test_watch_modifyPackagespec() { +- String packagesPath = '$projPath/.packages'; +- String filePath = '$projPath/bin/main.dart'; +- +- resourceProvider.newFile(packagesPath, ''); +- resourceProvider.newFile(filePath, 'library main;'); +- +- manager.setRoots([projPath], [], {}); +- +- Iterable filePaths = callbacks.currentFilePaths; +- expect(filePaths, hasLength(1)); +- expect(filePaths, contains(filePath)); +- expect(_currentPackageMap, isEmpty); +- +- // update .packages +- callbacks.now++; +- resourceProvider.modifyFile(packagesPath, 'main:./lib/'); +- return pumpEventQueue().then((_) { +- // verify new package info +- expect(_currentPackageMap.keys, unorderedEquals(['main'])); +- }); +- } +- +- /** +- * Verify that package URI's for source files in [path] will be resolved +- * using a package root matching [expectation]. +- */ +- void _checkPackageRoot(String path, expectation) { +- // TODO(brianwilkerson) Figure out how to test this. Possibly by comparing +- // the contents of the package map (although that approach doesn't work at +- // the moment). +-// FolderDisposition disposition = callbacks.currentContextDispositions[path]; +-// expect(disposition.packageRoot, expectation); +- // TODO(paulberry): we should also verify that the package map itself is +- // correct. See dartbug.com/23909. +- } +-} +- +-abstract class ContextManagerTest { +- /** +- * The name of the 'bin' directory. +- */ +- static const String BIN_NAME = 'bin'; +- +- /** +- * The name of the 'example' directory. +- */ +- static const String EXAMPLE_NAME = 'example'; +- +- /** +- * The name of the 'lib' directory. +- */ +- static const String LIB_NAME = 'lib'; +- +- /** +- * The name of the 'src' directory. +- */ +- static const String SRC_NAME = 'src'; +- +- /** +- * The name of the 'test' directory. +- */ +- static const String TEST_NAME = 'test'; +- +- ContextManagerImpl manager; +- +- TestContextManagerCallbacks callbacks; +- +- MemoryResourceProvider resourceProvider; +- +- MockPackageMapProvider packageMapProvider; +- +- UriResolver packageResolver = null; +- +- String projPath = '/my/proj'; +- +- AnalysisError missing_required_param = new AnalysisError( +- new TestSource(), 0, 1, HintCode.MISSING_REQUIRED_PARAM, [ +- ['x'] +- ]); +- +- AnalysisError missing_return = +- new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [ +- ['x'] +- ]); +- +- AnalysisError invalid_assignment_error = +- new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [ +- ['x'], +- ['y'] +- ]); +- +- AnalysisError unused_local_variable = new AnalysisError( +- new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [ +- ['x'] +- ]); +- +- List get analysisFilesGlobs { +- List patterns = [ +- '**/*.${AnalysisEngine.SUFFIX_DART}', +- '**/*.${AnalysisEngine.SUFFIX_HTML}', +- '**/*.${AnalysisEngine.SUFFIX_HTM}', +- '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}', +- '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}' +- ]; +- return patterns +- .map((pattern) => new Glob(path.posix.separator, pattern)) +- .toList(); +- } +- +- AnalysisOptions get analysisOptions => callbacks.analysisOptions; +- +- List get errorProcessors => analysisOptions.errorProcessors; +- +- List get lints => analysisOptions.lintRules; +- +- SourceFactory get sourceFactory => callbacks.sourceFactory; +- +- Map> get _currentPackageMap => _packageMap(projPath); +- +- void deleteFile(List pathComponents) { +- String filePath = path.posix.joinAll(pathComponents); +- resourceProvider.deleteFile(filePath); +- } +- +- /** +- * TODO(brianwilkerson) This doesn't add the strong mode processor when using +- * the new analysis driver. +- */ +- ErrorProcessor getProcessor(AnalysisError error) => errorProcessors +- .firstWhere((ErrorProcessor p) => p.appliesTo(error), orElse: () => null); +- +- String newFile(List pathComponents, [String content = '']) { +- String filePath = path.posix.joinAll(pathComponents); +- resourceProvider.newFile(filePath, content); +- return filePath; +- } +- +- String newFileFromBytes(List pathComponents, List bytes) { +- String filePath = path.posix.joinAll(pathComponents); +- resourceProvider.newFileWithBytes(filePath, bytes); +- return filePath; +- } +- +- String newFolder(List pathComponents) { +- String folderPath = path.posix.joinAll(pathComponents); +- resourceProvider.newFolder(folderPath); +- return folderPath; +- } +- +- void processRequiredPlugins() { +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- +- registerLintRules(); +- } +- +- UriResolver providePackageResolver(Folder folder) => packageResolver; +- +- void setUp() { +- processRequiredPlugins(); +- resourceProvider = new MemoryResourceProvider(); +- resourceProvider.newFolder(projPath); +- packageMapProvider = new MockPackageMapProvider(); +- // Create an SDK in the mock file system. +- new MockSdk(generateSummaryFiles: true, resourceProvider: resourceProvider); +- DartSdkManager sdkManager = new DartSdkManager('/', true); +- manager = new ContextManagerImpl( +- resourceProvider, +- sdkManager, +- providePackageResolver, +- packageMapProvider, +- analysisFilesGlobs, +- InstrumentationService.NULL_SERVICE, +- new AnalysisOptionsImpl()); +- PerformanceLog logger = new PerformanceLog(new NullStringSink()); +- AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger); +- callbacks = new TestContextManagerCallbacks( +- resourceProvider, sdkManager, logger, scheduler); +- manager.callbacks = callbacks; +- } +- +- /** +- * Verify that package URI's for source files in [path] will be resolved +- * using a package root matching [expectation]. +- */ +- void _checkPackageRoot(String path, expectation) { +- // TODO(brianwilkerson) Figure out how to test this. Possibly by comparing +- // the contents of the package map (although that approach doesn't work at +- // the moment). +-// FolderDisposition disposition = callbacks.currentContextDispositions[path]; +-// expect(disposition.packageRoot, expectation); +- // TODO(paulberry): we should also verify that the package map itself is +- // correct. See dartbug.com/23909. +- } +- +- Map> _packageMap(String contextPath) { +- Folder folder = resourceProvider.getFolder(contextPath); +- ContextInfo info = manager.getContextInfoFor(folder); +- return info.analysisDriver.sourceFactory?.packageMap; +- } +-} +- +-@reflectiveTest +-class ContextManagerWithNewOptionsTest extends ContextManagerWithOptionsTest { +- String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE; +-} +- +-@reflectiveTest +-class ContextManagerWithOldOptionsTest extends ContextManagerWithOptionsTest { +- String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_FILE; +-} +- +-abstract class ContextManagerWithOptionsTest extends ContextManagerTest { +- String get optionsFileName; +- +- test_analysis_options_file_delete() async { +- // Setup analysis options +- newFile([projPath, optionsFileName], r''' +-embedded_libs: +- "dart:foobar": "../sdk_ext/entry.dart" +-analyzer: +- language: +- enableStrictCallChecks: true +- errors: +- unused_local_variable: false +-linter: +- rules: +- - camel_case_types +-'''); +- +- // Setup context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- +- // Verify options were set. +- expect(errorProcessors, hasLength(1)); +- expect(lints, hasLength(1)); +- expect(analysisOptions.enableStrictCallChecks, isTrue); +- +- // Remove options. +- deleteFile([projPath, optionsFileName]); +- await pumpEventQueue(); +- +- // Verify defaults restored. +- expect(errorProcessors, isEmpty); +- expect(lints, isEmpty); +- expect(analysisOptions.enableStrictCallChecks, isFalse); +- } +- +- @failingTest +- test_analysis_options_file_delete_with_embedder() async { +- // This fails because the ContextBuilder doesn't pick up the strongMode +- // flag from the embedder.yaml file. +- // Setup _embedder.yaml. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, '_embedder.yaml'], r''' +-analyzer: +- strong-mode: true +- errors: +- missing_return: false +-linter: +- rules: +- - avoid_as +-'''); +- +- // Setup .packages file +- newFile([projPath, '.packages'], r''' +-test_pack:lib/'''); +- +- // Setup analysis options +- newFile([projPath, optionsFileName], r''' +-analyzer: +- language: +- enableStrictCallChecks: true +- errors: +- unused_local_variable: false +-linter: +- rules: +- - camel_case_types +-'''); +- +- // Setup context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- +- // Verify options were set. +- expect(analysisOptions.enableStrictCallChecks, isTrue); +- expect(analysisOptions.strongMode, isTrue); +- expect(errorProcessors, hasLength(2)); +- expect(lints, hasLength(2)); +- +- // Remove options. +- deleteFile([projPath, optionsFileName]); +- await pumpEventQueue(); +- +- // Verify defaults restored. +- expect(analysisOptions.enableStrictCallChecks, isFalse); +- expect(lints, hasLength(1)); +- expect(lints.first, new isInstanceOf()); +- expect(errorProcessors, hasLength(1)); +- expect(getProcessor(missing_return).severity, isNull); +- } +- +- test_analysis_options_include() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Setup analysis options file which includes another options file. +- newFile([projPath, optionsFileName], r''' +-include: other_options.yaml +-'''); +- newFile([projPath, 'other_options.yaml'], r''' +-analyzer: +- language: +- enableStrictCallChecks: true +- errors: +- unused_local_variable: false +-linter: +- rules: +- - camel_case_types +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- // Verify options were set. +- expect(analysisOptions.enableStrictCallChecks, isTrue); +- expect(errorProcessors, hasLength(1)); +- expect(lints, hasLength(1)); +- expect(lints[0].name, 'camel_case_types'); +- } +- +- test_analysis_options_include_package() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Setup package +- String booLibPosixPath = '/my/pkg/boo/lib'; +- newFile([booLibPosixPath, 'other_options.yaml'], r''' +-analyzer: +- language: +- enableStrictCallChecks: true +- errors: +- unused_local_variable: false +-linter: +- rules: +- - camel_case_types +-'''); +- // Setup analysis options file which includes another options file. +- newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], +- 'boo:$booLibPosixPath\n'); +- newFile([projPath, optionsFileName], r''' +-include: package:boo/other_options.yaml +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- // Verify options were set. +- expect(analysisOptions.enableStrictCallChecks, isTrue); +- expect(errorProcessors, hasLength(1)); +- expect(lints, hasLength(1)); +- expect(lints[0].name, 'camel_case_types'); +- } +- +- test_analysis_options_parse_failure() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Setup analysis options file with ignore list. +- String optionsFilePath = newFile([projPath, optionsFileName], r''' +-; +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Check that an error was produced. +- TestNotificationManager notificationManager = callbacks.notificationManager; +- var errors = notificationManager.recordedErrors; +- expect(errors, hasLength(1)); +- expect(errors[errors.keys.first][optionsFilePath], hasLength(1)); +- } +- +- test_deleteRoot_hasAnalysisOptions() async { +- newFile([projPath, optionsFileName], ''); +- +- // Add the root. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- +- // Remove the root, with the analysis options file. +- // No exceptions. +- resourceProvider.deleteFolder(projPath); +- await pumpEventQueue(); +- } +- +- @failingTest +- test_embedder_options() async { +- // This fails because the ContextBuilder doesn't pick up the strongMode +- // flag from the embedder.yaml file. +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([projPath, 'test', 'test.dart']); +- newFile([sdkExtPath, 'entry.dart']); +- List bytes = new SummaryBuilder([], null, true).build(); +- newFileFromBytes([projPath, 'sdk.ds'], bytes); +- // Setup _embedder.yaml. +- newFile([libPath, '_embedder.yaml'], r''' +-embedded_libs: +- "dart:foobar": "../sdk_ext/entry.dart" +-analyzer: +- strong-mode: true +- language: +- enableSuperMixins: true +- errors: +- missing_return: false +-linter: +- rules: +- - avoid_as +-'''); +- // Setup .packages file +- newFile([projPath, '.packages'], r''' +-test_pack:lib/'''); +- +- // Setup analysis options +- newFile([projPath, optionsFileName], r''' +-analyzer: +- exclude: +- - 'test/**' +- language: +- enableStrictCallChecks: true +- errors: +- unused_local_variable: false +-linter: +- rules: +- - camel_case_types +-'''); +- +- // Setup context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- +- // Confirm that one context was created. +- int count = manager +- .numberOfContextsInAnalysisRoot(resourceProvider.newFolder(projPath)); +- expect(count, equals(1)); +- +- // Verify options. +- // * from `_embedder.yaml`: +- expect(analysisOptions.strongMode, isTrue); +- expect(analysisOptions.enableSuperMixins, isTrue); +- // * from analysis options: +- expect(analysisOptions.enableStrictCallChecks, isTrue); +- +- // * verify tests are excluded +- expect( +- callbacks.currentContextFilePaths[projPath].keys, +- unorderedEquals( +- ['/my/proj/sdk_ext/entry.dart', '/my/proj/$optionsFileName'])); +- +- // Verify filter setup. +- expect(errorProcessors, hasLength(2)); +- +- // * (embedder.) +- expect(getProcessor(missing_return).severity, isNull); +- +- // * (options.) +- expect(getProcessor(unused_local_variable).severity, isNull); +- +- // Verify lints. +- var lintNames = lints.map((lint) => lint.name); +- +- expect( +- lintNames, +- unorderedEquals( +- ['avoid_as' /* embedder */, 'camel_case_types' /* options */])); +- +- // Sanity check embedder libs. +- var source = sourceFactory.forUri('dart:foobar'); +- expect(source, isNotNull); +- expect(source.fullName, '/my/proj/sdk_ext/entry.dart'); +- } +- +- test_error_filter_analysis_option() async { +- // Create files. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- errors: +- unused_local_variable: ignore +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Verify filter setup. +- expect(errorProcessors, hasLength(1)); +- expect(getProcessor(unused_local_variable).severity, isNull); +- } +- +- test_error_filter_analysis_option_multiple_filters() async { +- // Create files. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- errors: +- invalid_assignment: ignore +- unused_local_variable: error +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Verify filter setup. +- expect(errorProcessors, hasLength(2)); +- +- expect(getProcessor(invalid_assignment_error).severity, isNull); +- expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR); +- } +- +- test_error_filter_analysis_option_synonyms() async { +- // Create files. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- errors: +- unused_local_variable: ignore +- ambiguous_import: false +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Verify filter setup. +- expect(errorProcessors, isNotNull); +- expect(errorProcessors, hasLength(2)); +- } +- +- test_error_filter_analysis_option_unpsecified() async { +- // Create files. +- newFile([projPath, optionsFileName], r''' +-analyzer: +-# errors: +-# unused_local_variable: ignore +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Verify filter setup. +- expect(errorProcessors, isEmpty); +- } +- +- @failingTest +- test_optionsFile_update_strongMode() async { +- // It appears that this fails because we are not correctly updating the +- // analysis options in the driver when the file is modified. +- //return super.test_optionsFile_update_strongMode(); +- // After a few other changes, the test now times out on my machine, so I'm +- // disabling it in order to prevent it from being flaky. +- fail('Test times out'); +- var file = resourceProvider.newFile('$projPath/bin/test.dart', r''' +-main() { +- var paths = []; +- var names = []; +- paths.addAll(names.map((s) => s.length)); +-} +-'''); +- resourceProvider.newFile('$projPath/$optionsFileName', r''' +-analyzer: +- strong-mode: false +-'''); +- // Create the context. +- manager.setRoots([projPath], [], {}); +- await pumpEventQueue(); +- +- AnalysisResult result = await callbacks.currentDriver.getResult(file.path); +- +- // Not strong mode - both in the context and the SDK context. +- AnalysisContext sdkContext = sourceFactory.dartSdk.context; +- expect(analysisOptions.strongMode, isFalse); +- expect(sdkContext.analysisOptions.strongMode, isFalse); +- expect(result.errors, isEmpty); +- +- // Update the options file - turn on 'strong-mode'. +- resourceProvider.updateFile('$projPath/$optionsFileName', r''' +-analyzer: +- strong-mode: true +-'''); +- await pumpEventQueue(); +- +- // Strong mode - both in the context and the SDK context. +- result = await callbacks.currentDriver.getResult(file.path); +- +- // Not strong mode - both in the context and the SDK context. +- sdkContext = sourceFactory.dartSdk.context; +- expect(analysisOptions.strongMode, isTrue); +- expect(sdkContext.analysisOptions.strongMode, isTrue); +- // The code is strong-mode clean. +- // Verify that TypeSystem was reset. +- expect(result.errors, isEmpty); +- } +- +- @failingTest +- test_path_filter_analysis_option() async { +- // This fails because we're not analyzing the analysis options file. +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'nope.dart']); +- String sdkExtPath = newFolder([projPath, 'sdk_ext']); +- newFile([sdkExtPath, 'entry.dart']); +- String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']); +- newFile([sdkExtSrcPath, 'part.dart']); +- // Setup analysis options file with ignore list. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- exclude: +- - lib/nope.dart +- - 'sdk_ext/**' +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Verify that analysis options was parsed and the ignore patterns applied. +- Folder projectFolder = resourceProvider.newFolder(projPath); +- var drivers = manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, hasLength(1)); +- AnalysisDriver driver = drivers[0]; +- expect( +- driver.addedFiles, +- unorderedEquals( +- ['/my/proj/lib/main.dart', '/my/proj/$optionsFileName'])); +- } +- +- test_path_filter_child_contexts_option() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'pubspec.yaml'], r''' +-name: foobar +-'''); +- String otherLibPath = newFolder([projPath, 'other_lib']); +- newFile([otherLibPath, 'entry.dart']); +- newFile([otherLibPath, 'pubspec.yaml'], r''' +-name: other_lib +-'''); +- // Setup analysis options file with ignore list that ignores the 'other_lib' +- // directory by name. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- exclude: +- - 'other_lib' +-'''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- // Verify that the context in other_lib wasn't created and that the +- // context in lib was created. +- Folder projectFolder = resourceProvider.newFolder(projPath); +- var drivers = manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, hasLength(2)); +- expect(drivers[0].name, equals('/my/proj')); +- expect(drivers[1].name, equals('/my/proj/lib')); +- } +- +- test_path_filter_recursive_wildcard_child_contexts_option() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'pubspec.yaml'], r''' +- name: foobar +- '''); +- String otherLibPath = newFolder([projPath, 'other_lib']); +- newFile([otherLibPath, 'entry.dart']); +- newFile([otherLibPath, 'pubspec.yaml'], r''' +- name: other_lib +- '''); +- // Setup analysis options file with ignore list that ignores 'other_lib' +- // and all descendants. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- exclude: +- - 'other_lib/**' +- '''); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- +- // Verify that the context in other_lib wasn't created and that the +- // context in lib was created. +- Folder projectFolder = resourceProvider.newFolder(projPath); +- var drivers = manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, hasLength(2)); +- expect(drivers[0].name, equals('/my/proj')); +- expect(drivers[1].name, equals('/my/proj/lib')); +- } +- +- test_path_filter_wildcard_child_contexts_option() async { +- // Create files. +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- newFile([libPath, 'pubspec.yaml'], r''' +-name: foobar +-'''); +- String otherLibPath = newFolder([projPath, 'other_lib']); +- newFile([otherLibPath, 'entry.dart']); +- newFile([otherLibPath, 'pubspec.yaml'], r''' +-name: other_lib +-'''); +- // Setup analysis options file with ignore list that ignores 'other_lib' +- // and all immediate children. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- exclude: +- - 'other_lib/*' +-'''); +- // Setup context / driver. +- manager.setRoots([projPath], [], {}); +- +- Folder projectFolder = resourceProvider.newFolder(projPath); +- var drivers = manager.getDriversInAnalysisRoot(projectFolder); +- expect(drivers, hasLength(2)); +- expect(drivers[0].name, equals('/my/proj')); +- expect(drivers[1].name, equals('/my/proj/lib')); +- } +- +- void test_setRoots_nested_excludedByOuter() { +- String project = '/project'; +- String projectPubspec = '$project/pubspec.yaml'; +- String example = '$project/example'; +- String examplePubspec = '$example/pubspec.yaml'; +- // create files +- resourceProvider.newFile(projectPubspec, 'name: project'); +- resourceProvider.newFile(examplePubspec, 'name: example'); +- newFile([project, optionsFileName], r''' +-analyzer: +- exclude: +- - 'example' +-'''); +- manager +- .setRoots([project, example], [], {}); +- // verify +- { +- ContextInfo rootInfo = manager.rootInfo; +- expect(rootInfo.children, hasLength(1)); +- { +- ContextInfo projectInfo = rootInfo.children[0]; +- expect(projectInfo.folder.path, project); +- expect(projectInfo.children, hasLength(1)); +- { +- ContextInfo exampleInfo = projectInfo.children[0]; +- expect(exampleInfo.folder.path, example); +- expect(exampleInfo.children, isEmpty); +- } +- } +- } +- expect(callbacks.currentContextRoots, hasLength(2)); +- expect(callbacks.currentContextRoots, unorderedEquals([project, example])); +- } +- +- void test_setRoots_nested_excludedByOuter_deep() { +- String a = '/a'; +- String c = '$a/b/c'; +- String aPubspec = '$a/pubspec.yaml'; +- String cPubspec = '$c/pubspec.yaml'; +- // create files +- resourceProvider.newFile(aPubspec, 'name: aaa'); +- resourceProvider.newFile(cPubspec, 'name: ccc'); +- newFile([a, optionsFileName], r''' +-analyzer: +- exclude: +- - 'b**' +-'''); +- manager.setRoots([a, c], [], {}); +- // verify +- { +- ContextInfo rootInfo = manager.rootInfo; +- expect(rootInfo.children, hasLength(1)); +- { +- ContextInfo aInfo = rootInfo.children[0]; +- expect(aInfo.folder.path, a); +- expect(aInfo.children, hasLength(1)); +- { +- ContextInfo cInfo = aInfo.children[0]; +- expect(cInfo.folder.path, c); +- expect(cInfo.children, isEmpty); +- } +- } +- } +- expect(callbacks.currentContextRoots, hasLength(2)); +- expect(callbacks.currentContextRoots, unorderedEquals([a, c])); +- } +- +- test_strong_mode_analysis_option() async { +- // Create files. +- newFile([projPath, optionsFileName], r''' +-analyzer: +- strong-mode: true +-'''); +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- newFile([libPath, 'main.dart']); +- // Setup context. +- manager.setRoots([projPath], [], {}); +- // Verify that analysis options was parsed and strong-mode set. +- expect(analysisOptions.strongMode, true); +- } +- +- test_watchEvents() async { +- String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]); +- manager.setRoots([projPath], [], {}); +- newFile([libPath, 'main.dart']); +- await new Future.delayed(new Duration(milliseconds: 1)); +- expect(callbacks.watchEvents, hasLength(1)); +- } +-} +- +-class TestContextManagerCallbacks extends ContextManagerCallbacks { +- /** +- * Source of timestamps stored in [currentContextFilePaths]. +- */ +- int now = 0; +- +- /** +- * The analysis driver that was created. +- */ +- AnalysisDriver currentDriver; +- +- /** +- * A table mapping paths to the analysis driver associated with that path. +- */ +- Map driverMap = {}; +- +- /** +- * Map from context to the timestamp when the context was created. +- */ +- Map currentContextTimestamps = {}; +- +- /** +- * Map from context to (map from file path to timestamp of last event). +- */ +- final Map> currentContextFilePaths = +- >{}; +- +- /** +- * A map from the paths of contexts to a set of the sources that should be +- * explicitly analyzed in those contexts. +- */ +- final Map> currentContextSources = +- >{}; +- +- /** +- * Resource provider used for this test. +- */ +- final ResourceProvider resourceProvider; +- +- /** +- * The manager managing the SDKs. +- */ +- final DartSdkManager sdkManager; +- +- /** +- * The logger used by the scheduler and the driver. +- */ +- final PerformanceLog logger; +- +- /** +- * The scheduler used by the driver. +- */ +- final AnalysisDriverScheduler scheduler; +- +- /** +- * The list of `flushedFiles` in the last [removeContext] invocation. +- */ +- List lastFlushedFiles; +- +- /** +- * The watch events that have been broadcast. +- */ +- List watchEvents = []; +- +- @override +- NotificationManager notificationManager = new TestNotificationManager(); +- +- TestContextManagerCallbacks( +- this.resourceProvider, this.sdkManager, this.logger, this.scheduler); +- +- /** +- * Return the current set of analysis options. +- */ +- AnalysisOptions get analysisOptions => currentDriver?.analysisOptions; +- +- /** +- * Return the paths to the context roots that currently exist. +- */ +- Iterable get currentContextRoots { +- return currentContextTimestamps.keys; +- } +- +- /** +- * Return the paths to the files being analyzed in the current context root. +- */ +- Iterable get currentFilePaths { +- if (currentDriver == null) { +- return []; +- } +- return currentDriver.addedFiles; +- } +- +- /** +- * Return the current source factory. +- */ +- SourceFactory get sourceFactory => currentDriver?.sourceFactory; +- +- @override +- AnalysisDriver addAnalysisDriver( +- Folder folder, ContextRoot contextRoot, AnalysisOptions options) { +- String path = folder.path; +- expect(currentContextRoots, isNot(contains(path))); +- expect(contextRoot, isNotNull); +- expect(contextRoot.root, path); +- currentContextTimestamps[path] = now; +- +- ContextBuilder builder = +- createContextBuilder(folder, options, useSummaries: true); +- AnalysisContext context = builder.buildContext(folder.path); +- SourceFactory sourceFactory = context.sourceFactory; +- AnalysisOptions analysisOptions = context.analysisOptions; +- context.dispose(); +- +- currentDriver = new AnalysisDriver( +- scheduler, +- logger, +- resourceProvider, +- new MemoryByteStore(), +- new FileContentOverlay(), +- contextRoot, +- sourceFactory, +- analysisOptions); +- driverMap[path] = currentDriver; +- currentDriver.exceptions.listen((ExceptionResult result) { +- AnalysisEngine.instance.logger +- .logError('Analysis failed: ${result.path}', result.exception); +- }); +- return currentDriver; +- } +- +- @override +- void afterWatchEvent(WatchEvent event) {} +- +- @override +- void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { +- AnalysisDriver driver = driverMap[contextFolder.path]; +- if (driver != null) { +- changeSet.addedSources.forEach((source) { +- driver.addFile(source.fullName); +- }); +- changeSet.changedSources.forEach((source) { +- driver.changeFile(source.fullName); +- }); +- changeSet.removedSources.forEach((source) { +- driver.removeFile(source.fullName); +- }); +- } +- } +- +- @override +- void applyFileRemoved(AnalysisDriver driver, String file) { +- driver.removeFile(file); +- } +- +- void assertContextFiles(String contextPath, List expectedFiles) { +- expect(getCurrentFilePaths(contextPath), unorderedEquals(expectedFiles)); +- } +- +- void assertContextPaths(List expected) { +- expect(currentContextRoots, unorderedEquals(expected)); +- } +- +- @override +- void broadcastWatchEvent(WatchEvent event) { +- watchEvents.add(event); +- } +- +- @override +- void computingPackageMap(bool computing) { +- // Do nothing. +- } +- +- @override +- ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options, +- {bool useSummaries = false}) { +- ContextBuilderOptions builderOptions = new ContextBuilderOptions(); +- builderOptions.defaultOptions = options; +- ContextBuilder builder = new ContextBuilder( +- resourceProvider, sdkManager, new ContentCache(), +- options: builderOptions); +- return builder; +- } +- +- /** +- * Return the paths to the files being analyzed in the current context root. +- */ +- Iterable currentFileSources(String contextPath) { +- if (currentDriver == null) { +- return []; +- } +- AnalysisDriver driver = driverMap[contextPath]; +- SourceFactory sourceFactory = driver.sourceFactory; +- return driver.addedFiles.map((String path) { +- File file = resourceProvider.getFile(path); +- Source source = file.createSource(); +- Uri uri = sourceFactory.restoreUri(source); +- return file.createSource(uri); +- }); +- } +- +- /** +- * Return the paths to the files being analyzed in the current context root. +- */ +- Iterable getCurrentFilePaths(String contextPath) { +- if (currentDriver == null) { +- return []; +- } +- return driverMap[contextPath].addedFiles; +- } +- +- @override +- void moveContext(Folder from, Folder to) { +- String path = from.path; +- String path2 = to.path; +- expect(currentContextFilePaths, contains(path)); +- expect(currentContextTimestamps, contains(path)); +- expect(currentContextSources, contains(path)); +- expect(currentContextFilePaths, isNot(contains(path2))); +- expect(currentContextTimestamps, isNot(contains(path2))); +- expect(currentContextSources, isNot(contains(path2))); +- currentContextFilePaths[path2] = currentContextFilePaths.remove(path); +- currentContextTimestamps[path2] = currentContextTimestamps.remove(path); +- currentContextSources[path2] = currentContextSources.remove(path); +- } +- +- @override +- void removeContext(Folder folder, List flushedFiles) { +- String path = folder.path; +- expect(currentContextRoots, contains(path)); +- currentContextTimestamps.remove(path); +- currentContextFilePaths.remove(path); +- currentContextSources.remove(path); +- lastFlushedFiles = flushedFiles; +- } +-} +- +-/** +- * A [Source] that knows it's [fullName]. +- */ +-class TestSource implements Source { +- TestSource(); +- +- @override +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +-} +- +-class TestUriResolver extends UriResolver { +- Map uriMap; +- +- TestUriResolver(this.uriMap); +- +- @override +- Source resolveAbsolute(Uri uri, [Uri actualUri]) { +- return uriMap[uri]; +- } +-} +diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart +deleted file mode 100644 +index 334e7f98191..00000000000 +--- a/pkg/analysis_server/test/domain_analysis_test.dart ++++ /dev/null +@@ -1,790 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/domain_analysis.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:plugin/manager.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'analysis_abstract.dart'; +-import 'mock_sdk.dart'; +-import 'mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisDomainTest); +- defineReflectiveTests(SetSubscriptionsTest); +- }); +- +- MockServerChannel serverChannel; +- MemoryResourceProvider resourceProvider; +- AnalysisServer server; +- AnalysisDomainHandler handler; +- +- void processRequiredPlugins() { +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- } +- +- setUp(() { +- serverChannel = new MockServerChannel(); +- resourceProvider = new MemoryResourceProvider(); +- processRequiredPlugins(); +- // Create an SDK in the mock file system. +- new MockSdk(resourceProvider: resourceProvider); +- server = new AnalysisServer( +- serverChannel, +- resourceProvider, +- new MockPackageMapProvider(), +- new AnalysisServerOptions(), +- new DartSdkManager('/', false), +- InstrumentationService.NULL_SERVICE); +- handler = new AnalysisDomainHandler(server); +- }); +- +- group('updateContent', testUpdateContent); +- +- group('AnalysisDomainHandler', () { +- // TODO(brianwilkerson) Re-enable these tests if we re-enable the +- // analysis.getReachableSources request. +-// group('getReachableSources', () { +-// test('valid sources', () async { +-// String fileA = '/project/a.dart'; +-// String fileB = '/project/b.dart'; +-// resourceProvider.newFile(fileA, 'import "b.dart";'); +-// resourceProvider.newFile(fileB, ''); +-// +-// server.setAnalysisRoots('0', ['/project/'], [], {}); +-// +-// await server.onAnalysisComplete; +-// +-// var request = +-// new AnalysisGetReachableSourcesParams(fileA).toRequest('0'); +-// var response = handler.handleRequest(request); +-// +-// Map json = response.toJson()[Response.RESULT]; +-// +-// // Sanity checks. +-// expect(json['sources'], hasLength(6)); +-// expect(json['sources']['file:///project/a.dart'], +-// unorderedEquals(['dart:core', 'file:///project/b.dart'])); +-// expect(json['sources']['file:///project/b.dart'], ['dart:core']); +-// }); +-// +-// test('invalid source', () async { +-// resourceProvider.newFile('/project/a.dart', 'import "b.dart";'); +-// server.setAnalysisRoots('0', ['/project/'], [], {}); +-// +-// await server.onAnalysisComplete; +-// +-// var request = +-// new AnalysisGetReachableSourcesParams('/does/not/exist.dart') +-// .toRequest('0'); +-// var response = handler.handleRequest(request); +-// expect(response.error, isNotNull); +-// expect(response.error.code, +-// RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE); +-// }); +-// }); +- +- group('setAnalysisRoots', () { +- Response testSetAnalysisRoots( +- List included, List excluded) { +- Request request = new AnalysisSetAnalysisRootsParams(included, excluded) +- .toRequest('0'); +- return handler.handleRequest(request); +- } +- +- group('excluded', () { +- test('excluded folder', () async { +- String fileA = '/project/aaa/a.dart'; +- String fileB = '/project/bbb/b.dart'; +- resourceProvider.newFile(fileA, '// a'); +- resourceProvider.newFile(fileB, '// b'); +- var response = testSetAnalysisRoots(['/project'], ['/project/bbb']); +- expect(response, isResponseSuccess('0')); +- }); +- +- test('not absolute', () async { +- var response = testSetAnalysisRoots([], ['foo/bar']); +- expect( +- response, +- isResponseFailure( +- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT)); +- }); +- +- test('not normalized', () async { +- var response = testSetAnalysisRoots([], ['/foo/../bar']); +- expect( +- response, +- isResponseFailure( +- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT)); +- }); +- }); +- +- group('included', () { +- test('new folder', () async { +- String file = '/project/bin/test.dart'; +- resourceProvider.newFile('/project/pubspec.yaml', 'name: project'); +- resourceProvider.newFile(file, 'main() {}'); +- var response = testSetAnalysisRoots(['/project'], []); +- var serverRef = server; +- expect(response, isResponseSuccess('0')); +- // verify that unit is resolved eventually +- await server.onAnalysisComplete; +- var unit = await serverRef.getResolvedCompilationUnit(file); +- expect(unit, isNotNull); +- }); +- +- test('nonexistent folder', () async { +- String fileB = '/project_b/b.dart'; +- resourceProvider.newFile(fileB, '// b'); +- var response = testSetAnalysisRoots(['/project_a', '/project_b'], []); +- var serverRef = server; +- expect(response, isResponseSuccess('0')); +- // Non-existence of /project_a should not prevent files in /project_b +- // from being analyzed. +- await server.onAnalysisComplete; +- var unit = await serverRef.getResolvedCompilationUnit(fileB); +- expect(unit, isNotNull); +- }); +- +- test('not absolute', () async { +- var response = testSetAnalysisRoots(['foo/bar'], []); +- expect( +- response, +- isResponseFailure( +- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT)); +- }); +- +- test('not normalized', () async { +- var response = testSetAnalysisRoots(['/foo/../bar'], []); +- expect( +- response, +- isResponseFailure( +- '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT)); +- }); +- }); +- }); +- +- group('setPriorityFiles', () { +- test('invalid', () { +- var request = new AnalysisSetPriorityFilesParams(['/project/lib.dart']) +- .toRequest('0'); +- var response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- }); +- +- test('valid', () { +- resourceProvider.newFolder('/p1'); +- resourceProvider.newFile('/p1/a.dart', 'library a;'); +- resourceProvider.newFolder('/p2'); +- resourceProvider.newFile('/p2/b.dart', 'library b;'); +- resourceProvider.newFile('/p2/c.dart', 'library c;'); +- +- var setRootsRequest = +- new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], []) +- .toRequest('0'); +- var setRootsResponse = handler.handleRequest(setRootsRequest); +- expect(setRootsResponse, isResponseSuccess('0')); +- +- void setPriorityFiles(List fileList) { +- var request = +- new AnalysisSetPriorityFilesParams(fileList).toRequest('0'); +- var response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- // TODO(brianwilkerson) Enable the line below after getPriorityFiles +- // has been implemented. +- // expect(server.getPriorityFiles(), unorderedEquals(fileList)); +- } +- +- setPriorityFiles(['/p1/a.dart', '/p2/b.dart']); +- setPriorityFiles(['/p2/b.dart', '/p2/c.dart']); +- setPriorityFiles([]); +- }); +- }); +- +- group('updateOptions', () { +- test('invalid', () { +- var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, { +- ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: {'not-an-option': true} +- }); +- var response = handler.handleRequest(request); +- // Invalid options should be silently ignored. +- expect(response, isResponseSuccess('0')); +- }); +- +- test('null', () { +- // null is allowed as a synonym for {}. +- var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, +- {ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: null}); +- var response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- }); +- }); +- }); +-} +- +-testUpdateContent() { +- test('bad type', () { +- AnalysisTestHelper helper = new AnalysisTestHelper(); +- helper.createSingleFileProject('// empty'); +- return helper.onAnalysisComplete.then((_) { +- Request request = new Request('0', ANALYSIS_REQUEST_UPDATE_CONTENT, { +- ANALYSIS_REQUEST_UPDATE_CONTENT_FILES: { +- helper.testFile: { +- 'type': 'foo', +- } +- } +- }); +- Response response = helper.handler.handleRequest(request); +- expect(response, isResponseFailure('0')); +- }); +- }); +- +- test('full content', () { +- AnalysisTestHelper helper = new AnalysisTestHelper(); +- helper.createSingleFileProject('// empty'); +- return helper.onAnalysisComplete.then((_) { +- // no errors initially +- List errors = helper.getTestErrors(); +- expect(errors, isEmpty); +- // update code +- helper.sendContentChange(new AddContentOverlay('library lib')); +- // wait, there is an error +- return helper.onAnalysisComplete.then((_) { +- List errors = helper.getTestErrors(); +- expect(errors, hasLength(1)); +- }); +- }); +- }); +- +- test('incremental', () { +- AnalysisTestHelper helper = new AnalysisTestHelper(); +- String initialContent = 'library A;'; +- helper.createSingleFileProject(initialContent); +- return helper.onAnalysisComplete.then((_) { +- // no errors initially +- List errors = helper.getTestErrors(); +- expect(errors, isEmpty); +- // Add the file to the cache +- helper.sendContentChange(new AddContentOverlay(initialContent)); +- // update code +- helper.sendContentChange(new ChangeContentOverlay( +- [new SourceEdit('library '.length, 'A;'.length, 'lib')])); +- // wait, there is an error +- return helper.onAnalysisComplete.then((_) { +- List errors = helper.getTestErrors(); +- expect(errors, hasLength(1)); +- }); +- }); +- }); +- +- test('change on disk, normal', () { +- AnalysisTestHelper helper = new AnalysisTestHelper(); +- helper.createSingleFileProject('library A;'); +- return helper.onAnalysisComplete.then((_) { +- // There should be no errors +- expect(helper.getTestErrors(), hasLength(0)); +- // Change file on disk, adding a syntax error. +- helper.resourceProvider.modifyFile(helper.testFile, 'library lib'); +- // There should be errors now. +- return pumpEventQueue().then((_) { +- return helper.onAnalysisComplete.then((_) { +- expect(helper.getTestErrors(), hasLength(1)); +- }); +- }); +- }); +- }); +- +- test('change on disk, during override', () { +- AnalysisTestHelper helper = new AnalysisTestHelper(); +- helper.createSingleFileProject('library A;'); +- return helper.onAnalysisComplete.then((_) { +- // update code +- helper.sendContentChange(new AddContentOverlay('library B;')); +- // There should be no errors +- return helper.onAnalysisComplete.then((_) { +- expect(helper.getTestErrors(), hasLength(0)); +- // Change file on disk, adding a syntax error. +- helper.resourceProvider.modifyFile(helper.testFile, 'library lib'); +- // There should still be no errors (file should not have been reread). +- return helper.onAnalysisComplete.then((_) { +- expect(helper.getTestErrors(), hasLength(0)); +- // Send a content change with a null content param--file should be +- // reread from disk. +- helper.sendContentChange(new RemoveContentOverlay()); +- // There should be errors now. +- return helper.onAnalysisComplete.then((_) { +- expect(helper.getTestErrors(), hasLength(1)); +- }); +- }); +- }); +- }); +- }); +- +- group('out of range', () { +- Future outOfRangeTest(SourceEdit edit) { +- AnalysisTestHelper helper = new AnalysisTestHelper(); +- helper.createSingleFileProject('library A;'); +- return helper.onAnalysisComplete.then((_) { +- helper.sendContentChange(new AddContentOverlay('library B;')); +- return helper.onAnalysisComplete.then((_) { +- ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]); +- Request request = +- new AnalysisUpdateContentParams({helper.testFile: contentChange}) +- .toRequest('0'); +- Response response = helper.handler.handleRequest(request); +- expect(response, +- isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE)); +- }); +- }); +- } +- +- test('negative length', () { +- return outOfRangeTest(new SourceEdit(3, -1, 'foo')); +- }); +- +- test('negative offset', () { +- return outOfRangeTest(new SourceEdit(-1, 3, 'foo')); +- }); +- +- test('beyond end', () { +- return outOfRangeTest(new SourceEdit(6, 6, 'foo')); +- }); +- }); +-} +- +-@reflectiveTest +-class AnalysisDomainTest extends AbstractAnalysisTest { +- Map> filesErrors = {}; +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { +- var decoded = new AnalysisErrorsParams.fromNotification(notification); +- filesErrors[decoded.file] = decoded.errors; +- } +- } +- +- test_setRoots_packages() { +- // prepare package +- String pkgFile = '/packages/pkgA/libA.dart'; +- resourceProvider.newFile(pkgFile, ''' +-library lib_a; +-class A {} +-'''); +- resourceProvider.newFile( +- '/project/.packages', 'pkgA:file:///packages/pkgA'); +- addTestFile(''' +-import 'package:pkgA/libA.dart'; +-main(A a) { +-} +-'''); +- // create project and wait for analysis +- createProject(); +- return waitForTasksFinished().then((_) { +- // if 'package:pkgA/libA.dart' was resolved, then there are no errors +- expect(filesErrors[testFile], isEmpty); +- // errors are not reported for packages +- expect(filesErrors[pkgFile], isNull); +- }); +- } +-} +- +-/** +- * A helper to test 'analysis.*' requests. +- */ +-class AnalysisTestHelper { +- MockServerChannel serverChannel; +- MemoryResourceProvider resourceProvider; +- AnalysisServer server; +- AnalysisDomainHandler handler; +- +- Map> analysisSubscriptions = {}; +- +- Map> filesErrors = {}; +- Map> filesHighlights = {}; +- Map> filesNavigation = {}; +- +- String testFile = '/project/bin/test.dart'; +- String testCode; +- +- AnalysisTestHelper() { +- processRequiredPlugins(); +- serverChannel = new MockServerChannel(); +- resourceProvider = new MemoryResourceProvider(); +- // Create an SDK in the mock file system. +- new MockSdk(resourceProvider: resourceProvider); +- server = new AnalysisServer( +- serverChannel, +- resourceProvider, +- new MockPackageMapProvider(), +- new AnalysisServerOptions(), +- new DartSdkManager('/', false), +- InstrumentationService.NULL_SERVICE); +- handler = new AnalysisDomainHandler(server); +- // listen for notifications +- Stream notificationStream = +- serverChannel.notificationController.stream; +- notificationStream.listen((Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { +- var decoded = new AnalysisErrorsParams.fromNotification(notification); +- filesErrors[decoded.file] = decoded.errors; +- } +- if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) { +- var params = +- new AnalysisHighlightsParams.fromNotification(notification); +- filesHighlights[params.file] = params.regions; +- } +- if (notification.event == ANALYSIS_NOTIFICATION_NAVIGATION) { +- var params = +- new AnalysisNavigationParams.fromNotification(notification); +- filesNavigation[params.file] = params.regions; +- } +- }); +- } +- +- /** +- * Returns a [Future] that completes when the server's analysis is complete. +- */ +- Future get onAnalysisComplete { +- return server.onAnalysisComplete; +- } +- +- void addAnalysisSubscription(AnalysisService service, String file) { +- // add file to subscription +- var files = analysisSubscriptions[service]; +- if (files == null) { +- files = []; +- analysisSubscriptions[service] = files; +- } +- files.add(file); +- // set subscriptions +- Request request = new AnalysisSetSubscriptionsParams(analysisSubscriptions) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- void addAnalysisSubscriptionHighlights(String file) { +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file); +- } +- +- void addAnalysisSubscriptionNavigation(String file) { +- addAnalysisSubscription(AnalysisService.NAVIGATION, file); +- } +- +- /** +- * Creates an empty project `/project`. +- */ +- void createEmptyProject() { +- resourceProvider.newFolder('/project'); +- Request request = +- new AnalysisSetAnalysisRootsParams(['/project'], []).toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- /** +- * Creates a project with a single Dart file `/project/bin/test.dart` with +- * the given [code]. +- */ +- void createSingleFileProject(code) { +- this.testCode = _getCodeString(code); +- resourceProvider.newFolder('/project'); +- resourceProvider.newFile(testFile, testCode); +- Request request = +- new AnalysisSetAnalysisRootsParams(['/project'], []).toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- /** +- * Returns the offset of [search] in [testCode]. +- * Fails if not found. +- */ +- int findOffset(String search) { +- int offset = testCode.indexOf(search); +- expect(offset, isNot(-1)); +- return offset; +- } +- +- /** +- * Returns [AnalysisError]s recorded for the given [file]. +- * May be empty, but not `null`. +- */ +- List getErrors(String file) { +- List errors = filesErrors[file]; +- if (errors != null) { +- return errors; +- } +- return []; +- } +- +- /** +- * Returns highlights recorded for the given [file]. +- * May be empty, but not `null`. +- */ +- List getHighlights(String file) { +- List highlights = filesHighlights[file]; +- if (highlights != null) { +- return highlights; +- } +- return []; +- } +- +- /** +- * Returns navigation regions recorded for the given [file]. +- * May be empty, but not `null`. +- */ +- List getNavigation(String file) { +- List navigation = filesNavigation[file]; +- if (navigation != null) { +- return navigation; +- } +- return []; +- } +- +- /** +- * Returns [AnalysisError]s recorded for the [testFile]. +- * May be empty, but not `null`. +- */ +- List getTestErrors() { +- return getErrors(testFile); +- } +- +- /** +- * Returns highlights recorded for the given [testFile]. +- * May be empty, but not `null`. +- */ +- List getTestHighlights() { +- return getHighlights(testFile); +- } +- +- /** +- * Returns navigation information recorded for the given [testFile]. +- * May be empty, but not `null`. +- */ +- List getTestNavigation() { +- return getNavigation(testFile); +- } +- +- /** +- * Validates that the given [request] is handled successfully. +- */ +- void handleSuccessfulRequest(Request request) { +- Response response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- } +- +- void processRequiredPlugins() { +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- } +- +- /** +- * Send an `updateContent` request for [testFile]. +- */ +- void sendContentChange(dynamic contentChange) { +- Request request = new AnalysisUpdateContentParams({testFile: contentChange}) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- } +- +- String setFileContent(String path, String content) { +- resourceProvider.newFile(path, content); +- return path; +- } +- +- /** +- * Stops the associated server. +- */ +- void stopServer() { +- server.done(); +- } +- +- static String _getCodeString(code) { +- if (code is List) { +- code = code.join('\n'); +- } +- return code as String; +- } +-} +- +-@reflectiveTest +-class SetSubscriptionsTest extends AbstractAnalysisTest { +- Map> filesHighlights = {}; +- +- Completer _resultsAvailable = new Completer(); +- +- void processNotification(Notification notification) { +- if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) { +- var params = new AnalysisHighlightsParams.fromNotification(notification); +- filesHighlights[params.file] = params.regions; +- _resultsAvailable.complete(null); +- } +- } +- +- test_afterAnalysis() async { +- addTestFile('int V = 42;'); +- createProject(); +- // wait for analysis, no results initially +- await waitForTasksFinished(); +- expect(filesHighlights[testFile], isNull); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile); +- await _resultsAvailable.future; +- // there are results +- expect(filesHighlights[testFile], isNotEmpty); +- } +- +- test_afterAnalysis_noSuchFile() async { +- String file = '/no-such-file.dart'; +- addTestFile('// no matter'); +- createProject(); +- // wait for analysis, no results initially +- await waitForTasksFinished(); +- expect(filesHighlights[testFile], isNull); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file); +- await server.onAnalysisComplete; +- // there are results +- expect(filesHighlights[file], isNull); +- } +- +- test_afterAnalysis_packageFile_external() async { +- String pkgFile = '/packages/pkgA/lib/libA.dart'; +- resourceProvider.newFile(pkgFile, ''' +-library lib_a; +-class A {} +-'''); +- resourceProvider.newFile( +- '/project/.packages', 'pkgA:file:///packages/pkgA/lib'); +- // +- addTestFile(''' +-import 'package:pkgA/libA.dart'; +-main() { +- new A(); +-} +-'''); +- createProject(); +- // wait for analysis, no results initially +- await waitForTasksFinished(); +- expect(filesHighlights[pkgFile], isNull); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile); +- await _resultsAvailable.future; +- // there are results +- expect(filesHighlights[pkgFile], isNotEmpty); +- } +- +- test_afterAnalysis_packageFile_inRoot() async { +- String pkgA = '/pkgA'; +- String pkgB = '/pkgA'; +- String pkgFileA = '$pkgA/lib/libA.dart'; +- String pkgFileB = '$pkgA/lib/libB.dart'; +- resourceProvider.newFile(pkgFileA, ''' +-library lib_a; +-class A {} +-'''); +- resourceProvider.newFile(pkgFileB, ''' +-import 'package:pkgA/libA.dart'; +-main() { +- new A(); +-} +-'''); +- packageMapProvider.packageMap = { +- 'pkgA': [ +- resourceProvider.newFolder('$pkgA/lib'), +- resourceProvider.newFolder('$pkgB/lib') +- ] +- }; +- // add 'pkgA' and 'pkgB' as projects +- { +- resourceProvider.newFolder(projectPath); +- handleSuccessfulRequest( +- new AnalysisSetAnalysisRootsParams([pkgA, pkgB], []).toRequest('0')); +- } +- // wait for analysis, no results initially +- await waitForTasksFinished(); +- expect(filesHighlights[pkgFileA], isNull); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFileA); +- await _resultsAvailable.future; +- // there are results +- expect(filesHighlights[pkgFileA], isNotEmpty); +- } +- +- test_afterAnalysis_packageFile_notUsed() async { +- String pkgFile = '/packages/pkgA/lib/libA.dart'; +- resourceProvider.newFile(pkgFile, ''' +-library lib_a; +-class A {} +-'''); +- resourceProvider.newFile('/project/.packages', 'pkgA:/packages/pkgA/lib'); +- // +- addTestFile('// no "pkgA" reference'); +- createProject(); +- // wait for analysis, no results initially +- await waitForTasksFinished(); +- expect(filesHighlights[pkgFile], isNull); +- // make it a priority file, so make analyzable +- server.setPriorityFiles('0', [pkgFile]); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile); +- await _resultsAvailable.future; +- // there are results +- expect(filesHighlights[pkgFile], isNotEmpty); +- } +- +- test_afterAnalysis_sdkFile() async { +- String file = '/lib/core/core.dart'; +- addTestFile('// no matter'); +- createProject(); +- // wait for analysis, no results initially +- await waitForTasksFinished(); +- expect(filesHighlights[file], isNull); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file); +- await _resultsAvailable.future; +- // there are results +- expect(filesHighlights[file], isNotEmpty); +- } +- +- test_beforeAnalysis() async { +- addTestFile('int V = 42;'); +- createProject(); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile); +- // wait for analysis +- await waitForTasksFinished(); +- expect(filesHighlights[testFile], isNotEmpty); +- } +- +- test_sentToPlugins() async { +- addTestFile('int V = 42;'); +- createProject(); +- // subscribe +- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile); +- // wait for analysis +- await waitForTasksFinished(); +- plugin.AnalysisSetSubscriptionsParams params = +- pluginManager.analysisSetSubscriptionsParams; +- expect(params, isNotNull); +- Map> subscriptions = +- params.subscriptions; +- expect(subscriptions, hasLength(1)); +- List files = subscriptions[plugin.AnalysisService.HIGHLIGHTS]; +- expect(files, [testFile]); +- } +-} +diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart +deleted file mode 100644 +index 5aad7e432c7..00000000000 +--- a/pkg/analysis_server/test/domain_completion_test.dart ++++ /dev/null +@@ -1,780 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/provisional/completion/completion_core.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'domain_completion_util.dart'; +-import 'mocks.dart' show pumpEventQueue; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(CompletionDomainHandlerTest); +- }); +-} +- +-@reflectiveTest +-class CompletionDomainHandlerTest extends AbstractCompletionDomainTest { +- test_ArgumentList_constructor_named_fieldFormalParam() async { +- // https://github.com/dart-lang/sdk/issues/31023 +- addTestFile(''' +-main() { new A(field: ^);} +-class A { +- A({this.field: -1}) {} +-} +-'''); +- await getSuggestions(); +- } +- +- test_ArgumentList_constructor_named_param_label() async { +- addTestFile('main() { new A(^);}' +- 'class A { A({one, two}) {} }'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(2)); +- } +- +- test_ArgumentList_factory_named_param_label() async { +- addTestFile('main() { new A(^);}' +- 'class A { factory A({one, two}) => null; }'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(2)); +- } +- +- test_ArgumentList_imported_function_named_param() async { +- addTestFile('main() { int.parse("16", ^);}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(2)); +- } +- +- test_ArgumentList_imported_function_named_param1() async { +- addTestFile('main() { foo(o^);} foo({one, two}) {}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(2)); +- } +- +- test_ArgumentList_imported_function_named_param2() async { +- addTestFile('mainx() {A a = new A(); a.foo(one: 7, ^);}' +- 'class A { foo({one, two}) {} }'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(1)); +- } +- +- test_ArgumentList_imported_function_named_param_label1() async { +- addTestFile('main() { int.parse("16", r^: 16);}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(2)); +- } +- +- test_ArgumentList_imported_function_named_param_label3() async { +- addTestFile('main() { int.parse("16", ^: 16);}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ', +- relevance: DART_RELEVANCE_NAMED_PARAMETER); +- expect(suggestions, hasLength(2)); +- } +- +- test_catch() async { +- addTestFile('main() {try {} ^}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'on', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally', +- relevance: DART_RELEVANCE_KEYWORD); +- expect(suggestions, hasLength(3)); +- } +- +- test_catch2() async { +- addTestFile('main() {try {} on Foo {} ^}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'on', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'for', +- relevance: DART_RELEVANCE_KEYWORD); +- suggestions.firstWhere( +- (CompletionSuggestion suggestion) => +- suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () { +- fail('Expected suggestions other than keyword suggestions'); +- }); +- } +- +- test_catch3() async { +- addTestFile('main() {try {} catch (e) {} finally {} ^}'); +- await getSuggestions(); +- assertNoResult('on'); +- assertNoResult('catch'); +- assertNoResult('finally'); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'for', +- relevance: DART_RELEVANCE_KEYWORD); +- suggestions.firstWhere( +- (CompletionSuggestion suggestion) => +- suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () { +- fail('Expected suggestions other than keyword suggestions'); +- }); +- } +- +- test_catch4() async { +- addTestFile('main() {try {} finally {} ^}'); +- await getSuggestions(); +- assertNoResult('on'); +- assertNoResult('catch'); +- assertNoResult('finally'); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'for', +- relevance: DART_RELEVANCE_KEYWORD); +- suggestions.firstWhere( +- (CompletionSuggestion suggestion) => +- suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () { +- fail('Expected suggestions other than keyword suggestions'); +- }); +- } +- +- test_catch5() async { +- addTestFile('main() {try {} ^ finally {}}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'on', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch', +- relevance: DART_RELEVANCE_KEYWORD); +- expect(suggestions, hasLength(2)); +- } +- +- test_constructor() async { +- addTestFile('class A {bool foo; A() : ^;}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'super', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_constructor2() async { +- addTestFile('class A {bool foo; A() : s^;}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'super', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_constructor3() async { +- addTestFile('class A {bool foo; A() : a=7,^;}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'super', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_constructor4() async { +- addTestFile('class A {bool foo; A() : a=7,s^;}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'super', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_constructor5() async { +- addTestFile('class A {bool foo; A() : a=7,s^}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'super', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_constructor6() async { +- addTestFile('class A {bool foo; A() : a=7,^ void bar() {}}'); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'super', +- relevance: DART_RELEVANCE_KEYWORD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_html() { +- // +- // We no longer support the analysis of non-dart files. +- // +- testFile = '/project/web/test.html'; +- addTestFile(''' +- ^ +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- expect(suggestions, hasLength(0)); +- }); +- } +- +- test_import_uri_with_trailing() { +- addFile('/project/bin/testA.dart', 'library libA;'); +- addTestFile(''' +- import '/project/bin/t^.dart'; +- main() {}'''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset - 14)); +- expect(replacementLength, equals(5 + 14)); +- assertHasResult( +- CompletionSuggestionKind.IMPORT, '/project/bin/testA.dart'); +- assertNoResult('test'); +- }); +- } +- +- test_imports() { +- addTestFile(''' +- import 'dart:html'; +- main() {^} +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement'); +- assertNoResult('test'); +- }); +- } +- +- test_imports_aborted_new_request() async { +- addTestFile(''' +- class foo { } +- c^'''); +- +- // Make a request for suggestions +- Request request1 = +- new CompletionGetSuggestionsParams(testFile, completionOffset) +- .toRequest('7'); +- Future responseFuture1 = waitResponse(request1); +- +- // Make another request before the first request completes +- Request request2 = +- new CompletionGetSuggestionsParams(testFile, completionOffset) +- .toRequest('8'); +- Future responseFuture2 = waitResponse(request2); +- +- // Await first response +- Response response1 = await responseFuture1; +- var result1 = new CompletionGetSuggestionsResult.fromResponse(response1); +- assertValidId(result1.id); +- +- // Await second response +- Response response2 = await responseFuture2; +- var result2 = new CompletionGetSuggestionsResult.fromResponse(response2); +- assertValidId(result2.id); +- +- // Wait for all processing to be complete +- await analysisHandler.server.analysisDriverScheduler.waitForIdle(); +- await pumpEventQueue(); +- +- // Assert that first request has been aborted +- expect(allSuggestions[result1.id], hasLength(0)); +- +- // Assert valid results for the second request +- expect(allSuggestions[result2.id], same(suggestions)); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'class', +- relevance: DART_RELEVANCE_HIGH); +- } +- +- @failingTest +- test_imports_aborted_source_changed() async { +- // TODO(brianwilkerson) Figure out whether this test makes sense when +- // running the new driver. It waits for an initial empty notification then +- // waits for a new notification. But I think that under the driver we only +- // ever send one notification. +- addTestFile(''' +- class foo { } +- c^'''); +- +- // Make a request for suggestions +- Request request = +- new CompletionGetSuggestionsParams(testFile, completionOffset) +- .toRequest('0'); +- Future responseFuture = waitResponse(request); +- +- // Simulate user deleting text after request but before suggestions returned +- server.updateContent('uc1', {testFile: new AddContentOverlay(testCode)}); +- server.updateContent('uc2', { +- testFile: new ChangeContentOverlay( +- [new SourceEdit(completionOffset - 1, 1, '')]) +- }); +- +- // Await a response +- Response response = await responseFuture; +- completionId = response.id; +- assertValidId(completionId); +- +- // Wait for all processing to be complete +- await analysisHandler.server.analysisDriverScheduler.waitForIdle(); +- await pumpEventQueue(); +- +- // Assert that request has been aborted +- expect(suggestionsDone, isTrue); +- expect(suggestions, hasLength(0)); +- } +- +- test_imports_incremental() async { +- addTestFile('''library foo; +- e^ +- import "dart:async"; +- import "package:foo/foo.dart"; +- class foo { }'''); +- await waitForTasksFinished(); +- server.updateContent('uc1', {testFile: new AddContentOverlay(testCode)}); +- server.updateContent('uc2', { +- testFile: +- new ChangeContentOverlay([new SourceEdit(completionOffset, 0, 'xp')]) +- }); +- completionOffset += 2; +- await getSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';', +- selectionOffset: 8, relevance: DART_RELEVANCE_HIGH); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';', +- selectionOffset: 8, relevance: DART_RELEVANCE_HIGH); +- assertNoResult('extends'); +- assertNoResult('library'); +- } +- +- test_imports_partial() async { +- addTestFile('''^ +- import "package:foo/foo.dart"; +- import "package:bar/bar.dart"; +- class Baz { }'''); +- +- // Wait for analysis then edit the content +- await waitForTasksFinished(); +- String revisedContent = testCode.substring(0, completionOffset) + +- 'i' + +- testCode.substring(completionOffset); +- ++completionOffset; +- server.handleRequest(new AnalysisUpdateContentParams( +- {testFile: new AddContentOverlay(revisedContent)}).toRequest('add1')); +- +- // Request code completion immediately after edit +- Response response = await waitResponse( +- new CompletionGetSuggestionsParams(testFile, completionOffset) +- .toRequest('0')); +- completionId = response.id; +- assertValidId(completionId); +- await waitForTasksFinished(); +- // wait for response to arrive +- // because although the analysis is complete (waitForTasksFinished) +- // the response may not yet have been processed +- while (replacementOffset == null) { +- await new Future.delayed(new Duration(milliseconds: 5)); +- } +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'library', +- relevance: DART_RELEVANCE_HIGH); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';', +- selectionOffset: 8, relevance: DART_RELEVANCE_HIGH); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';', +- selectionOffset: 8, relevance: DART_RELEVANCE_HIGH); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'part \'\';', +- selectionOffset: 6, relevance: DART_RELEVANCE_HIGH); +- assertNoResult('extends'); +- } +- +- test_imports_prefixed() { +- addTestFile(''' +- import 'dart:html' as foo; +- main() {^} +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object'); +- assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo'); +- assertNoResult('HtmlElement'); +- assertNoResult('test'); +- }); +- } +- +- test_imports_prefixed2() { +- addTestFile(''' +- import 'dart:html' as foo; +- main() {foo.^} +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement'); +- assertNoResult('test'); +- }); +- } +- +- test_inComment_block_beforeNode() async { +- addTestFile(''' +- main(aaa, bbb) { +- /* text ^ */ +- print(42); +- } +- '''); +- await getSuggestions(); +- expect(suggestions, isEmpty); +- } +- +- test_inComment_endOfLine_beforeNode() async { +- addTestFile(''' +- main(aaa, bbb) { +- // text ^ +- print(42); +- } +- '''); +- await getSuggestions(); +- expect(suggestions, isEmpty); +- } +- +- test_inComment_endOfLine_beforeToken() async { +- addTestFile(''' +- main(aaa, bbb) { +- // text ^ +- } +- '''); +- await getSuggestions(); +- expect(suggestions, isEmpty); +- } +- +- test_inDartDoc1() async { +- addTestFile(''' +- /// ^ +- main(aaa, bbb) {} +- '''); +- await getSuggestions(); +- expect(suggestions, isEmpty); +- } +- +- test_inDartDoc2() async { +- addTestFile(''' +- /// Some text^ +- main(aaa, bbb) {} +- '''); +- await getSuggestions(); +- expect(suggestions, isEmpty); +- } +- +- test_inDartDoc_reference1() async { +- addFile('/testA.dart', ''' +- part of libA; +- foo(bar) => 0;'''); +- addTestFile(''' +- library libA; +- part "/testA.dart"; +- import "dart:math"; +- /// The [^] +- main(aaa, bbb) {} +- '''); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min'); +- } +- +- test_inDartDoc_reference2() async { +- addTestFile(''' +- /// The [m^] +- main(aaa, bbb) {} +- '''); +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- } +- +- test_inherited() { +- addFile('/libA.dart', 'class A {m() {}}'); +- addTestFile(''' +-import '/libA.dart'; +-class B extends A { +- x() {^} +-} +-'''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'm'); +- }); +- } +- +- test_invocation() { +- addTestFile('class A {b() {}} main() {A a; a.^}'); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'b'); +- }); +- } +- +- test_invocation_sdk_relevancy_off() { +- var originalSorter = DartCompletionManager.contributionSorter; +- var mockSorter = new MockRelevancySorter(); +- DartCompletionManager.contributionSorter = mockSorter; +- addTestFile('main() {Map m; m.^}'); +- return getSuggestions().then((_) { +- // Assert that the CommonUsageComputer has been replaced +- expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE), +- isFalse); +- DartCompletionManager.contributionSorter = originalSorter; +- mockSorter.enabled = false; +- }); +- } +- +- test_invocation_sdk_relevancy_on() { +- addTestFile('main() {Map m; m.^}'); +- return getSuggestions().then((_) { +- // Assert that the CommonUsageComputer is working +- expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE), +- isTrue); +- }); +- } +- +- test_invocation_withTrailingStmt() { +- addTestFile('class A {b() {}} main() {A a; a.^ int x = 7;}'); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'b'); +- }); +- } +- +- test_keyword() { +- addTestFile('library A; cl^'); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset - 2)); +- expect(replacementLength, equals(2)); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';', +- selectionOffset: 8, relevance: DART_RELEVANCE_HIGH); +- assertHasResult(CompletionSuggestionKind.KEYWORD, 'class', +- relevance: DART_RELEVANCE_HIGH); +- }); +- } +- +- test_local_named_constructor() { +- addTestFile('class A {A.c(); x() {new A.^}}'); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'c'); +- assertNoResult('A'); +- }); +- } +- +- test_local_override() { +- addFile('/libA.dart', 'class A {m() {}}'); +- addTestFile(''' +-import '/libA.dart'; +-class B extends A { +- m() {} +- x() {^} +-} +-'''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'm', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- }); +- } +- +- test_locals() { +- addTestFile('class A {var a; x() {var b;^}} class DateTime { }'); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'a', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'b', +- relevance: DART_RELEVANCE_LOCAL_VARIABLE); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'x', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'DateTime'); +- }); +- } +- +- test_offset_past_eof() async { +- addTestFile('main() { }', offset: 300); +- Request request = +- new CompletionGetSuggestionsParams(testFile, completionOffset) +- .toRequest('0'); +- Response response = await waitResponse(request); +- expect(response.id, '0'); +- expect(response.error.code, RequestErrorCode.INVALID_PARAMETER); +- } +- +- test_overrides() { +- addFile('/libA.dart', 'class A {m() {}}'); +- addTestFile(''' +-import '/libA.dart'; +-class B extends A {m() {^}} +-'''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'm', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- }); +- } +- +- test_partFile() { +- addFile('/project/bin/testA.dart', ''' +- library libA; +- part "$testFile"; +- import 'dart:html'; +- class A { } +- '''); +- addTestFile(''' +- part of libA; +- main() {^}'''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A'); +- assertNoResult('test'); +- }); +- } +- +- test_partFile2() { +- addFile('/testA.dart', ''' +- part of libA; +- class A { }'''); +- addTestFile(''' +- library libA; +- part "/testA.dart"; +- import 'dart:html'; +- main() {^} +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A'); +- assertNoResult('test'); +- }); +- } +- +- test_sentToPlugins() async { +- addTestFile(''' +- void main() { +- ^ +- } +- '''); +- PluginInfo info = new DiscoveredPluginInfo('a', 'b', 'c', null, null); +- plugin.CompletionGetSuggestionsResult result = +- new plugin.CompletionGetSuggestionsResult( +- testFile.indexOf('^'), 0, [ +- new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER, +- DART_RELEVANCE_DEFAULT, 'plugin completion', 3, 0, false, false) +- ]); +- pluginManager.broadcastResults = >{ +- info: new Future.value(result.toResponse('-', 1)) +- }; +- await getSuggestions(); +- assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'plugin completion', +- selectionOffset: 3); +- } +- +- test_simple() { +- addTestFile(''' +- void main() { +- ^ +- } +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object'); +- assertNoResult('HtmlElement'); +- assertNoResult('test'); +- }); +- } +- +- test_static() { +- addTestFile('class A {static b() {} c() {}} main() {A.^}'); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'b'); +- assertNoResult('c'); +- }); +- } +- +- test_topLevel() { +- addTestFile(''' +- typedef foo(); +- var test = ''; +- main() {tes^t} +- '''); +- return getSuggestions().then((_) { +- expect(replacementOffset, equals(completionOffset - 3)); +- expect(replacementLength, equals(4)); +- // Suggestions based upon imported elements are partially filtered +- //assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'test', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertNoResult('HtmlElement'); +- }); +- } +-} +- +-class MockRelevancySorter implements DartContributionSorter { +- bool enabled = true; +- +- @override +- Future sort( +- CompletionRequest request, Iterable suggestions) { +- if (!enabled) { +- throw 'unexpected sort'; +- } +- return new Future.value(); +- } +-} +diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart +deleted file mode 100644 +index 6f1da485995..00000000000 +--- a/pkg/analysis_server/test/domain_completion_util.dart ++++ /dev/null +@@ -1,123 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/constants.dart'; +-import 'package:analysis_server/src/domain_completion.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +- +-import 'analysis_abstract.dart'; +- +-class AbstractCompletionDomainTest extends AbstractAnalysisTest { +- String completionId; +- int completionOffset; +- int replacementOffset; +- int replacementLength; +- Map> receivedSuggestionsCompleters = {}; +- List suggestions = []; +- bool suggestionsDone = false; +- Map> allSuggestions = {}; +- +- String addTestFile(String content, {int offset}) { +- completionOffset = content.indexOf('^'); +- if (offset != null) { +- expect(completionOffset, -1, reason: 'cannot supply offset and ^'); +- completionOffset = offset; +- return super.addTestFile(content); +- } +- expect(completionOffset, isNot(equals(-1)), reason: 'missing ^'); +- int nextOffset = content.indexOf('^', completionOffset + 1); +- expect(nextOffset, equals(-1), reason: 'too many ^'); +- return super.addTestFile(content.substring(0, completionOffset) + +- content.substring(completionOffset + 1)); +- } +- +- void assertHasResult(CompletionSuggestionKind kind, String completion, +- {int relevance: DART_RELEVANCE_DEFAULT, +- bool isDeprecated: false, +- bool isPotential: false, +- int selectionOffset}) { +- var cs; +- suggestions.forEach((s) { +- if (s.completion == completion) { +- if (cs == null) { +- cs = s; +- } else { +- fail('expected exactly one $completion but found > 1'); +- } +- } +- }); +- if (cs == null) { +- var completions = suggestions.map((s) => s.completion).toList(); +- fail('expected "$completion" but found\n $completions'); +- } +- expect(cs.kind, equals(kind)); +- expect(cs.relevance, equals(relevance)); +- expect(cs.selectionOffset, selectionOffset ?? completion.length); +- expect(cs.selectionLength, equals(0)); +- expect(cs.isDeprecated, equals(isDeprecated)); +- expect(cs.isPotential, equals(isPotential)); +- } +- +- void assertNoResult(String completion) { +- if (suggestions.any((cs) => cs.completion == completion)) { +- fail('did not expect completion: $completion'); +- } +- } +- +- void assertValidId(String id) { +- expect(id, isNotNull); +- expect(id.isNotEmpty, isTrue); +- } +- +- Future getSuggestions() async { +- await waitForTasksFinished(); +- +- Request request = +- new CompletionGetSuggestionsParams(testFile, completionOffset) +- .toRequest('0'); +- Response response = await waitResponse(request); +- var result = new CompletionGetSuggestionsResult.fromResponse(response); +- completionId = result.id; +- assertValidId(completionId); +- await _getResultsCompleter(completionId).future; +- expect(suggestionsDone, isTrue); +- } +- +- processNotification(Notification notification) async { +- if (notification.event == COMPLETION_RESULTS) { +- var params = new CompletionResultsParams.fromNotification(notification); +- String id = params.id; +- assertValidId(id); +- replacementOffset = params.replacementOffset; +- replacementLength = params.replacementLength; +- suggestionsDone = params.isLast; +- expect(suggestionsDone, isNotNull); +- suggestions = params.results; +- expect(allSuggestions.containsKey(id), isFalse); +- allSuggestions[id] = params.results; +- _getResultsCompleter(id).complete(null); +- } else if (notification.event == SERVER_NOTIFICATION_ERROR) { +- fail('server error: ${notification.toJson()}'); +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new CompletionDomainHandler(server); +- } +- +- Completer _getResultsCompleter(String id) { +- return receivedSuggestionsCompleters.putIfAbsent( +- id, () => new Completer()); +- } +-} +diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart +deleted file mode 100644 +index 913294f8946..00000000000 +--- a/pkg/analysis_server/test/domain_diagnostic_test.dart ++++ /dev/null +@@ -1,58 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/domain_diagnostic.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(DiagnosticDomainTest); +- }); +-} +- +-@reflectiveTest +-class DiagnosticDomainTest extends AbstractAnalysisTest { +- @override +- void setUp() { +- generateSummaryFiles = true; +- super.setUp(); +- handler = new DiagnosticDomainHandler(server); +- server.handlers = [handler]; +- } +- +- test_getDiagnostics() async { +- String file = '/project/bin/test.dart'; +- resourceProvider.newFile('/project/pubspec.yaml', 'name: project'); +- resourceProvider.newFile(file, 'main() {}'); +- +- server.setAnalysisRoots('0', ['/project/'], [], {}); +- +- await server.onAnalysisComplete; +- +- var request = new DiagnosticGetDiagnosticsParams().toRequest('0'); +- var response = handler.handleRequest(request); +- var result = new DiagnosticGetDiagnosticsResult.fromResponse(response); +- +- expect(result.contexts, hasLength(1)); +- +- ContextData context = result.contexts[0]; +- expect(context.name, '/project'); +- expect(context.explicitFileCount, 1); /* test.dart */ +- +- expect(context.implicitFileCount, 4); +- +- expect(context.workItemQueueLength, isNotNull); +- } +- +- test_getDiagnostics_noRoot() async { +- var request = new DiagnosticGetDiagnosticsParams().toRequest('0'); +- var response = handler.handleRequest(request); +- var result = new DiagnosticGetDiagnosticsResult.fromResponse(response); +- expect(result.contexts, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart +deleted file mode 100644 +index b46daaab75a..00000000000 +--- a/pkg/analysis_server/test/domain_execution_test.dart ++++ /dev/null +@@ -1,243 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/domain_execution.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/generated/source_io.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'analysis_abstract.dart'; +-import 'mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ExecutionDomainTest); +- }); +- group('ExecutionDomainHandler', () { +- MemoryResourceProvider provider = new MemoryResourceProvider(); +- AnalysisServer server; +- ExecutionDomainHandler handler; +- +- setUp(() { +- server = new AnalysisServer( +- new MockServerChannel(), +- provider, +- new MockPackageMapProvider(), +- new AnalysisServerOptions(), +- new DartSdkManager('', false), +- InstrumentationService.NULL_SERVICE); +- handler = new ExecutionDomainHandler(server); +- }); +- +- group('createContext/deleteContext', () { +- test('create/delete multiple contexts', () { +- Request request = +- new ExecutionCreateContextParams('/a/b.dart').toRequest('0'); +- Response response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- ExecutionCreateContextResult result = +- new ExecutionCreateContextResult.fromResponse(response); +- String id0 = result.id; +- +- request = new ExecutionCreateContextParams('/c/d.dart').toRequest('1'); +- response = handler.handleRequest(request); +- expect(response, isResponseSuccess('1')); +- result = new ExecutionCreateContextResult.fromResponse(response); +- String id1 = result.id; +- +- expect(id0 == id1, isFalse); +- +- request = new ExecutionDeleteContextParams(id0).toRequest('2'); +- response = handler.handleRequest(request); +- expect(response, isResponseSuccess('2')); +- +- request = new ExecutionDeleteContextParams(id1).toRequest('3'); +- response = handler.handleRequest(request); +- expect(response, isResponseSuccess('3')); +- }); +- +- test('delete non-existent context', () { +- Request request = new ExecutionDeleteContextParams('13').toRequest('0'); +- Response response = handler.handleRequest(request); +- // TODO(brianwilkerson) It isn't currently specified to be an error if a +- // client attempts to delete a context that doesn't exist. Should it be? +-// expect(response, isResponseFailure('0')); +- expect(response, isResponseSuccess('0')); +- }); +- }); +- +- // TODO(brianwilkerson) Re-enable these tests if we re-enable the +- // execution.mapUri request. +-// group('mapUri', () { +-// String contextId; +-// +-// void createExecutionContextIdForFile(String path) { +-// Request request = new ExecutionCreateContextParams(path).toRequest('0'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseSuccess('0')); +-// ExecutionCreateContextResult result = +-// new ExecutionCreateContextResult.fromResponse(response); +-// contextId = result.id; +-// } +-// +-// setUp(() { +-// Folder folder = provider.newFile('/a/b.dart', '').parent; +-// server.folderMap.putIfAbsent(folder, () { +-// SourceFactory factory = +-// new SourceFactory([new ResourceUriResolver(provider)]); +-// AnalysisContext context = +-// AnalysisEngine.instance.createAnalysisContext(); +-// context.sourceFactory = factory; +-// return context; +-// }); +-// createExecutionContextIdForFile('/a/b.dart'); +-// }); +-// +-// tearDown(() { +-// Request request = +-// new ExecutionDeleteContextParams(contextId).toRequest('1'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseSuccess('1')); +-// }); +-// +-// group('file to URI', () { +-// test('does not exist', () { +-// Request request = +-// new ExecutionMapUriParams(contextId, file: '/a/c.dart') +-// .toRequest('2'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseFailure('2')); +-// }); +-// +-// test('directory', () { +-// provider.newFolder('/a/d'); +-// Request request = +-// new ExecutionMapUriParams(contextId, file: '/a/d').toRequest('2'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseFailure('2')); +-// }); +-// }); +-// +-// group('URI to file', () { +-// test('invalid', () { +-// Request request = +-// new ExecutionMapUriParams(contextId, uri: 'foo:///a/b.dart') +-// .toRequest('2'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseFailure('2')); +-// }); +-// }); +-// +-// test('invalid context id', () { +-// Request request = +-// new ExecutionMapUriParams('xxx', uri: '').toRequest('4'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseFailure('4')); +-// }); +-// +-// test('both file and uri', () { +-// Request request = +-// new ExecutionMapUriParams('xxx', file: '', uri: '').toRequest('5'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseFailure('5')); +-// }); +-// +-// test('neither file nor uri', () { +-// Request request = new ExecutionMapUriParams('xxx').toRequest('6'); +-// Response response = handler.handleRequest(request); +-// expect(response, isResponseFailure('6')); +-// }); +-// }); +- }); +-} +- +-@reflectiveTest +-class ExecutionDomainTest extends AbstractAnalysisTest { +- String contextId; +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new ExecutionDomainHandler(server); +- _createExecutionContext(testFile); +- } +- +- @override +- void tearDown() { +- _disposeExecutionContext(); +- super.tearDown(); +- } +- +- void test_mapUri_file() { +- String path = '/a/b.dart'; +- resourceProvider.newFile(path, ''); +- // map the file +- ExecutionMapUriResult result = _mapUri(file: path); +- expect(result.file, isNull); +- expect(result.uri, 'file:///a/b.dart'); +- } +- +- void test_mapUri_file_dartUriKind() { +- String path = server.findSdk().mapDartUri('dart:async').fullName; +- // hack - pretend that the SDK file exists in the project FS +- resourceProvider.newFile(path, '// hack'); +- // map file +- ExecutionMapUriResult result = _mapUri(file: path); +- expect(result.file, isNull); +- expect(result.uri, 'dart:async'); +- } +- +- void test_mapUri_uri() { +- String path = '/a/b.dart'; +- resourceProvider.newFile(path, ''); +- // map the uri +- ExecutionMapUriResult result = _mapUri(uri: 'file://$path'); +- expect(result.file, '/a/b.dart'); +- expect(result.uri, isNull); +- } +- +- void _createExecutionContext(String path) { +- Request request = new ExecutionCreateContextParams(path).toRequest('0'); +- Response response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- ExecutionCreateContextResult result = +- new ExecutionCreateContextResult.fromResponse(response); +- contextId = result.id; +- } +- +- void _disposeExecutionContext() { +- Request request = +- new ExecutionDeleteContextParams(contextId).toRequest('1'); +- Response response = handler.handleRequest(request); +- expect(response, isResponseSuccess('1')); +- } +- +- ExecutionMapUriResult _mapUri({String file, String uri}) { +- Request request = new ExecutionMapUriParams(contextId, file: file, uri: uri) +- .toRequest('2'); +- Response response = handler.handleRequest(request); +- expect(response, isResponseSuccess('2')); +- return new ExecutionMapUriResult.fromResponse(response); +- } +-} +- +-/** +- * A [Source] that knows it's [fullName]. +- */ +-class TestSource implements Source { +- String fullName; +- +- TestSource(this.fullName); +- +- @override +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +-} +diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart +deleted file mode 100644 +index c4aeebd783e..00000000000 +--- a/pkg/analysis_server/test/domain_server_test.dart ++++ /dev/null +@@ -1,81 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/constants.dart'; +-import 'package:analysis_server/src/domain_server.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:test/test.dart'; +- +-import 'mocks.dart'; +- +-main() { +- AnalysisServer server; +- ServerDomainHandler handler; +- MockServerChannel serverChannel; +- +- setUp(() { +- serverChannel = new MockServerChannel(); +- var resourceProvider = new MemoryResourceProvider(); +- server = new AnalysisServer( +- serverChannel, +- resourceProvider, +- new MockPackageMapProvider(), +- new AnalysisServerOptions(), +- new DartSdkManager('', false), +- InstrumentationService.NULL_SERVICE); +- handler = new ServerDomainHandler(server); +- }); +- +- group('ServerDomainHandler', () { +- test('getVersion', () { +- var request = new ServerGetVersionParams().toRequest('0'); +- var response = handler.handleRequest(request); +- expect( +- response.toJson(), +- equals({ +- Response.ID: '0', +- Response.RESULT: {VERSION: AnalysisServer.VERSION} +- })); +- }); +- +- group('setSubscriptions', () { +- test('invalid service name', () { +- Request request = new Request('0', SERVER_REQUEST_SET_SUBSCRIPTIONS, { +- SUBSCRIPTIONS: ['noSuchService'] +- }); +- var response = handler.handleRequest(request); +- expect(response, isResponseFailure('0')); +- }); +- +- test('success', () { +- expect(server.serverServices, isEmpty); +- // send request +- Request request = +- new ServerSetSubscriptionsParams([ServerService.STATUS]) +- .toRequest('0'); +- var response = handler.handleRequest(request); +- expect(response, isResponseSuccess('0')); +- // set of services has been changed +- expect(server.serverServices, contains(ServerService.STATUS)); +- }); +- }); +- +- test('shutdown', () async { +- expect(server.running, isTrue); +- // send request +- var request = new ServerShutdownParams().toRequest('0'); +- var response = await serverChannel.sendRequest(request); +- expect(response, isResponseSuccess('0')); +- +- // server is down +- expect(server.running, isFalse); +- }); +- }); +-} +diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart +deleted file mode 100644 +index 399706d2aa9..00000000000 +--- a/pkg/analysis_server/test/edit/assists_test.dart ++++ /dev/null +@@ -1,134 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AssistsTest); +- }); +-} +- +-@reflectiveTest +-class AssistsTest extends AbstractAnalysisTest { +- List changes; +- +- prepareAssists(String search, [int length = 0]) async { +- int offset = findOffset(search); +- await prepareAssistsAt(offset, length); +- } +- +- prepareAssistsAt(int offset, int length) async { +- Request request = +- new EditGetAssistsParams(testFile, offset, length).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new EditGetAssistsResult.fromResponse(response); +- changes = result.assists; +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- } +- +- test_fromPlugins() async { +- PluginInfo info = new DiscoveredPluginInfo('a', 'b', 'c', null, null); +- String message = 'From a plugin'; +- plugin.PrioritizedSourceChange change = new plugin.PrioritizedSourceChange( +- 5, +- new SourceChange(message, edits: [ +- new SourceFileEdit('', 0, +- edits: [new SourceEdit(0, 0, 'x')]) +- ])); +- plugin.EditGetAssistsResult result = new plugin.EditGetAssistsResult( +- [change]); +- pluginManager.broadcastResults = >{ +- info: new Future.value(result.toResponse('-', 1)) +- }; +- +- addTestFile('main() {}'); +- await waitForTasksFinished(); +- await prepareAssists('in('); +- _assertHasChange(message, 'xmain() {}'); +- } +- +- test_removeTypeAnnotation() async { +- addTestFile(''' +-main() { +- int v = 1; +-} +-'''); +- await waitForTasksFinished(); +- await prepareAssists('v ='); +- _assertHasChange('Remove type annotation', ''' +-main() { +- var v = 1; +-} +-'''); +- } +- +- test_splitVariableDeclaration() async { +- addTestFile(''' +-main() { +- int v = 1; +-} +-'''); +- await waitForTasksFinished(); +- await prepareAssists('v ='); +- _assertHasChange('Split variable declaration', ''' +-main() { +- int v; +- v = 1; +-} +-'''); +- } +- +- test_surroundWithIf() async { +- addTestFile(''' +-main() { +- print(1); +- print(2); +-} +-'''); +- await waitForTasksFinished(); +- int offset = findOffset(' print(1)'); +- int length = findOffset('}') - offset; +- await prepareAssistsAt(offset, length); +- _assertHasChange("Surround with 'if'", ''' +-main() { +- if (condition) { +- print(1); +- print(2); +- } +-} +-'''); +- } +- +- void _assertHasChange(String message, String expectedCode) { +- for (SourceChange change in changes) { +- if (change.message == message) { +- String resultCode = +- SourceEdit.applySequence(testCode, change.edits[0].edits); +- expect(resultCode, expectedCode); +- return; +- } +- } +- fail("Expected to find |$message| in\n" + changes.join('\n')); +- } +-} +diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart +deleted file mode 100644 +index 90732cdceef..00000000000 +--- a/pkg/analysis_server/test/edit/fixes_test.dart ++++ /dev/null +@@ -1,164 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FixesTest); +- }); +-} +- +-@reflectiveTest +-class FixesTest extends AbstractAnalysisTest { +- @override +- void setUp() { +- super.setUp(); +- handler = new EditDomainHandler(server); +- } +- +- test_fixUndefinedClass() async { +- createProject(); +- addTestFile(''' +-main() { +- Future x = null; +-} +-'''); +- await waitForTasksFinished(); +- List errorFixes = await _getFixesAt('Future'); +- expect(errorFixes, hasLength(1)); +- AnalysisError error = errorFixes[0].error; +- expect(error.severity, AnalysisErrorSeverity.WARNING); +- expect(error.type, AnalysisErrorType.STATIC_WARNING); +- List fixes = errorFixes[0].fixes; +- expect(fixes, hasLength(2)); +- expect(fixes[0].message, matches('Import library')); +- expect(fixes[1].message, matches('Create class')); +- } +- +- test_fromPlugins() async { +- PluginInfo info = new DiscoveredPluginInfo('a', 'b', 'c', null, null); +- plugin.AnalysisErrorFixes fixes = new plugin.AnalysisErrorFixes( +- new AnalysisError(AnalysisErrorSeverity.ERROR, AnalysisErrorType.HINT, +- new Location('', 0, 0, 0, 0), 'message', 'code')); +- plugin.EditGetFixesResult result = +- new plugin.EditGetFixesResult([fixes]); +- pluginManager.broadcastResults = >{ +- info: new Future.value(result.toResponse('-', 1)) +- }; +- +- createProject(); +- addTestFile('main() {}'); +- await waitForTasksFinished(); +- List errorFixes = await _getFixesAt('in('); +- expect(errorFixes, hasLength(1)); +- } +- +- test_hasFixes() async { +- createProject(); +- addTestFile(''' +-foo() { +- print(1) +-} +-bar() { +- print(10) print(20) +-} +-'''); +- await waitForTasksFinished(); +- // print(1) +- { +- List errorFixes = await _getFixesAt('print(1)'); +- expect(errorFixes, hasLength(1)); +- _isSyntacticErrorWithSingleFix(errorFixes[0]); +- } +- // print(10) +- { +- List errorFixes = await _getFixesAt('print(10)'); +- expect(errorFixes, hasLength(2)); +- _isSyntacticErrorWithSingleFix(errorFixes[0]); +- _isSyntacticErrorWithSingleFix(errorFixes[1]); +- } +- } +- +- test_overlayOnlyFile() async { +- createProject(); +- testCode = ''' +-main() { +-print(1) +-} +-'''; +- _addOverlay(testFile, testCode); +- // ask for fixes +- await waitForTasksFinished(); +- List errorFixes = await _getFixesAt('print(1)'); +- expect(errorFixes, hasLength(1)); +- _isSyntacticErrorWithSingleFix(errorFixes[0]); +- } +- +- test_suggestImportFromDifferentAnalysisRoot() async { +- // Set up two projects. +- resourceProvider..newFolder("/project1")..newFolder("/project2"); +- handleSuccessfulRequest( +- new AnalysisSetAnalysisRootsParams(["/project1", "/project2"], []) +- .toRequest('0'), +- handler: analysisHandler); +- +- // Set up files. +- testFile = "/project1/main.dart"; +- testCode = "main() { print(new Foo()); }"; +- _addOverlay(testFile, testCode); +- // Add another file in the same project that imports the target file. +- // This ensures it will be analyzed as an implicit Source. +- _addOverlay("/project1/another.dart", 'import "../project2/target.dart";'); +- _addOverlay("/project2/target.dart", "class Foo() {}"); +- +- await waitForTasksFinished(); +- +- List fixes = (await _getFixesAt('Foo()')) +- .single +- .fixes +- .map((f) => f.message) +- .toList(); +- expect(fixes, contains("Import library '../project2/target.dart'")); +- } +- +- void _addOverlay(String name, String contents) { +- Request request = +- new AnalysisUpdateContentParams({name: new AddContentOverlay(contents)}) +- .toRequest('0'); +- handleSuccessfulRequest(request, handler: analysisHandler); +- } +- +- Future> _getFixes(int offset) async { +- Request request = new EditGetFixesParams(testFile, offset).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new EditGetFixesResult.fromResponse(response); +- return result.fixes; +- } +- +- Future> _getFixesAt(String search) async { +- int offset = findOffset(search); +- return await _getFixes(offset); +- } +- +- void _isSyntacticErrorWithSingleFix(AnalysisErrorFixes fixes) { +- AnalysisError error = fixes.error; +- expect(error.severity, AnalysisErrorSeverity.ERROR); +- expect(error.type, AnalysisErrorType.SYNTACTIC_ERROR); +- expect(fixes.fixes, hasLength(1)); +- } +-} +diff --git a/pkg/analysis_server/test/edit/format_test.dart b/pkg/analysis_server/test/edit/format_test.dart +deleted file mode 100644 +index ced5eabf4b8..00000000000 +--- a/pkg/analysis_server/test/edit/format_test.dart ++++ /dev/null +@@ -1,125 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FormatTest); +- }); +-} +- +-@reflectiveTest +-class FormatTest extends AbstractAnalysisTest { +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- } +- +- Future test_format_longLine() { +- String content = ''' +-fun(firstParam, secondParam, thirdParam, fourthParam) { +- if (firstParam.noNull && secondParam.noNull && thirdParam.noNull && fourthParam.noNull) {} +-} +-'''; +- addTestFile(content); +- return waitForTasksFinished().then((_) { +- EditFormatResult formatResult = _formatAt(0, 3, lineLength: 100); +- +- expect(formatResult.edits, isNotNull); +- expect(formatResult.edits, hasLength(0)); +- +- expect(formatResult.selectionOffset, equals(0)); +- expect(formatResult.selectionLength, equals(3)); +- }); +- } +- +- Future test_format_noOp() { +- // Already formatted source +- addTestFile(''' +-main() { +- int x = 3; +-} +-'''); +- return waitForTasksFinished().then((_) { +- EditFormatResult formatResult = _formatAt(0, 3); +- expect(formatResult.edits, isNotNull); +- expect(formatResult.edits, hasLength(0)); +- }); +- } +- +- Future test_format_noSelection() async { +- addTestFile(''' +-main() { int x = 3; } +-'''); +- await waitForTasksFinished(); +- EditFormatResult formatResult = _formatAt(0, 0); +- +- expect(formatResult.edits, isNotNull); +- expect(formatResult.edits, hasLength(1)); +- +- SourceEdit edit = formatResult.edits[0]; +- expect(edit.replacement, equals(''' +-main() { +- int x = 3; +-} +-''')); +- expect(formatResult.selectionOffset, equals(0)); +- expect(formatResult.selectionLength, equals(0)); +- } +- +- Future test_format_simple() { +- addTestFile(''' +-main() { int x = 3; } +-'''); +- return waitForTasksFinished().then((_) { +- EditFormatResult formatResult = _formatAt(0, 3); +- +- expect(formatResult.edits, isNotNull); +- expect(formatResult.edits, hasLength(1)); +- +- SourceEdit edit = formatResult.edits[0]; +- expect(edit.replacement, equals(''' +-main() { +- int x = 3; +-} +-''')); +- expect(formatResult.selectionOffset, equals(0)); +- expect(formatResult.selectionLength, equals(3)); +- }); +- } +- +- Future test_format_withErrors() { +- addTestFile(''' +-main() { int x = +-'''); +- return waitForTasksFinished().then((_) { +- Request request = new EditFormatParams(testFile, 0, 3).toRequest('0'); +- Response response = handler.handleRequest(request); +- expect(response, isResponseFailure('0')); +- }); +- } +- +- EditFormatResult _formatAt(int selectionOffset, int selectionLength, +- {int lineLength}) { +- Request request = new EditFormatParams( +- testFile, selectionOffset, selectionLength, +- lineLength: lineLength) +- .toRequest('0'); +- Response response = handleSuccessfulRequest(request); +- return new EditFormatResult.fromResponse(response); +- } +-} +diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart +deleted file mode 100644 +index cf320de2ca8..00000000000 +--- a/pkg/analysis_server/test/edit/organize_directives_test.dart ++++ /dev/null +@@ -1,167 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OrganizeDirectivesTest); +- }); +-} +- +-@reflectiveTest +-class OrganizeDirectivesTest extends AbstractAnalysisTest { +- SourceFileEdit fileEdit; +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- } +- +- @failingTest +- Future test_BAD_doesNotExist() async { +- // The analysis driver fails to return an error +- Request request = +- new EditOrganizeDirectivesParams('/no/such/file.dart').toRequest('0'); +- Response response = await waitResponse(request); +- expect( +- response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED)); +- } +- +- Future test_BAD_hasParseError() async { +- addTestFile(''' +-import 'dart:async' +- +-main() {} +-'''); +- Request request = new EditOrganizeDirectivesParams(testFile).toRequest('0'); +- Response response = await waitResponse(request); +- expect(response, +- isResponseFailure('0', RequestErrorCode.ORGANIZE_DIRECTIVES_ERROR)); +- } +- +- Future test_BAD_notDartFile() async { +- Request request = +- new EditOrganizeDirectivesParams('/not-a-Dart-file.txt').toRequest('0'); +- Response response = await waitResponse(request); +- expect( +- response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED)); +- } +- +- Future test_OK_remove_duplicateImports_withSamePrefix() { +- addTestFile(''' +-library lib; +- +-import 'dart:async' as async; +-import 'dart:async' as async; +- +-main() { +- async.Future f; +-} +-'''); +- return _assertOrganized(r''' +-library lib; +- +-import 'dart:async' as async; +- +-main() { +- async.Future f; +-} +-'''); +- } +- +- Future test_OK_remove_unresolvedDirectives() { +- addFile('$testFolder/existing_part1.dart', 'part of lib;'); +- addFile('$testFolder/existing_part2.dart', 'part of lib;'); +- addTestFile(''' +-library lib; +- +-export 'dart:noSuchExportSdkLibrary'; +-export 'dart:async'; +-export 'package:noSuchExportPackage/andLib.dart'; +-export 'dart:math'; +- +-import 'dart:async'; +-import 'dart:noSuchImportSdkLibrary'; +-import 'dart:math'; +-import 'package:noSuchImportPackage/andLib.dart'; +- +-part 'existing_part1.dart'; +-part 'no_such_part.dart'; +-part 'existing_part2.dart'; +- +-main(Future f) { +- print(PI); +-} +-'''); +- return _assertOrganized(r''' +-library lib; +- +-import 'dart:async'; +-import 'dart:math'; +- +-export 'dart:async'; +-export 'dart:math'; +- +-part 'existing_part1.dart'; +-part 'existing_part2.dart'; +- +-main(Future f) { +- print(PI); +-} +-'''); +- } +- +- Future test_OK_remove_unusedImports() { +- addTestFile(''' +-library lib; +- +-import 'dart:async'; +-import 'dart:math'; +-import 'dart:convert'; +-import 'dart:collection'; +- +-main() { +- print(PI); +- new HashMap(); +-} +-'''); +- return _assertOrganized(r''' +-library lib; +- +-import 'dart:collection'; +-import 'dart:math'; +- +-main() { +- print(PI); +- new HashMap(); +-} +-'''); +- } +- +- Future _assertOrganized(String expectedCode) async { +- await _requestOrganize(); +- String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits); +- expect(resultCode, expectedCode); +- } +- +- Future _requestOrganize() async { +- Request request = new EditOrganizeDirectivesParams(testFile).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new EditOrganizeDirectivesResult.fromResponse(response); +- fileEdit = result.edit; +- } +-} +diff --git a/pkg/analysis_server/test/edit/postfix_completion_test.dart b/pkg/analysis_server/test/edit/postfix_completion_test.dart +deleted file mode 100644 +index 61fb2f68d68..00000000000 +--- a/pkg/analysis_server/test/edit/postfix_completion_test.dart ++++ /dev/null +@@ -1,93 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(PostfixCompletionTest); +- }); +-} +- +-@reflectiveTest +-class PostfixCompletionTest extends AbstractAnalysisTest { +- SourceChange change; +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- } +- +- test_for() async { +- addTestFile(''' +-main() { +- [].for +-} +-'''); +- await waitForTasksFinished(); +- await _prepareCompletion('.for', atStart: true); +- _assertHasChange('Expand .for', ''' +-main() { +- for (var value in []) { +- /*caret*/ +- } +-} +-'''); +- } +- +- void _assertHasChange(String message, String expectedCode, [Function cmp]) { +- if (change.message == message) { +- if (!change.edits.isEmpty) { +- String resultCode = +- SourceEdit.applySequence(testCode, change.edits[0].edits); +- expect(resultCode, expectedCode.replaceAll('/*caret*/', '')); +- if (cmp != null) { +- int offset = cmp(resultCode); +- expect(change.selection.offset, offset); +- } +- } else { +- if (cmp != null) { +- int offset = cmp(testCode); +- expect(change.selection.offset, offset); +- } +- } +- return; +- } +- fail("Expected to find |$message| but got: " + change.message); +- } +- +- _prepareCompletion(String key, +- {bool atStart: false, bool atEnd: false, int delta: 0}) async { +- int offset = findOffset(key); +- String src = testCode.replaceFirst(key, '', offset); +- modifyTestFile(src); +- await _prepareCompletionAt(offset, key); +- } +- +- _prepareCompletionAt(int offset, String key) async { +- var params = new EditGetPostfixCompletionParams(testFile, key, offset); +- var request = +- new Request('0', "edit.isPostfixCompletionApplicable", params.toJson()); +- Response response = await waitResponse(request); +- var isApplicable = +- new EditIsPostfixCompletionApplicableResult.fromResponse(response); +- if (!isApplicable.value) { +- fail("Postfix completion not applicable at given location"); +- } +- request = new EditGetPostfixCompletionParams(testFile, key, offset) +- .toRequest('1'); +- response = await waitResponse(request); +- var result = new EditGetPostfixCompletionResult.fromResponse(response); +- change = result.change; +- } +-} +diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart +deleted file mode 100644 +index fd225c6d005..00000000000 +--- a/pkg/analysis_server/test/edit/refactoring_test.dart ++++ /dev/null +@@ -1,2016 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ConvertGetterMethodToMethodTest); +- defineReflectiveTests(ConvertMethodToGetterTest); +- defineReflectiveTests(ExtractLocalVariableTest); +- defineReflectiveTests(ExtractMethodTest); +- defineReflectiveTests(GetAvailableRefactoringsTest); +- defineReflectiveTests(InlineLocalTest); +- defineReflectiveTests(InlineMethodTest); +- defineReflectiveTests(MoveFileTest); +- // TODO(brianwilkerson) Re-enable these tests. They were commented out +- // because they are non-deterministic under the new driver. I suspect that +- // there is a future that isn't being waited for. +-// defineReflectiveTests(RenameTest); +- }); +-} +- +-@reflectiveTest +-class ConvertGetterMethodToMethodTest extends _AbstractGetRefactoring_Test { +- test_function() { +- addTestFile(''' +-int get test => 42; +-main() { +- var a = 1 + test; +- var b = 2 + test; +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendConvertRequest('test =>'); +- }, ''' +-int test() => 42; +-main() { +- var a = 1 + test(); +- var b = 2 + test(); +-} +-'''); +- } +- +- test_init_fatalError_notExplicit() { +- addTestFile(''' +-int test = 42; +-main() { +- var v = test; +-} +-'''); +- return getRefactoringResult(() { +- return _sendConvertRequest('test;'); +- }).then((result) { +- assertResultProblemsFatal(result.initialProblems, +- 'Only explicit getters can be converted to methods.'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_method() { +- addTestFile(''' +-class A { +- int get test => 1; +-} +-class B extends A { +- int get test => 2; +-} +-class C extends B { +- int get test => 3; +-} +-class D extends A { +- int get test => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test; +- var vb = b.test; +- var vc = c.test; +- var vd = d.test; +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendConvertRequest('test => 2'); +- }, ''' +-class A { +- int test() => 1; +-} +-class B extends A { +- int test() => 2; +-} +-class C extends B { +- int test() => 3; +-} +-class D extends A { +- int test() => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test(); +- var vb = b.test(); +- var vc = c.test(); +- var vd = d.test(); +-} +-'''); +- } +- +- Future _sendConvertRequest(String search) { +- Request request = new EditGetRefactoringParams( +- RefactoringKind.CONVERT_GETTER_TO_METHOD, +- testFile, +- findOffset(search), +- 0, +- false) +- .toRequest('0'); +- return serverChannel.sendRequest(request); +- } +-} +- +-@reflectiveTest +-class ConvertMethodToGetterTest extends _AbstractGetRefactoring_Test { +- test_function() { +- addTestFile(''' +-int test() => 42; +-main() { +- var a = 1 + test(); +- var b = 2 + test(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendConvertRequest('test() =>'); +- }, ''' +-int get test => 42; +-main() { +- var a = 1 + test; +- var b = 2 + test; +-} +-'''); +- } +- +- test_init_fatalError_hasParameters() { +- addTestFile(''' +-int test(p) => p + 1; +-main() { +- var v = test(2); +-} +-'''); +- return getRefactoringResult(() { +- return _sendConvertRequest('test(p)'); +- }).then((result) { +- assertResultProblemsFatal(result.initialProblems, +- 'Only methods without parameters can be converted to getters.'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_init_fatalError_notExecutableElement() { +- addTestFile(''' +-main() { +- int abc = 1; +- print(abc); +-} +-'''); +- return getRefactoringResult(() { +- return _sendConvertRequest('abc'); +- }).then((result) { +- assertResultProblemsFatal( +- result.initialProblems, 'Unable to create a refactoring'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_method() { +- addTestFile(''' +-class A { +- int test() => 1; +-} +-class B extends A { +- int test() => 2; +-} +-class C extends B { +- int test() => 3; +-} +-class D extends A { +- int test() => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test(); +- var vb = b.test(); +- var vc = c.test(); +- var vd = d.test(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendConvertRequest('test() => 2'); +- }, ''' +-class A { +- int get test => 1; +-} +-class B extends A { +- int get test => 2; +-} +-class C extends B { +- int get test => 3; +-} +-class D extends A { +- int get test => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test; +- var vb = b.test; +- var vc = c.test; +- var vd = d.test; +-} +-'''); +- } +- +- Future _sendConvertRequest(String search) { +- Request request = new EditGetRefactoringParams( +- RefactoringKind.CONVERT_METHOD_TO_GETTER, +- testFile, +- findOffset(search), +- 0, +- false) +- .toRequest('0'); +- return serverChannel.sendRequest(request); +- } +-} +- +-@reflectiveTest +-class ExtractLocalVariableTest extends _AbstractGetRefactoring_Test { +- Future sendExtractRequest( +- int offset, int length, String name, bool extractAll) { +- RefactoringKind kind = RefactoringKind.EXTRACT_LOCAL_VARIABLE; +- ExtractLocalVariableOptions options = +- name != null ? new ExtractLocalVariableOptions(name, extractAll) : null; +- return sendRequest(kind, offset, length, options, false); +- } +- +- Future sendStringRequest( +- String search, String name, bool extractAll) { +- int offset = findOffset(search); +- int length = search.length; +- return sendExtractRequest(offset, length, name, extractAll); +- } +- +- Future sendStringSuffixRequest( +- String search, String suffix, String name, bool extractAll) { +- int offset = findOffset(search + suffix); +- int length = search.length; +- return sendExtractRequest(offset, length, name, extractAll); +- } +- +- void tearDown() { +- test_simulateRefactoringException_init = false; +- test_simulateRefactoringException_final = false; +- test_simulateRefactoringException_change = false; +- super.tearDown(); +- } +- +- test_analysis_onlyOneFile() async { +- shouldWaitForFullAnalysis = false; +- String otherFile = '$testFolder/other.dart'; +- addFile(otherFile, r''' +-foo(int myName) {} +-'''); +- addTestFile(''' +-import 'other.dart'; +-main() { +- foo(1 + 2); +-} +-'''); +- // Start refactoring. +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'res', true); +- }); +- // We get the refactoring feedback.... +- ExtractLocalVariableFeedback feedback = result.feedback; +- expect(feedback.names, contains('myName')); +- } +- +- test_coveringExpressions() { +- addTestFile(''' +-main() { +- var v = 111 + 222 + 333; +-} +-'''); +- return getRefactoringResult(() { +- return sendExtractRequest(testCode.indexOf('222 +'), 0, 'res', true); +- }).then((result) { +- ExtractLocalVariableFeedback feedback = result.feedback; +- expect(feedback.coveringExpressionOffsets, [ +- testCode.indexOf('222 +'), +- testCode.indexOf('111 +'), +- testCode.indexOf('111 +') +- ]); +- expect(feedback.coveringExpressionLengths, +- ['222'.length, '111 + 222'.length, '111 + 222 + 333'.length]); +- }); +- } +- +- test_extractAll() { +- addTestFile(''' +-main() { +- print(1 + 2); +- print(1 + 2); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendStringRequest('1 + 2', 'res', true); +- }, ''' +-main() { +- var res = 1 + 2; +- print(res); +- print(res); +-} +-'''); +- } +- +- test_extractOne() { +- addTestFile(''' +-main() { +- print(1 + 2); +- print(1 + 2); // marker +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendStringSuffixRequest('1 + 2', '); // marker', 'res', false); +- }, ''' +-main() { +- print(1 + 2); +- var res = 1 + 2; +- print(res); // marker +-} +-'''); +- } +- +- test_names() async { +- addTestFile(''' +-class TreeItem {} +-TreeItem getSelectedItem() => null; +-main() { +- var a = getSelectedItem(); +-} +-'''); +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendStringSuffixRequest('getSelectedItem()', ';', null, true); +- }); +- ExtractLocalVariableFeedback feedback = result.feedback; +- expect( +- feedback.names, unorderedEquals(['treeItem', 'item', 'selectedItem'])); +- expect(result.change, isNull); +- } +- +- test_nameWarning() async { +- addTestFile(''' +-main() { +- print(1 + 2); +-} +-'''); +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'Name', true); +- }); +- assertResultProblemsWarning(result.optionsProblems, +- 'Variable name should start with a lowercase letter.'); +- // ...but there is still a change +- assertTestRefactoringResult(result, ''' +-main() { +- var Name = 1 + 2; +- print(Name); +-} +-'''); +- } +- +- test_offsetsLengths() { +- addTestFile(''' +-main() { +- print(1 + 2); +- print(1 + 2); +-} +-'''); +- return getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'res', true); +- }).then((result) { +- ExtractLocalVariableFeedback feedback = result.feedback; +- expect(feedback.offsets, [findOffset('1 + 2'), findOffset('1 + 2')]); +- expect(feedback.lengths, [5, 6]); +- }); +- } +- +- test_resetOnAnalysisSetChanged_overlay() async { +- addTestFile(''' +-main() { +- print(1 + 2); // 0 +-} +-'''); +- +- Future checkUpdate(doUpdate()) async { +- await getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'res', true); +- }); +- int initialResetCount = test_resetCount; +- doUpdate(); +- await pumpEventQueue(); +- expect(test_resetCount, initialResetCount + 1); +- } +- +- await checkUpdate(() { +- server.updateContent('u1', { +- testFile: new AddContentOverlay(''' +-main() { +- print(1 + 2); // 1 +-} +-''') +- }); +- }); +- +- await checkUpdate(() { +- server.updateContent('u2', { +- testFile: new ChangeContentOverlay([ +- new SourceEdit(0, 0, ''' +-main() { +- print(1 + 2); // 2 +-} +-''') +- ]) +- }); +- }); +- +- await checkUpdate(() { +- server.updateContent('u3', {testFile: new RemoveContentOverlay()}); +- }); +- } +- +- test_resetOnAnalysisSetChanged_watch_otherFile() async { +- String otherFile = '$testFolder/other.dart'; +- addFile(otherFile, '// other 1'); +- addTestFile(''' +-main() { +- foo(1 + 2); +-} +-foo(int myName) {} +-'''); +- // Send the first request. +- { +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'res', true); +- }); +- ExtractLocalVariableFeedback feedback = result.feedback; +- expect(feedback.names, contains('myName')); +- } +- int initialResetCount = test_resetCount; +- // Update the other.dart file. +- // The refactoring is reset, even though it's a different file. It is up to +- // analyzer to track dependencies and provide resolved units fast when +- // possible. +- addFile(otherFile, '// other 2'); +- await pumpEventQueue(); +- expect(test_resetCount, initialResetCount + 1); +- } +- +- test_resetOnAnalysisSetChanged_watch_thisFile() async { +- addTestFile(''' +-main() { +- foo(1 + 2); +-} +-foo(int myName) {} +-'''); +- // Send the first request. +- { +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'res', true); +- }); +- ExtractLocalVariableFeedback feedback = result.feedback; +- expect(feedback.names, contains('myName')); +- } +- int initialResetCount = test_resetCount; +- // Update the test.dart file. +- modifyTestFile(''' +-main() { +- foo(1 + 2); +-} +-foo(int otherName) {} +-'''); +- // The refactoring was reset. +- await pumpEventQueue(); +- expect(test_resetCount, initialResetCount + 1); +- // Send the second request, with the same kind, file and offset. +- { +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendStringRequest('1 + 2', 'res', true); +- }); +- ExtractLocalVariableFeedback feedback = result.feedback; +- // The refactoring was reset, so we don't get stale results. +- expect(feedback.names, contains('otherName')); +- } +- } +- +- test_serverError_change() { +- test_simulateRefactoringException_change = true; +- addTestFile(''' +-main() { +- print(1 + 2); +-} +-'''); +- return waitForTasksFinished().then((_) { +- return sendStringRequest('1 + 2', 'res', true).then((response) { +- expect(response.error, isNotNull); +- expect(response.error.code, RequestErrorCode.SERVER_ERROR); +- }); +- }); +- } +- +- test_serverError_final() { +- test_simulateRefactoringException_final = true; +- addTestFile(''' +-main() { +- print(1 + 2); +-} +-'''); +- return waitForTasksFinished().then((_) { +- return sendStringRequest('1 + 2', 'res', true).then((response) { +- expect(response.error, isNotNull); +- expect(response.error.code, RequestErrorCode.SERVER_ERROR); +- }); +- }); +- } +- +- test_serverError_init() { +- test_simulateRefactoringException_init = true; +- addTestFile(''' +-main() { +- print(1 + 2); +-} +-'''); +- return waitForTasksFinished().then((_) { +- return sendStringRequest('1 + 2', 'res', true).then((response) { +- expect(response.error, isNotNull); +- expect(response.error.code, RequestErrorCode.SERVER_ERROR); +- }); +- }); +- } +-} +- +-@reflectiveTest +-class ExtractMethodTest extends _AbstractGetRefactoring_Test { +- int offset; +- int length; +- String name = 'res'; +- ExtractMethodOptions options; +- +- test_expression() { +- addTestFile(''' +-main() { +- print(1 + 2); +- print(1 + 2); +-} +-'''); +- _setOffsetLengthForString('1 + 2'); +- return assertSuccessfulRefactoring(_computeChange, ''' +-main() { +- print(res()); +- print(res()); +-} +- +-int res() => 1 + 2; +-'''); +- } +- +- test_expression_hasParameters() { +- addTestFile(''' +-main() { +- int a = 1; +- int b = 2; +- print(a + b); +- print(a + b); +-} +-'''); +- _setOffsetLengthForString('a + b'); +- return assertSuccessfulRefactoring(_computeChange, ''' +-main() { +- int a = 1; +- int b = 2; +- print(res(a, b)); +- print(res(a, b)); +-} +- +-int res(int a, int b) => a + b; +-'''); +- } +- +- test_expression_updateParameters() { +- addTestFile(''' +-main() { +- int a = 1; +- int b = 2; +- print(a + b); +- print(a + b); +-} +-'''); +- _setOffsetLengthForString('a + b'); +- return getRefactoringResult(_computeChange).then((result) { +- ExtractMethodFeedback feedback = result.feedback; +- List parameters = feedback.parameters; +- parameters[0].name = 'aaa'; +- parameters[1].name = 'bbb'; +- parameters[1].type = 'num'; +- parameters.insert(0, parameters.removeLast()); +- options.parameters = parameters; +- return assertSuccessfulRefactoring(_sendExtractRequest, ''' +-main() { +- int a = 1; +- int b = 2; +- print(res(b, a)); +- print(res(b, a)); +-} +- +-int res(num bbb, int aaa) => aaa + bbb; +-'''); +- }); +- } +- +- test_init_fatalError_invalidStatement() { +- addTestFile(''' +-main(bool b) { +-// start +- if (b) { +- print(1); +-// end +- print(2); +- } +-} +-'''); +- _setOffsetLengthForStartEnd(); +- return waitForTasksFinished().then((_) { +- return _sendExtractRequest(); +- }).then((Response response) { +- var result = new EditGetRefactoringResult.fromResponse(response); +- assertResultProblemsFatal(result.initialProblems); +- // ...there is no any feedback +- expect(result.feedback, isNull); +- }); +- } +- +- test_long_expression() { +- addTestFile(''' +-main() { +- print(1 + +- 2); +-} +-'''); +- _setOffsetLengthForString('1 +\n 2'); +- return assertSuccessfulRefactoring(_computeChange, ''' +-main() { +- print(res()); +-} +- +-int res() { +- return 1 + +- 2; +-} +-'''); +- } +- +- test_names() { +- addTestFile(''' +-class TreeItem {} +-TreeItem getSelectedItem() => null; +-main() { +- var a = getSelectedItem( ); +-} +-'''); +- _setOffsetLengthForString('getSelectedItem( )'); +- return _computeInitialFeedback().then((feedback) { +- expect(feedback.names, +- unorderedEquals(['treeItem', 'item', 'selectedItem'])); +- expect(feedback.returnType, 'TreeItem'); +- }); +- } +- +- test_offsetsLengths() { +- addTestFile(''' +-class TreeItem {} +-TreeItem getSelectedItem() => null; +-main() { +- var a = 1 + 2; +- var b = 1 + 2; +-} +-'''); +- _setOffsetLengthForString('1 + 2'); +- return _computeInitialFeedback().then((feedback) { +- expect(feedback.offsets, [findOffset('1 + 2'), findOffset('1 + 2')]); +- expect(feedback.lengths, [5, 6]); +- }); +- } +- +- test_statements() { +- addTestFile(''' +-main() { +- int a = 1; +- int b = 2; +-// start +- print(a + b); +-// end +- print(a + b); +-} +-'''); +- _setOffsetLengthForStartEnd(); +- return assertSuccessfulRefactoring(_computeChange, ''' +-main() { +- int a = 1; +- int b = 2; +-// start +- res(a, b); +-// end +- res(a, b); +-} +- +-void res(int a, int b) { +- print(a + b); +-} +-'''); +- } +- +- Future _computeChange() async { +- await _prepareOptions(); +- // send request with the options +- return _sendExtractRequest(); +- } +- +- Future _computeInitialFeedback() async { +- await waitForTasksFinished(); +- Response response = await _sendExtractRequest(); +- var result = new EditGetRefactoringResult.fromResponse(response); +- return result.feedback; +- } +- +- Future _prepareOptions() { +- return getRefactoringResult(() { +- // get initial feedback +- return _sendExtractRequest(); +- }).then((result) { +- assertResultProblemsOK(result); +- // fill options from result +- ExtractMethodFeedback feedback = result.feedback; +- options = new ExtractMethodOptions( +- feedback.returnType, false, name, feedback.parameters, true); +- // done +- return new Future.value(); +- }); +- } +- +- Future _sendExtractRequest() { +- RefactoringKind kind = RefactoringKind.EXTRACT_METHOD; +- return sendRequest(kind, offset, length, options, false); +- } +- +- void _setOffsetLengthForStartEnd() { +- offset = findOffset('// start') + '// start\n'.length; +- length = findOffset('// end') - offset; +- } +- +- void _setOffsetLengthForString(String search) { +- offset = findOffset(search); +- length = search.length; +- } +-} +- +-@reflectiveTest +-class GetAvailableRefactoringsTest extends AbstractAnalysisTest { +- List kinds; +- +- /** +- * Tests that there is refactoring of the given [kind] is available at the +- * [search] offset. +- */ +- Future assertHasKind( +- String code, String search, RefactoringKind kind, bool expected) async { +- addTestFile(code); +- await waitForTasksFinished(); +- await getRefactoringsAtString(search); +- // verify +- Matcher matcher = contains(kind); +- if (!expected) { +- matcher = isNot(matcher); +- } +- expect(kinds, matcher); +- } +- +- /** +- * Tests that there is a RENAME refactoring available at the [search] offset. +- */ +- Future assertHasRenameRefactoring(String code, String search) async { +- return assertHasKind(code, search, RefactoringKind.RENAME, true); +- } +- +- /** +- * Returns the list of available refactorings for the given [offset] and +- * [length]. +- */ +- Future getRefactorings(int offset, int length) async { +- Request request = +- new EditGetAvailableRefactoringsParams(testFile, offset, length) +- .toRequest('0'); +- serverChannel.sendRequest(request); +- var response = await serverChannel.waitForResponse(request); +- var result = new EditGetAvailableRefactoringsResult.fromResponse(response); +- kinds = result.kinds; +- } +- +- /** +- * Returns the list of available refactorings at the offset of [search]. +- */ +- Future getRefactoringsAtString(String search) { +- int offset = findOffset(search); +- return getRefactorings(offset, 0); +- } +- +- Future getRefactoringsForString(String search) { +- int offset = findOffset(search); +- return getRefactorings(offset, search.length); +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- server.handlers = [handler]; +- } +- +- Future test_convertMethodToGetter_hasElement() { +- return assertHasKind(''' +-int getValue() => 42; +-''', 'getValue', RefactoringKind.CONVERT_METHOD_TO_GETTER, true); +- } +- +- Future test_extractLocal() async { +- addTestFile(''' +-main() { +- var a = 1 + 2; +-} +-'''); +- await waitForTasksFinished(); +- await getRefactoringsForString('1 + 2'); +- expect(kinds, contains(RefactoringKind.EXTRACT_LOCAL_VARIABLE)); +- expect(kinds, contains(RefactoringKind.EXTRACT_METHOD)); +- } +- +- Future test_rename_hasElement_class() { +- return assertHasRenameRefactoring(''' +-class Test {} +-main() { +- Test v; +-} +-''', 'Test v'); +- } +- +- Future test_rename_hasElement_constructor() { +- return assertHasRenameRefactoring(''' +-class A { +- A.test() {} +-} +-main() { +- new A.test(); +-} +-''', 'test();'); +- } +- +- Future test_rename_hasElement_function() { +- return assertHasRenameRefactoring(''' +-main() { +- test(); +-} +-test() {} +-''', 'test();'); +- } +- +- Future test_rename_hasElement_importElement_directive() { +- return assertHasRenameRefactoring(''' +-import 'dart:math' as math; +-main() { +- math.PI; +-} +-''', 'import '); +- } +- +- Future test_rename_hasElement_importElement_prefixDecl() { +- return assertHasRenameRefactoring(''' +-import 'dart:math' as math; +-main() { +- math.PI; +-} +-''', 'math;'); +- } +- +- Future test_rename_hasElement_importElement_prefixRef() { +- return assertHasRenameRefactoring(''' +-import 'dart:async' as test; +-import 'dart:math' as test; +-main() { +- test.PI; +-} +-''', 'test.PI;'); +- } +- +- Future test_rename_hasElement_instanceGetter() { +- return assertHasRenameRefactoring(''' +-class A { +- get test => 0; +-} +-main(A a) { +- a.test; +-} +-''', 'test;'); +- } +- +- Future test_rename_hasElement_instanceSetter() { +- return assertHasRenameRefactoring(''' +-class A { +- set test(x) {} +-} +-main(A a) { +- a.test = 2; +-} +-''', 'test = 2;'); +- } +- +- Future test_rename_hasElement_library() { +- return assertHasRenameRefactoring(''' +-library my.lib; +-''', 'library '); +- } +- +- Future test_rename_hasElement_localVariable() { +- return assertHasRenameRefactoring(''' +-main() { +- int test = 0; +- print(test); +-} +-''', 'test = 0;'); +- } +- +- Future test_rename_hasElement_method() { +- return assertHasRenameRefactoring(''' +-class A { +- test() {} +-} +-main(A a) { +- a.test(); +-} +-''', 'test();'); +- } +- +- Future test_rename_noElement() async { +- addTestFile(''' +-main() { +- // not an element +-} +-'''); +- await waitForTasksFinished(); +- await getRefactoringsAtString('// not an element'); +- expect(kinds, isNot(contains(RefactoringKind.RENAME))); +- } +-} +- +-@reflectiveTest +-class InlineLocalTest extends _AbstractGetRefactoring_Test { +- test_analysis_onlyOneFile() async { +- shouldWaitForFullAnalysis = false; +- String otherFile = '$testFolder/other.dart'; +- addFile(otherFile, r''' +-foo(int p) {} +-'''); +- addTestFile(''' +-import 'other.dart'; +-main() { +- int res = 1 + 2; +- foo(res); +- foo(res); +-} +-'''); +- // Start refactoring. +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return _sendInlineRequest('res ='); +- }); +- // We get the refactoring feedback.... +- InlineLocalVariableFeedback feedback = result.feedback; +- expect(feedback.occurrences, 2); +- } +- +- test_feedback() { +- addTestFile(''' +-main() { +- int test = 42; +- print(test); +- print(test); +-} +-'''); +- return getRefactoringResult(() { +- return _sendInlineRequest('test ='); +- }).then((result) { +- InlineLocalVariableFeedback feedback = result.feedback; +- expect(feedback.name, 'test'); +- expect(feedback.occurrences, 2); +- }); +- } +- +- test_init_fatalError_notVariable() { +- addTestFile('main() {}'); +- return getRefactoringResult(() { +- return _sendInlineRequest('main() {}'); +- }).then((result) { +- assertResultProblemsFatal(result.initialProblems, +- 'Local variable declaration or reference must be selected to activate this refactoring.'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_OK() { +- addTestFile(''' +-main() { +- int test = 42; +- int a = test + 2; +- print(test); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendInlineRequest('test + 2'); +- }, ''' +-main() { +- int a = 42 + 2; +- print(42); +-} +-'''); +- } +- +- test_resetOnAnalysisSetChanged() async { +- String otherFile = '$testFolder/other.dart'; +- addFile(otherFile, '// other 1'); +- addTestFile(''' +-main() { +- int res = 1 + 2; +- print(res); +-} +-'''); +- // Send the first request. +- await getRefactoringResult(() { +- return _sendInlineRequest('res = '); +- }); +- int initialResetCount = test_resetCount; +- // Update the test.dart file. +- modifyTestFile(''' +-main() { +- print(1 + 2); +-} +-'''); +- // The refactoring was reset. +- await pumpEventQueue(); +- expect(test_resetCount, initialResetCount + 1); +- } +- +- Future _sendInlineRequest(String search) { +- Request request = new EditGetRefactoringParams( +- RefactoringKind.INLINE_LOCAL_VARIABLE, +- testFile, +- findOffset(search), +- 0, +- false) +- .toRequest('0'); +- return serverChannel.sendRequest(request); +- } +-} +- +-@reflectiveTest +-class InlineMethodTest extends _AbstractGetRefactoring_Test { +- InlineMethodOptions options = new InlineMethodOptions(true, true); +- +- test_feedback() { +- addTestFile(''' +-class A { +- int f; +- test(int p) { +- print(f + p); +- } +- main() { +- test(1); +- } +-} +-'''); +- return getRefactoringResult(() { +- return _sendInlineRequest('test(int p)'); +- }).then((result) { +- InlineMethodFeedback feedback = result.feedback; +- expect(feedback.className, 'A'); +- expect(feedback.methodName, 'test'); +- expect(feedback.isDeclaration, isTrue); +- }); +- } +- +- test_init_fatalError_noMethod() { +- addTestFile('// nothing to inline'); +- return getRefactoringResult(() { +- return _sendInlineRequest('// nothing'); +- }).then((result) { +- assertResultProblemsFatal(result.initialProblems, +- 'Method declaration or reference must be selected to activate this refactoring.'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_method() { +- addTestFile(''' +-class A { +- int f; +- test(int p) { +- print(f + p); +- } +- main() { +- test(1); +- } +-} +-main(A a) { +- a.test(2); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendInlineRequest('test(int p)'); +- }, ''' +-class A { +- int f; +- main() { +- print(f + 1); +- } +-} +-main(A a) { +- print(a.f + 2); +-} +-'''); +- } +- +- test_topLevelFunction() { +- addTestFile(''' +-test(a, b) { +- print(a + b); +-} +-main() { +- test(1, 2); +- test(10, 20); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return _sendInlineRequest('test(a'); +- }, ''' +-main() { +- print(1 + 2); +- print(10 + 20); +-} +-'''); +- } +- +- test_topLevelFunction_oneInvocation() { +- addTestFile(''' +-test(a, b) { +- print(a + b); +-} +-main() { +- test(1, 2); +- test(10, 20); +-} +-'''); +- options.deleteSource = false; +- options.inlineAll = false; +- return assertSuccessfulRefactoring(() { +- return _sendInlineRequest('test(10,'); +- }, ''' +-test(a, b) { +- print(a + b); +-} +-main() { +- test(1, 2); +- print(10 + 20); +-} +-'''); +- } +- +- Future _sendInlineRequest(String search) { +- Request request = new EditGetRefactoringParams( +- RefactoringKind.INLINE_METHOD, +- testFile, +- findOffset(search), +- 0, +- false, +- options: options) +- .toRequest('0'); +- return serverChannel.sendRequest(request); +- } +-} +- +-@reflectiveTest +-class MoveFileTest extends _AbstractGetRefactoring_Test { +- MoveFileOptions options; +- +- @failingTest +- test_OK() { +- fail('The move file refactoring is not supported under the new driver'); +- resourceProvider.newFile('/project/bin/lib.dart', ''); +- addTestFile(''' +-import 'dart:math'; +-import 'lib.dart'; +-'''); +- _setOptions('/project/test.dart'); +- return assertSuccessfulRefactoring(() { +- return _sendMoveRequest(); +- }, ''' +-import 'dart:math'; +-import 'bin/lib.dart'; +-'''); +- } +- +- Future _sendMoveRequest() { +- Request request = new EditGetRefactoringParams( +- RefactoringKind.MOVE_FILE, testFile, 0, 0, false, +- options: options) +- .toRequest('0'); +- return serverChannel.sendRequest(request); +- } +- +- void _setOptions(String newFile) { +- options = new MoveFileOptions(newFile); +- } +-} +- +-@reflectiveTest +-class RenameTest extends _AbstractGetRefactoring_Test { +- Future sendRenameRequest(String search, String newName, +- {String id: '0', bool validateOnly: false}) { +- RenameOptions options = newName != null ? new RenameOptions(newName) : null; +- Request request = new EditGetRefactoringParams(RefactoringKind.RENAME, +- testFile, findOffset(search), 0, validateOnly, +- options: options) +- .toRequest(id); +- return serverChannel.sendRequest(request); +- } +- +- void tearDown() { +- test_simulateRefactoringReset_afterInitialConditions = false; +- test_simulateRefactoringReset_afterFinalConditions = false; +- test_simulateRefactoringReset_afterCreateChange = false; +- super.tearDown(); +- } +- +- test_cancelPendingRequest() async { +- addTestFile(''' +-main() { +- int test = 0; +- print(test); +-} +-'''); +- // send the "1" request, but don't wait for it +- Future futureA = sendRenameRequest('test =', 'nameA', id: '1'); +- // send the "2" request and wait for it +- Response responseB = await sendRenameRequest('test =', 'nameB', id: '2'); +- // wait for the (delayed) "1" response +- Response responseA = await futureA; +- // "1" was cancelled +- // "2" is successful +- expect(responseA, +- isResponseFailure('1', RequestErrorCode.REFACTORING_REQUEST_CANCELLED)); +- expect(responseB, isResponseSuccess('2')); +- } +- +- test_class() { +- addTestFile(''' +-class Test { +- Test() {} +- Test.named() {} +-} +-main() { +- Test v; +- new Test(); +- new Test.named(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('Test {', 'NewName'); +- }, ''' +-class NewName { +- NewName() {} +- NewName.named() {} +-} +-main() { +- NewName v; +- new NewName(); +- new NewName.named(); +-} +-'''); +- } +- +- test_class_options_fatalError() { +- addTestFile(''' +-class Test {} +-main() { +- Test v; +-} +-'''); +- return getRefactoringResult(() { +- return sendRenameRequest('Test {}', ''); +- }).then((result) { +- assertResultProblemsFatal( +- result.optionsProblems, 'Class name must not be empty.'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_class_validateOnly() { +- addTestFile(''' +-class Test {} +-main() { +- Test v; +-} +-'''); +- return getRefactoringResult(() { +- return sendRenameRequest('Test {}', 'NewName', validateOnly: true); +- }).then((result) { +- RenameFeedback feedback = result.feedback; +- assertResultProblemsOK(result); +- expect(feedback.elementKindName, 'class'); +- expect(feedback.oldName, 'Test'); +- expect(result.change, isNull); +- }); +- } +- +- test_class_warning() { +- addTestFile(''' +-class Test {} +-main() { +- Test v; +-} +-'''); +- return getRefactoringResult(() { +- return sendRenameRequest('Test {}', 'newName'); +- }).then((result) { +- assertResultProblemsWarning(result.optionsProblems, +- 'Class name should start with an uppercase letter.'); +- // ...but there is still a change +- assertTestRefactoringResult(result, ''' +-class newName {} +-main() { +- newName v; +-} +-'''); +- }).then((_) { +- // "NewName" is a perfectly valid name +- return getRefactoringResult(() { +- return sendRenameRequest('Test {}', 'NewName'); +- }).then((result) { +- assertResultProblemsOK(result); +- // ...and there is a new change +- assertTestRefactoringResult(result, ''' +-class NewName {} +-main() { +- NewName v; +-} +-'''); +- }); +- }); +- } +- +- test_classMember_field() { +- addTestFile(''' +-class A { +- var test = 0; +- A(this.test); +- main() { +- print(test); +- } +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test = 0', 'newName'); +- }, ''' +-class A { +- var newName = 0; +- A(this.newName); +- main() { +- print(newName); +- } +-} +-'''); +- } +- +- test_classMember_field_onFieldFormalParameter() { +- addTestFile(''' +-class A { +- var test = 0; +- A(this.test); +- main() { +- print(test); +- } +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test);', 'newName'); +- }, ''' +-class A { +- var newName = 0; +- A(this.newName); +- main() { +- print(newName); +- } +-} +-'''); +- } +- +- test_classMember_field_onFieldFormalParameter_named() { +- addTestFile(''' +-class A { +- final int test; +- A({this.test: 0}); +-} +-main() { +- new A(test: 42); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test: 42', 'newName'); +- }, ''' +-class A { +- final int newName; +- A({this.newName: 0}); +-} +-main() { +- new A(newName: 42); +-} +-'''); +- } +- +- test_classMember_getter() { +- addTestFile(''' +-class A { +- get test => 0; +- main() { +- print(test); +- } +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test =>', 'newName'); +- }, ''' +-class A { +- get newName => 0; +- main() { +- print(newName); +- } +-} +-'''); +- } +- +- test_classMember_method() { +- addTestFile(''' +-class A { +- test() {} +- main() { +- test(); +- } +-} +-main(A a) { +- a.test(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test() {}', 'newName'); +- }, ''' +-class A { +- newName() {} +- main() { +- newName(); +- } +-} +-main(A a) { +- a.newName(); +-} +-'''); +- } +- +- test_classMember_method_potential() { +- addTestFile(''' +-class A { +- test() {} +-} +-main(A a, a2) { +- a.test(); +- a2.test(); // a2 +-} +-'''); +- return getRefactoringResult(() { +- return sendRenameRequest('test() {}', 'newName'); +- }).then((result) { +- assertResultProblemsOK(result); +- // prepare potential edit ID +- List potentialIds = result.potentialEdits; +- expect(potentialIds, hasLength(1)); +- String potentialId = potentialIds[0]; +- // find potential edit +- SourceChange change = result.change; +- SourceEdit potentialEdit = _findEditWithId(change, potentialId); +- expect(potentialEdit, isNotNull); +- expect(potentialEdit.offset, findOffset('test(); // a2')); +- expect(potentialEdit.length, 4); +- }); +- } +- +- test_classMember_setter() { +- addTestFile(''' +-class A { +- set test(x) {} +- main() { +- test = 0; +- } +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test = 0', 'newName'); +- }, ''' +-class A { +- set newName(x) {} +- main() { +- newName = 0; +- } +-} +-'''); +- } +- +- test_constructor_fromFactoryRedirectingConstructor_onClassName() { +- addTestFile(''' +-class A { +- A() = B; +-} +-class B { +- B() {} +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('B;', 'newName'); +- }, ''' +-class A { +- A() = B.newName; +-} +-class B { +- B.newName() {} +-} +-'''); +- } +- +- test_constructor_fromInstanceCreation() { +- addTestFile(''' +-class A { +- A.test() {} +-} +-main() { +- new A.test(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test();', 'newName'); +- }, ''' +-class A { +- A.newName() {} +-} +-main() { +- new A.newName(); +-} +-'''); +- } +- +- test_constructor_fromInstanceCreation_default_onClassName() { +- addTestFile(''' +-class A { +- A() {} +-} +-main() { +- new A(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('A();', 'newName'); +- }, ''' +-class A { +- A.newName() {} +-} +-main() { +- new A.newName(); +-} +-'''); +- } +- +- test_constructor_fromInstanceCreation_default_onNew() { +- addTestFile(''' +-class A { +- A() {} +-} +-main() { +- new A(); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('new A();', 'newName'); +- }, ''' +-class A { +- A.newName() {} +-} +-main() { +- new A.newName(); +-} +-'''); +- } +- +- test_feedback() { +- addTestFile(''' +-class Test {} +-main() { +- Test v; +-} +-'''); +- return getRefactoringResult(() { +- return sendRenameRequest('st v;', 'NewName'); +- }).then((result) { +- RenameFeedback feedback = result.feedback; +- expect(feedback, isNotNull); +- expect(feedback.offset, findOffset('Test v;')); +- expect(feedback.length, 'Test'.length); +- }); +- } +- +- test_function() { +- addTestFile(''' +-test() {} +-main() { +- test(); +- print(test); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test() {}', 'newName'); +- }, ''' +-newName() {} +-main() { +- newName(); +- print(newName); +-} +-'''); +- } +- +- test_importPrefix_add() { +- addTestFile(''' +-import 'dart:math'; +-import 'dart:async'; +-main() { +- Random r; +- Future f; +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest("import 'dart:async';", 'new_name'); +- }, ''' +-import 'dart:math'; +-import 'dart:async' as new_name; +-main() { +- Random r; +- new_name.Future f; +-} +-'''); +- } +- +- test_importPrefix_remove() { +- addTestFile(''' +-import 'dart:math' as test; +-import 'dart:async' as test; +-main() { +- test.Random r; +- test.Future f; +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest("import 'dart:async' as test;", ''); +- }, ''' +-import 'dart:math' as test; +-import 'dart:async'; +-main() { +- test.Random r; +- Future f; +-} +-'''); +- } +- +- test_init_fatalError_noElement() { +- addTestFile('// nothing to rename'); +- return getRefactoringResult(() { +- return sendRenameRequest('// nothing', null); +- }).then((result) { +- assertResultProblemsFatal( +- result.initialProblems, 'Unable to create a refactoring'); +- // ...there is no any change +- expect(result.change, isNull); +- }); +- } +- +- test_library_libraryDirective() { +- addTestFile(''' +-library aaa.bbb.ccc; +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('library aaa', 'my.new_name'); +- }, ''' +-library my.new_name; +-'''); +- } +- +- test_library_libraryDirective_name() { +- addTestFile(''' +-library aaa.bbb.ccc; +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('aaa', 'my.new_name'); +- }, ''' +-library my.new_name; +-'''); +- } +- +- test_library_libraryDirective_nameDot() { +- addTestFile(''' +-library aaa.bbb.ccc; +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('.bbb', 'my.new_name'); +- }, ''' +-library my.new_name; +-'''); +- } +- +- test_library_partOfDirective() { +- addFile('$testFolder/my_lib.dart', ''' +-library aaa.bbb.ccc; +-part 'test.dart'; +-'''); +- addTestFile(''' +-part of aaa.bbb.ccc; +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('aaa.bb', 'my.new_name'); +- }, ''' +-part of my.new_name; +-'''); +- } +- +- test_localVariable() { +- addTestFile(''' +-main() { +- int test = 0; +- test = 1; +- test += 2; +- print(test); +-} +-'''); +- return assertSuccessfulRefactoring(() { +- return sendRenameRequest('test = 1', 'newName'); +- }, ''' +-main() { +- int newName = 0; +- newName = 1; +- newName += 2; +- print(newName); +-} +-'''); +- } +- +- test_localVariable_finalCheck_shadowError() { +- addTestFile(''' +-main() { +- var newName; +- int test = 0; +- print(test); +-} +-'''); +- return getRefactoringResult(() { +- return sendRenameRequest('test = 0', 'newName'); +- }).then((result) { +- List problems = result.finalProblems; +- expect(problems, hasLength(1)); +- assertResultProblemsError( +- problems, "Duplicate local variable 'newName'."); +- }); +- } +- +- test_reset_afterCreateChange() { +- test_simulateRefactoringReset_afterCreateChange = true; +- addTestFile(''' +-test() {} +-main() { +- test(); +-} +-'''); +- return waitForTasksFinished().then((_) { +- return sendRenameRequest('test() {}', 'newName').then((response) { +- _expectRefactoringRequestCancelled(response); +- }); +- }); +- } +- +- test_reset_afterFinalConditions() { +- test_simulateRefactoringReset_afterFinalConditions = true; +- addTestFile(''' +-test() {} +-main() { +- test(); +-} +-'''); +- return waitForTasksFinished().then((_) { +- return sendRenameRequest('test() {}', 'newName').then((response) { +- _expectRefactoringRequestCancelled(response); +- }); +- }); +- } +- +- test_reset_afterInitialConditions() { +- test_simulateRefactoringReset_afterInitialConditions = true; +- addTestFile(''' +-test() {} +-main() { +- test(); +-} +-'''); +- return waitForTasksFinished().then((_) { +- return sendRenameRequest('test() {}', 'newName').then((response) { +- _expectRefactoringRequestCancelled(response); +- }); +- }); +- } +- +- test_resetOnAnalysis() async { +- addTestFile(''' +-main() { +- int initialName = 0; +- print(initialName); +-} +-'''); +- // send the first request +- EditGetRefactoringResult result = await getRefactoringResult(() { +- return sendRenameRequest('initialName =', 'newName', validateOnly: true); +- }); +- _validateFeedback(result, oldName: 'initialName'); +- // update the file +- modifyTestFile(''' +-main() { +- int otherName = 0; +- print(otherName); +-} +-'''); +- server.getAnalysisDriver(testFile).getResult(testFile); +- // send the second request, with the same kind, file and offset +- await waitForTasksFinished(); +- result = await getRefactoringResult(() { +- return sendRenameRequest('otherName =', 'newName', validateOnly: true); +- }); +- // the refactoring was reset, so we don't get a stale result +- _validateFeedback(result, oldName: 'otherName'); +- } +- +- void _expectRefactoringRequestCancelled(Response response) { +- expect(response.error, isNotNull); +- expect(response, +- isResponseFailure('0', RequestErrorCode.REFACTORING_REQUEST_CANCELLED)); +- } +- +- SourceEdit _findEditWithId(SourceChange change, String id) { +- SourceEdit potentialEdit; +- change.edits.forEach((fileEdit) { +- fileEdit.edits.forEach((edit) { +- if (edit.id == id) { +- potentialEdit = edit; +- } +- }); +- }); +- return potentialEdit; +- } +- +- void _validateFeedback(EditGetRefactoringResult result, {String oldName}) { +- RenameFeedback feedback = result.feedback; +- expect(feedback, isNotNull); +- if (oldName != null) { +- expect(feedback.oldName, oldName); +- } +- } +-} +- +-@reflectiveTest +-class _AbstractGetRefactoring_Test extends AbstractAnalysisTest { +- bool shouldWaitForFullAnalysis = true; +- +- /** +- * Asserts that [problems] has a single ERROR problem. +- */ +- void assertResultProblemsError(List problems, +- [String message]) { +- RefactoringProblem problem = problems[0]; +- expect(problem.severity, RefactoringProblemSeverity.ERROR, +- reason: problem.toString()); +- if (message != null) { +- expect(problem.message, message); +- } +- } +- +- /** +- * Asserts that [result] has a single FATAL problem. +- */ +- void assertResultProblemsFatal(List problems, +- [String message]) { +- RefactoringProblem problem = problems[0]; +- expect(problems, hasLength(1)); +- expect(problem.severity, RefactoringProblemSeverity.FATAL, +- reason: problem.toString()); +- if (message != null) { +- expect(problem.message, message); +- } +- } +- +- /** +- * Asserts that [result] has no problems at all. +- */ +- void assertResultProblemsOK(EditGetRefactoringResult result) { +- expect(result.initialProblems, isEmpty); +- expect(result.optionsProblems, isEmpty); +- expect(result.finalProblems, isEmpty); +- } +- +- /** +- * Asserts that [result] has a single WARNING problem. +- */ +- void assertResultProblemsWarning(List problems, +- [String message]) { +- RefactoringProblem problem = problems[0]; +- expect(problems, hasLength(1)); +- expect(problem.severity, RefactoringProblemSeverity.WARNING, +- reason: problem.toString()); +- if (message != null) { +- expect(problem.message, message); +- } +- } +- +- Future assertSuccessfulRefactoring( +- Future requestSender(), String expectedCode) async { +- EditGetRefactoringResult result = await getRefactoringResult(requestSender); +- assertResultProblemsOK(result); +- assertTestRefactoringResult(result, expectedCode); +- } +- +- /** +- * Asserts that the given [EditGetRefactoringResult] has a [testFile] change +- * which results in the [expectedCode]. +- */ +- void assertTestRefactoringResult( +- EditGetRefactoringResult result, String expectedCode) { +- SourceChange change = result.change; +- expect(change, isNotNull); +- for (SourceFileEdit fileEdit in change.edits) { +- if (fileEdit.file == testFile) { +- String actualCode = SourceEdit.applySequence(testCode, fileEdit.edits); +- expect(actualCode, expectedCode); +- return; +- } +- } +- fail('No SourceFileEdit for $testFile in $change'); +- } +- +- Future getRefactoringResult( +- Future requestSender()) async { +- if (shouldWaitForFullAnalysis) { +- await waitForTasksFinished(); +- } +- Response response = await requestSender(); +- return new EditGetRefactoringResult.fromResponse(response); +- } +- +- Future sendRequest( +- RefactoringKind kind, int offset, int length, RefactoringOptions options, +- [bool validateOnly = false]) { +- Request request = new EditGetRefactoringParams( +- kind, testFile, offset, length, validateOnly, +- options: options) +- .toRequest('0'); +- return serverChannel.sendRequest(request); +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- server.handlers = [handler]; +- } +-} +diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart +deleted file mode 100644 +index abce2a0fe49..00000000000 +--- a/pkg/analysis_server/test/edit/sort_members_test.dart ++++ /dev/null +@@ -1,256 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SortMembersTest); +- }); +-} +- +-@reflectiveTest +-class SortMembersTest extends AbstractAnalysisTest { +- SourceFileEdit fileEdit; +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- } +- +- @failingTest +- test_BAD_doesNotExist() async { +- // The analysis driver fails to return an error +- Request request = +- new EditSortMembersParams('/no/such/file.dart').toRequest('0'); +- Response response = await waitResponse(request); +- expect(response, +- isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE)); +- } +- +- test_BAD_hasParseError() async { +- addTestFile(''' +-main() { +- print() +-} +-'''); +- Request request = new EditSortMembersParams(testFile).toRequest('0'); +- Response response = await waitResponse(request); +- expect(response, +- isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS)); +- } +- +- test_BAD_notDartFile() async { +- Request request = +- new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0'); +- Response response = await waitResponse(request); +- expect(response, +- isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE)); +- } +- +- test_OK_afterWaitForAnalysis() async { +- addTestFile(''' +-class C {} +-class A {} +-class B {} +-'''); +- await waitForTasksFinished(); +- return _assertSorted(r''' +-class A {} +-class B {} +-class C {} +-'''); +- } +- +- test_OK_classMembers_method() async { +- addTestFile(''' +-class A { +- c() {} +- a() {} +- b() {} +-} +-'''); +- return _assertSorted(r''' +-class A { +- a() {} +- b() {} +- c() {} +-} +-'''); +- } +- +- test_OK_directives() async { +- addTestFile(''' +-library lib; +- +-export 'dart:bbb'; +-import 'dart:bbb'; +-export 'package:bbb/bbb.dart'; +-import 'bbb/bbb.dart'; +-export 'dart:aaa'; +-export 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +-export 'aaa/aaa.dart'; +-export 'bbb/bbb.dart'; +-import 'dart:aaa'; +-import 'package:aaa/aaa.dart'; +-import 'aaa/aaa.dart'; +-part 'bbb/bbb.dart'; +-part 'aaa/aaa.dart'; +- +-main() { +-} +-'''); +- return _assertSorted(r''' +-library lib; +- +-import 'dart:aaa'; +-import 'dart:bbb'; +- +-import 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +- +-import 'aaa/aaa.dart'; +-import 'bbb/bbb.dart'; +- +-export 'dart:aaa'; +-export 'dart:bbb'; +- +-export 'package:aaa/aaa.dart'; +-export 'package:bbb/bbb.dart'; +- +-export 'aaa/aaa.dart'; +-export 'bbb/bbb.dart'; +- +-part 'aaa/aaa.dart'; +-part 'bbb/bbb.dart'; +- +-main() { +-} +-'''); +- } +- +- test_OK_directives_withAnnotation() async { +- addTestFile(''' +-library lib; +- +-export 'dart:bbb'; +-@MyAnnotation(1) +-@MyAnnotation(2) +-import 'dart:bbb'; +-@MyAnnotation(3) +-export 'dart:aaa'; +-import 'dart:aaa'; +- +-class MyAnnotation { +- const MyAnnotation(_); +-} +-'''); +- return _assertSorted(r''' +-library lib; +- +-import 'dart:aaa'; +-@MyAnnotation(1) +-@MyAnnotation(2) +-import 'dart:bbb'; +- +-@MyAnnotation(3) +-export 'dart:aaa'; +-export 'dart:bbb'; +- +-class MyAnnotation { +- const MyAnnotation(_); +-} +-'''); +- } +- +- test_OK_genericFunctionType() async { +- addFile(projectPath + '/analysis_options.yaml', ''' +-analyzer: +- strong-mode: true +-'''); +- addTestFile(''' +-class C { +- void caller() { +- Super s = new Super(); +- takesSub(s); // <- No warning +- } +- +- void takesSub(Sub s) {} +-} +- +-class Sub extends Super {} +- +-class Super {} +- +-typedef dynamic Func(String x, String y); +- +-F allowInterop(F f) => null; +- +-Func bar(Func f) { +- return allowInterop(f); +-} +-'''); +- return _assertSorted(''' +-F allowInterop(F f) => null; +- +-Func bar(Func f) { +- return allowInterop(f); +-} +- +-typedef dynamic Func(String x, String y); +- +-class C { +- void caller() { +- Super s = new Super(); +- takesSub(s); // <- No warning +- } +- +- void takesSub(Sub s) {} +-} +- +-class Sub extends Super {} +- +-class Super {} +-'''); +- } +- +- test_OK_unitMembers_class() async { +- addTestFile(''' +-class C {} +-class A {} +-class B {} +-'''); +- return _assertSorted(r''' +-class A {} +-class B {} +-class C {} +-'''); +- } +- +- Future _assertSorted(String expectedCode) async { +- await _requestSort(); +- String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits); +- expect(resultCode, expectedCode); +- } +- +- Future _requestSort() async { +- Request request = new EditSortMembersParams(testFile).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new EditSortMembersResult.fromResponse(response); +- fileEdit = result.edit; +- } +-} +diff --git a/pkg/analysis_server/test/edit/statement_completion_test.dart b/pkg/analysis_server/test/edit/statement_completion_test.dart +deleted file mode 100644 +index 7df82ba87d4..00000000000 +--- a/pkg/analysis_server/test/edit/statement_completion_test.dart ++++ /dev/null +@@ -1,122 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/edit/edit_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(StatementCompletionTest); +- }); +-} +- +-@reflectiveTest +-class StatementCompletionTest extends AbstractAnalysisTest { +- SourceChange change; +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- handler = new EditDomainHandler(server); +- } +- +- test_plainEnterFromStart() async { +- addTestFile(''' +-main() { +- int v = 1; +-} +-'''); +- await waitForTasksFinished(); +- await _prepareCompletion('v = 1;', atStart: true); +- _assertHasChange('Insert a newline at the end of the current line', ''' +-main() { +- int v = 1; +- /*caret*/ +-} +-'''); +- } +- +- test_plainOleEnter() async { +- addTestFile(''' +-main() { +- int v = 1; +-} +-'''); +- await waitForTasksFinished(); +- await _prepareCompletion('v = 1;', atEnd: true); +- _assertHasChange('Insert a newline at the end of the current line', ''' +-main() { +- int v = 1; +- /*caret*/ +-} +-'''); +- } +- +- test_plainOleEnterWithError() async { +- addTestFile(''' +-main() { +- int v = +-} +-'''); +- await waitForTasksFinished(); +- String match = 'v ='; +- await _prepareCompletion(match, atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- int v = +- x +-} +-''', +- (s) => s.indexOf(match) + match.length); // Ensure cursor after '='. +- } +- +- void _assertHasChange(String message, String expectedCode, [Function cmp]) { +- if (change.message == message) { +- if (!change.edits.isEmpty) { +- String resultCode = +- SourceEdit.applySequence(testCode, change.edits[0].edits); +- expect(resultCode, expectedCode.replaceAll('/*caret*/', '')); +- if (cmp != null) { +- int offset = cmp(resultCode); +- expect(change.selection.offset, offset); +- } +- } else { +- if (cmp != null) { +- int offset = cmp(testCode); +- expect(change.selection.offset, offset); +- } +- } +- return; +- } +- fail("Expected to find |$message| but got: " + change.message); +- } +- +- _prepareCompletion(String search, +- {bool atStart: false, bool atEnd: false, int delta: 0}) async { +- int offset = findOffset(search); +- if (atStart) { +- delta = 0; +- } else if (atEnd) { +- delta = search.length; +- } +- await _prepareCompletionAt(offset + delta); +- } +- +- _prepareCompletionAt(int offset) async { +- Request request = +- new EditGetStatementCompletionParams(testFile, offset).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new EditGetStatementCompletionResult.fromResponse(response); +- change = result.change; +- } +-} +diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart +deleted file mode 100644 +index 1376ea6396c..00000000000 +--- a/pkg/analysis_server/test/edit/test_all.dart ++++ /dev/null +@@ -1,27 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'assists_test.dart' as assists_test; +-import 'fixes_test.dart' as fixes_test; +-import 'format_test.dart' as format_test; +-import 'organize_directives_test.dart' as organize_directives_test; +-import 'postfix_completion_test.dart' as postfix_completion_test; +-import 'refactoring_test.dart' as refactoring_test; +-import 'sort_members_test.dart' as sort_members_test; +-import 'statement_completion_test.dart' as statement_completion_test; +- +-main() { +- defineReflectiveSuite(() { +- assists_test.main(); +- fixes_test.main(); +- format_test.main(); +- organize_directives_test.main(); +- postfix_completion_test.main(); +- refactoring_test.main(); +- sort_members_test.main(); +- statement_completion_test.main(); +- }, name: 'edit'); +-} +diff --git a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart +deleted file mode 100644 +index e437193487e..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart ++++ /dev/null +@@ -1,81 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OptionsIntegrationTest); +- }); +-} +- +-@reflectiveTest +-class OptionsIntegrationTest extends AbstractAnalysisServerIntegrationTest { +- @failingTest +- test_option_warning_newOptionFile() async { +- // TimeoutException after 0:00:30.000000: Test timed out after 30 seconds +- // (#28868). +- +- fail('test timeout expected - #28868'); +- +- String options = sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE); +- writeFile(options, ''' +-linter: +- rules: +- - camel_case_typo # :) +-'''); +- +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- expect(currentAnalysisErrors[options], isList); +- List errors = currentAnalysisErrors[options]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.location.file, options); +- expect(error.severity, AnalysisErrorSeverity.WARNING); +- expect(error.type, AnalysisErrorType.STATIC_WARNING); +- expect(error.location.offset, 23); +- expect(error.location.length, 'camel_case_typo'.length); +- expect(error.location.startLine, 3); +- expect(error.location.startColumn, 7); +- } +- +- @failingTest +- test_option_warning_oldOptionFile() async { +- // TimeoutException after 0:00:30.000000: Test timed out after 30 seconds +- // (#28868). +- +- fail('test timeout expected - #28868'); +- +- String options = sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_FILE); +- writeFile(options, ''' +-linter: +- rules: +- - camel_case_typo # :) +-'''); +- +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- expect(currentAnalysisErrors[options], isList); +- List errors = currentAnalysisErrors[options]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.location.file, options); +- expect(error.severity, AnalysisErrorSeverity.WARNING); +- expect(error.type, AnalysisErrorType.STATIC_WARNING); +- expect(error.location.offset, 23); +- expect(error.location.length, 'camel_case_typo'.length); +- expect(error.location.startLine, 3); +- expect(error.location.startColumn, 7); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart +deleted file mode 100644 +index 1c32caa732f..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/error_test.dart ++++ /dev/null +@@ -1,100 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisErrorIntegrationTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisErrorIntegrationTest +- extends AbstractAnalysisServerIntegrationTest { +- test_detect_simple_error() { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-main() { +- print(null) // parse error: missing ';' +-}'''); +- standardAnalysisSetup(); +- return analysisFinished.then((_) { +- expect(currentAnalysisErrors[pathname], isList); +- List errors = currentAnalysisErrors[pathname]; +- expect(errors, hasLength(1)); +- expect(errors[0].location.file, equals(pathname)); +- }); +- } +- +- test_super_mixins_disabled() async { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-class Test extends Object with C { +- void foo() {} +-} +-abstract class B { +- void foo() {} +-} +-abstract class C extends B { +- void bar() { +- super.foo(); +- } +-} +-'''); +- standardAnalysisSetup(); +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isList); +- List errors = currentAnalysisErrors[pathname]; +- expect(errors, hasLength(2)); +- Set allErrorMessages = +- errors.map((AnalysisError e) => e.message).toSet(); +- expect( +- allErrorMessages, +- contains( +- "The class 'C' can't be used as a mixin because it extends a class other than Object.")); +- expect( +- allErrorMessages, +- contains( +- "The class 'C' can't be used as a mixin because it references 'super'.")); +- } +- +- @failingTest +- test_super_mixins_enabled() async { +- // We see errors here with the new driver (#28870). +- // Expected: empty +- // Actual: [ +- // AnalysisError:{"severity":"ERROR","type":"COMPILE_TIME_ERROR","location":{"file":"/var/folders/00/0w95r000h01000cxqpysvccm003j4q/T/analysisServerfbuOQb/test.dart","offset":31,"length":1,"startLine":1,"startColumn":32},"message":"The class 'C' can't be used as a mixin because it extends a class other than Object.","correction":"","code":"mixin_inherits_from_not_object","hasFix":false}, +- // AnalysisError:{"severity":"ERROR","type":"COMPILE_TIME_ERROR","location":{"file":"/var/folders/00/0w95r000h01000cxqpysvccm003j4q/T/analysisServerfbuOQb/test.dart","offset":31,"length":1,"startLine":1,"startColumn":32},"message":"The class 'C' can't be used as a mixin because it references 'super'.","correction":"","code":"mixin_references_super","hasFix":false} +- // ] +- +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-class Test extends Object with C { +- void foo() {} +-} +-abstract class B { +- void foo() {} +-} +-abstract class C extends B { +- void bar() { +- super.foo(); +- } +-} +-'''); +- // ignore: deprecated_member_use +- await sendAnalysisUpdateOptions( +- new AnalysisOptions()..enableSuperMixins = true); +- standardAnalysisSetup(); +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isList); +- List errors = currentAnalysisErrors[pathname]; +- expect(errors, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart +deleted file mode 100644 +index 289a3321cd5..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart ++++ /dev/null +@@ -1,99 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +-import 'dart:io'; +- +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../mock_sdk.dart'; +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisDomainGetErrorsTest); +- }); +-} +- +-/** +- * Tests that when an SDK path is specified on the command-line (via the `--sdk` +- * argument) that the specified SDK is used. +- */ +-@reflectiveTest +-class AnalysisDomainGetErrorsTest +- extends AbstractAnalysisServerIntegrationTest { +- String createNonStandardSdk() { +- MockSdkLibrary fakeLibrary = +- new MockSdkLibrary('dart:fake', '/lib/fake/fake.dart', ''); +- String sdkPath = path.join(sourceDirectory.path, 'sdk'); +- StringBuffer librariesContent = new StringBuffer(); +- librariesContent.writeln( +- 'final Map LIBRARIES = const {'); +- MockSdk.LIBRARIES.toList() +- ..add(fakeLibrary) +- ..forEach((SdkLibrary library) { +- List components = path.posix.split(library.path); +- components[0] = sdkPath; +- String libraryPath = path.joinAll(components); +- new Directory(path.dirname(libraryPath)).createSync(recursive: true); +- new File(libraryPath) +- .writeAsStringSync((library as MockSdkLibrary).content); +- +- String relativePath = path.joinAll(components.sublist(2)); +- librariesContent.write('"'); +- librariesContent +- .write(library.shortName.substring(5)); // Remove the 'dart:' prefix +- librariesContent.write('": const LibraryInfo("'); +- librariesContent.write(relativePath); +- librariesContent.writeln('"),'); +- }); +- librariesContent.writeln('};'); +- +- String librariesPath = path.joinAll([ +- sdkPath, +- 'lib', +- '_internal', +- 'sdk_library_metadata', +- 'lib', +- 'libraries.dart' +- ]); +- new Directory(path.dirname(librariesPath)).createSync(recursive: true); +- new File(librariesPath).writeAsStringSync(librariesContent.toString()); +- +- return sdkPath; +- } +- +- @override +- Future startServer( +- {bool checked: true, +- int diagnosticPort, +- int servicesPort, +- bool previewDart2: false}) { +- String sdkPath = createNonStandardSdk(); +- return server.start( +- checked: checked, +- diagnosticPort: diagnosticPort, +- sdkPath: sdkPath, +- servicesPort: servicesPort, +- previewDart2: previewDart2); +- } +- +- Future test_getErrors() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:core'; +-import 'dart:fake'; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- List errors = currentAnalysisErrors[pathname]; +- expect(errors, hasLength(1)); +- expect(errors[0].code, 'unused_import'); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_test.dart +deleted file mode 100644 +index 2f3954222c4..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_errors_test.dart ++++ /dev/null +@@ -1,36 +0,0 @@ +-// Copyright (c) 2014, 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 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetErrorsTest); +- }); +-} +- +-@reflectiveTest +-class GetErrorsTest extends AbstractAnalysisServerIntegrationTest { +- test_getErrors() { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-main() { +- var x // parse error: missing ';' +-}'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- Future finishTest() { +- return sendAnalysisGetErrors(pathname).then((result) { +- expect(result.errors, equals(currentAnalysisErrors[pathname])); +- }); +- } +- +- return analysisFinished.then((_) => finishTest()); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart +deleted file mode 100644 +index 55be6ca2668..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart ++++ /dev/null +@@ -1,189 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisGetHoverIntegrationTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisGetHoverIntegrationTest +- extends AbstractAnalysisServerIntegrationTest { +- /** +- * Pathname of the file containing Dart code. +- */ +- String pathname; +- +- /** +- * Dart code under test. +- */ +- final String text = r''' +-library lib.test; +- +-List topLevelVar; +- +-/** +- * Documentation for func +- */ +-void func(int param) { +- num localVar = topLevelVar.length; +- topLevelVar.length = param; +- topLevelVar.add(localVar); +-} +- +-main() { +- // comment +- func(35); +-} +-'''; +- +- /** +- * Check that a getHover request on the substring [target] produces a result +- * which has length [length], has an elementDescription matching every +- * regexp in [descriptionRegexps], has a kind of [kind], and has a staticType +- * matching [staticTypeRegexps]. +- * +- * [isCore] means the hover info should indicate that the element is defined +- * in dart.core. [docRegexp], if specified, should match the documentation +- * string of the element. [isLiteral] means the hover should indicate a +- * literal value. [parameterRegexps] means is a set of regexps which should +- * match the hover parameters. [propagatedType], if specified, is the +- * expected propagated type of the element. +- */ +- checkHover(String target, int length, List descriptionRegexps, +- String kind, List staticTypeRegexps, +- {bool isLocal: false, +- bool isCore: false, +- String docRegexp: null, +- bool isLiteral: false, +- List parameterRegexps: null, +- propagatedType: null}) { +- int offset = text.indexOf(target); +- return sendAnalysisGetHover(pathname, offset).then((result) { +- expect(result.hovers, hasLength(1)); +- HoverInformation info = result.hovers[0]; +- expect(info.offset, equals(offset)); +- expect(info.length, equals(length)); +- if (isCore) { +- expect(path.basename(info.containingLibraryPath), equals('core.dart')); +- expect(info.containingLibraryName, equals('dart.core')); +- } else if (isLocal || isLiteral) { +- expect(info.containingLibraryPath, isNull); +- expect(info.containingLibraryName, isNull); +- } else { +- expect(info.containingLibraryPath, equals(pathname)); +- expect(info.containingLibraryName, equals('lib.test')); +- } +- if (docRegexp == null) { +- expect(info.dartdoc, isNull); +- } else { +- expect(info.dartdoc, matches(docRegexp)); +- } +- if (descriptionRegexps == null) { +- expect(info.elementDescription, isNull); +- } else { +- expect(info.elementDescription, isString); +- for (String descriptionRegexp in descriptionRegexps) { +- expect(info.elementDescription, matches(descriptionRegexp)); +- } +- } +- expect(info.elementKind, equals(kind)); +- if (parameterRegexps == null) { +- expect(info.parameter, isNull); +- } else { +- expect(info.parameter, isString); +- for (String parameterRegexp in parameterRegexps) { +- expect(info.parameter, matches(parameterRegexp)); +- } +- } +- expect(info.propagatedType, equals(propagatedType)); +- if (staticTypeRegexps == null) { +- expect(info.staticType, isNull); +- } else { +- expect(info.staticType, isString); +- for (String staticTypeRegexp in staticTypeRegexps) { +- expect(info.staticType, matches(staticTypeRegexp)); +- } +- } +- }); +- } +- +- /** +- * Check that a getHover request on the substring [target] produces no +- * results. +- */ +- Future checkNoHover(String target) { +- int offset = text.indexOf(target); +- return sendAnalysisGetHover(pathname, offset).then((result) { +- expect(result.hovers, hasLength(0)); +- }); +- } +- +- setUp() { +- return super.setUp().then((_) { +- pathname = sourcePath('test.dart'); +- }); +- } +- +- test_getHover() { +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- // Note: analysis.getHover doesn't wait for analysis to complete--it simply +- // returns the latest results that are available at the time that the +- // request is made. So wait for analysis to finish before testing anything. +- return analysisFinished.then((_) { +- List tests = []; +- tests.add(checkHover('topLevelVar;', 11, ['List', 'topLevelVar'], +- 'top level variable', ['List'])); +- tests.add(checkHover( +- 'func(', 4, ['func', 'int', 'param'], 'function', null, +- docRegexp: 'Documentation for func')); +- tests.add(checkHover('int param', 3, ['int'], 'class', null, +- isCore: true, docRegexp: '.*')); +- tests.add(checkHover('param)', 5, ['int', 'param'], 'parameter', ['int'], +- isLocal: true, docRegexp: 'Documentation for func')); +- tests.add(checkHover('num localVar', 3, ['num'], 'class', null, +- isCore: true, docRegexp: '.*')); +- tests.add(checkHover( +- 'localVar =', 8, ['num', 'localVar'], 'local variable', ['num'], +- isLocal: true, propagatedType: 'int')); +- tests.add(checkHover('topLevelVar.length;', 11, ['List', 'topLevelVar'], +- 'top level variable', ['List'])); +- tests.add(checkHover( +- 'length;', 6, ['get', 'length', 'int'], 'getter', null, +- isCore: true, docRegexp: '.*')); +- tests.add(checkHover( +- 'length =', 6, ['set', 'length', 'int'], 'setter', null, +- isCore: true, docRegexp: '.*')); +- tests.add(checkHover('param;', 5, ['int', 'param'], 'parameter', ['int'], +- isLocal: true, +- docRegexp: 'Documentation for func', +- parameterRegexps: ['.*'])); +- tests.add(checkHover( +- 'add(', 3, ['List', 'add'], 'method', ['dynamic', 'void'], +- isCore: true, docRegexp: '.*')); +- tests.add(checkHover( +- 'localVar)', 8, ['num', 'localVar'], 'local variable', ['num'], +- isLocal: true, parameterRegexps: ['.*'], propagatedType: 'int')); +- tests.add(checkHover( +- 'func(35', 4, ['func', 'int', 'param'], 'function', ['int', 'void'], +- docRegexp: 'Documentation for func')); +- tests.add(checkHover('35', 2, null, null, ['int'], +- isLiteral: true, parameterRegexps: ['int', 'param'])); +- tests.add(checkNoHover('comment')); +- return Future.wait(tests); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart b/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart +deleted file mode 100644 +index f5a98cd9909..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_imported_elements_test.dart ++++ /dev/null +@@ -1,135 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisGetImportedElementsIntegrationTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisGetImportedElementsIntegrationTest +- extends AbstractAnalysisServerIntegrationTest { +- /** +- * Pathname of the file containing Dart code. +- */ +- String pathname; +- +- /** +- * Dart code under test. +- */ +- String text; +- +- /** +- * Check that an analysis.getImportedElements request on the region starting +- * with the first character that matches [target] and having the given +- * [length] matches the given list of [expected] imported elements. +- */ +- checkElements(String target, List expected) async { +- bool equals( +- ImportedElements actualElements, ImportedElements expectedElements) { +- if (actualElements.path.endsWith(expectedElements.path) && +- actualElements.prefix == expectedElements.prefix) { +- List actual = actualElements.elements; +- List expected = expectedElements.elements; +- if (actual.length == expected.length) { +- for (int i = 0; i < actual.length; i++) { +- if (!expected.contains(actual[i])) { +- return false; +- } +- } +- return true; +- } +- } +- return false; +- } +- +- int find(List actual, ImportedElements expectedElements) { +- for (int i = 0; i < actual.length; i++) { +- ImportedElements actualElements = actual[i]; +- if (equals(actualElements, expectedElements)) { +- return i; +- } +- } +- return -1; +- } +- +- int offset = text.indexOf(target); +- AnalysisGetImportedElementsResult result = +- await sendAnalysisGetImportedElements(pathname, offset, target.length); +- +- List actual = result.elements; +- expect(actual, hasLength(expected.length)); +- for (ImportedElements elements in expected) { +- int index = find(actual, elements); +- if (index < 0) { +- fail('Expected $elements; not found'); +- } +- actual.removeAt(index); +- } +- } +- +- /** +- * Check that an analysis.getImportedElements request on the region matching +- * [target] produces an empty list of elements. +- */ +- Future checkNoElements(String target) async { +- int offset = text.indexOf(target); +- AnalysisGetImportedElementsResult result = +- await sendAnalysisGetImportedElements(pathname, offset, target.length); +- +- expect(result.elements, hasLength(0)); +- } +- +- setUp() { +- return super.setUp().then((_) { +- pathname = sourcePath('test.dart'); +- }); +- } +- +- test_getImportedElements_none() async { +- text = r''' +-main() {} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- await checkNoElements('main() {}'); +- } +- +- test_getImportedElements_some() async { +- String selection = r''' +-main() { +- Random r = new Random(); +- String s = r.nextBool().toString(); +- print(s); +-} +-'''; +- text = ''' +-import 'dart:math'; +- +-$selection +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- await checkElements(selection, [ +- new ImportedElements( +- path.join('lib', 'core', 'core.dart'), '', ['String', 'print']), +- new ImportedElements( +- path.join('lib', 'math', 'math.dart'), '', ['Random']) +- ]); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart b/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart +deleted file mode 100644 +index 51a76599663..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_library_dependencies_test.dart ++++ /dev/null +@@ -1,47 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetLibraryDependenciesTest); +- }); +-} +- +-@reflectiveTest +-class GetLibraryDependenciesTest extends AbstractAnalysisServerIntegrationTest { +- @failingTest +- test_libraryDeps() async { +- // This fails with the new analysis driver ('Bad state: Should not be used +- // with the new analysis driver') - #29310. +- String pathname = sourcePath('test.dart'); +- String text = r''' +-class Foo {} +- +-class Bar { +- Foo foo; +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- AnalysisGetLibraryDependenciesResult result = +- await sendAnalysisGetLibraryDependencies(); +- List libraries = result.libraries; +- Map>> packageMaps = result.packageMap; +- +- expect(libraries, contains(pathname)); +- expect(libraries.any((String lib) => lib.endsWith('core/core.dart')), true); +- +- expect(packageMaps.keys, hasLength(1)); +- Map> map = packageMaps[packageMaps.keys.first]; +- expect(map.keys, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_navigation_test.dart b/pkg/analysis_server/test/integration/analysis/get_navigation_test.dart +deleted file mode 100644 +index 9725e588998..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_navigation_test.dart ++++ /dev/null +@@ -1,67 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetNavigationTest); +- }); +-} +- +-@reflectiveTest +-class GetNavigationTest extends AbstractAnalysisServerIntegrationTest { +- test_navigation() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-class Foo {} +- +-class Bar { +- Foo foo; +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- AnalysisGetNavigationResult result = +- await sendAnalysisGetNavigation(pathname, text.indexOf('Foo foo'), 0); +- expect(result.targets, hasLength(1)); +- NavigationTarget target = result.targets.first; +- expect(target.kind, ElementKind.CLASS); +- expect(target.offset, text.indexOf('Foo {}')); +- expect(target.length, 3); +- expect(target.startLine, 1); +- expect(target.startColumn, 7); +- } +- +- @failingTest +- test_navigation_no_result() async { +- // This fails - it returns navigation results for a whitespace area (#28799). +- String pathname = sourcePath('test.dart'); +- String text = r''' +-// +- +-class Foo {} +- +-class Bar { +- Foo foo; +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- AnalysisGetNavigationResult result = +- await sendAnalysisGetNavigation(pathname, 0, 0); +- expect(result.targets, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart b/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart +deleted file mode 100644 +index 150c67ff3f2..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart ++++ /dev/null +@@ -1,49 +0,0 @@ +-// 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:io'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetReachableSourcesTest); +- }); +-} +- +-@reflectiveTest +-class GetReachableSourcesTest extends AbstractAnalysisServerIntegrationTest { +- @failingTest +- test_reachable() async { +- // This fails with the new analysis driver ('Bad state: Should not be used +- // with the new analysis driver') - #29311. +- String pathname = sourcePath('test.dart'); +- String text = r''' +-class Foo {} +- +-class Bar { +- Foo foo; +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- AnalysisGetReachableSourcesResult result = +- await sendAnalysisGetReachableSources(pathname); +- Map> sources = result.sources; +- List keys = sources.keys.toList(); +- String url = new File(pathname).uri.toString(); +- +- expect(keys, contains('dart:core')); +- expect(keys, contains('dart:collection')); +- expect(keys, contains('dart:math')); +- expect(keys, contains(url)); +- expect(sources[url], contains('dart:core')); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart +deleted file mode 100644 +index 64d331372ab..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart ++++ /dev/null +@@ -1,146 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisHighlightsTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest { +- test_highlights() { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:async' as async; +- +-/** +- * Doc comment +- */ +-class Class { +- Class() { +- field = {1.0: [].toList()}; +- } +- +- Class.constructor() { +- dynamic local = true; +- field = {2: local}; +- } +- +- Map field; +- static int staticField; +- +- method() { +- // End of line comment +- /* Block comment */ +- } +- +- static staticMethod() { +- } +- +- get getter { +- } +- +- set setter(int parameter) { +- } +-} +- +-class Class2 extends Class { +- @override +- method() { +- } +-} +- +-typedef functionType(); +- +-function(dynamicType) { +- print('string'); +- unresolvedIdentifier = 42; +- return async.Future.wait([]); +-} +- +-int topLevelVariable; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- sendAnalysisSetSubscriptions({ +- AnalysisService.HIGHLIGHTS: [pathname] +- }); +- // Map from highlight type to highlighted text +- Map> highlights; +- onAnalysisHighlights.listen((AnalysisHighlightsParams params) { +- expect(params.file, equals(pathname)); +- highlights = >{}; +- for (HighlightRegion region in params.regions) { +- int startIndex = region.offset; +- int endIndex = startIndex + region.length; +- String highlightedText = text.substring(startIndex, endIndex); +- HighlightRegionType type = region.type; +- if (!highlights.containsKey(type)) { +- highlights[type] = new Set(); +- } +- highlights[type].add(highlightedText); +- } +- }); +- return analysisFinished.then((_) { +- // There should be 1 error due to the fact that unresolvedIdentifier is +- // unresolved. +- expect(currentAnalysisErrors[pathname], hasLength(1)); +- void check(HighlightRegionType type, List expected) { +- expect(highlights[type], equals(expected.toSet())); +- highlights.remove(type); +- } +- +- check(HighlightRegionType.ANNOTATION, ['@override']); +- check(HighlightRegionType.BUILT_IN, +- ['as', 'get', 'import', 'set', 'static', 'typedef']); +- check(HighlightRegionType.CLASS, +- ['Class', 'Class2', 'Future', 'Map', 'int']); +- check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']); +- check(HighlightRegionType.COMMENT_DOCUMENTATION, +- ['/**\n * Doc comment\n */']); +- check( +- HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']); +- check(HighlightRegionType.CONSTRUCTOR, ['constructor']); +- check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]); +- check(HighlightRegionType.DYNAMIC_TYPE, ['dynamicType']); +- check(HighlightRegionType.FIELD, ['field']); +- check(HighlightRegionType.FIELD_STATIC, ['staticField']); +- check(HighlightRegionType.FUNCTION, ['print']); +- check(HighlightRegionType.FUNCTION_DECLARATION, ['function']); +- check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']); +- check(HighlightRegionType.GETTER_DECLARATION, ['getter']); +- check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']); +- check(HighlightRegionType.IMPORT_PREFIX, ['async']); +- check(HighlightRegionType.KEYWORD, ['class', 'true', 'return']); +- check(HighlightRegionType.LITERAL_BOOLEAN, ['true']); +- check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']); +- check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']); +- check(HighlightRegionType.LITERAL_LIST, ['[]']); +- check(HighlightRegionType.LITERAL_MAP, +- ['{1.0: [].toList()}', '{2: local}']); +- check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]); +- check(HighlightRegionType.LOCAL_VARIABLE, ['local']); +- check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']); +- check(HighlightRegionType.METHOD, ['toList']); +- check(HighlightRegionType.METHOD_DECLARATION, ['method']); +- check(HighlightRegionType.METHOD_DECLARATION_STATIC, ['staticMethod']); +- check(HighlightRegionType.METHOD_STATIC, ['wait']); +- check(HighlightRegionType.PARAMETER, ['parameter']); +- check(HighlightRegionType.SETTER_DECLARATION, ['setter']); +- check(HighlightRegionType.TOP_LEVEL_VARIABLE, +- ['override', 'topLevelVariable']); +- check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']); +- check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']); +- expect(highlights, isEmpty); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart +deleted file mode 100644 +index 2e672288905..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart ++++ /dev/null +@@ -1,166 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisHighlightsTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest { +- Future startServer({ +- bool checked: true, +- int diagnosticPort, +- int servicesPort, +- bool previewDart2: false, +- }) { +- return server.start( +- checked: checked, +- diagnosticPort: diagnosticPort, +- servicesPort: servicesPort, +- useAnalysisHighlight2: true, +- previewDart2: previewDart2); +- } +- +- test_highlights() { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:async' as async; +- +-/** +- * Doc comment +- */ +-class Class { +- Class() { +- field = {1.0: [].toList()}; +- } +- +- Class.constructor() { +- dynamic local = true; +- field = {2: local}; +- } +- +- Map field; +- static int staticField; +- +- method() { +- // End of line comment +- /* Block comment */ +- } +- +- static staticMethod() { +- } +- +- get getter { +- } +- +- set setter(int parameter) { +- print(parameter); +- } +-} +- +-class Class2 extends Class { +- @override +- method() { +- } +-} +- +-typedef functionType(); +- +-function(dynamicType) { +- print('string'); +- unresolvedIdentifier = 42; +- return async.Future.wait([]); +-} +- +-int topLevelVariable; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- sendAnalysisSetSubscriptions({ +- AnalysisService.HIGHLIGHTS: [pathname] +- }); +- // Map from highlight type to highlighted text +- Map> highlights; +- onAnalysisHighlights.listen((AnalysisHighlightsParams params) { +- expect(params.file, equals(pathname)); +- highlights = >{}; +- for (HighlightRegion region in params.regions) { +- int startIndex = region.offset; +- int endIndex = startIndex + region.length; +- String highlightedText = text.substring(startIndex, endIndex); +- HighlightRegionType type = region.type; +- if (!highlights.containsKey(type)) { +- highlights[type] = new Set(); +- } +- highlights[type].add(highlightedText); +- } +- }); +- return analysisFinished.then((_) { +- // There should be 1 error due to the fact that unresolvedIdentifier is +- // unresolved. +- expect(currentAnalysisErrors[pathname], hasLength(1)); +- void check(HighlightRegionType type, List expected) { +- expect(highlights[type], equals(expected.toSet())); +- highlights.remove(type); +- } +- +- check(HighlightRegionType.ANNOTATION, ['@override']); +- check(HighlightRegionType.BUILT_IN, +- ['as', 'get', 'import', 'set', 'static', 'typedef']); +- check(HighlightRegionType.CLASS, +- ['Class', 'Class2', 'Future', 'Map', 'int']); +- check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']); +- check(HighlightRegionType.COMMENT_DOCUMENTATION, +- ['/**\n * Doc comment\n */']); +- check( +- HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']); +- check(HighlightRegionType.CONSTRUCTOR, ['constructor']); +- check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]); +- check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']); +- check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']); +- check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']); +- check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']); +- check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']); +- check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']); +- check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']); +- check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']); +- check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']); +- check(HighlightRegionType.IMPORT_PREFIX, ['async']); +- check(HighlightRegionType.KEYWORD, ['class', 'true', 'return']); +- check(HighlightRegionType.LITERAL_BOOLEAN, ['true']); +- check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']); +- check(HighlightRegionType.LITERAL_INTEGER, ['2', '42']); +- check(HighlightRegionType.LITERAL_LIST, ['[]']); +- check(HighlightRegionType.LITERAL_MAP, +- ['{1.0: [].toList()}', '{2: local}']); +- check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]); +- check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']); +- check(HighlightRegionType.LOCAL_VARIABLE_REFERENCE, ['local']); +- check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']); +- check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']); +- check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']); +- check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']); +- check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']); +- check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']); +- check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']); +- check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']); +- check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION, +- ['topLevelVariable']); +- check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']); +- check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']); +- expect(highlights, isEmpty); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/lint_test.dart b/pkg/analysis_server/test/integration/analysis/lint_test.dart +deleted file mode 100644 +index 699b43bad43..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/lint_test.dart ++++ /dev/null +@@ -1,83 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LintIntegrationTest); +- }); +-} +- +-@reflectiveTest +-class LintIntegrationTest extends AbstractAnalysisServerIntegrationTest { +- test_no_lints_when_not_specified() async { +- String source = sourcePath('test.dart'); +- writeFile(source, ''' +-class abc { // lint: not CamelCase (should get ignored though) +-}'''); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[source], isList); +- // Should be empty without an analysis options file. +- List errors = currentAnalysisErrors[source]; +- expect(errors, hasLength(0)); +- } +- +- test_simple_lint_newOptionsFile() async { +- writeFile(sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE), ''' +-linter: +- rules: +- - camel_case_types +-'''); +- +- String source = sourcePath('test.dart'); +- writeFile(source, ''' +-class a { // lint: not CamelCase +-}'''); +- +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- expect(currentAnalysisErrors[source], isList); +- List errors = currentAnalysisErrors[source]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.location.file, source); +- expect(error.severity, AnalysisErrorSeverity.INFO); +- expect(error.type, AnalysisErrorType.LINT); +- } +- +- test_simple_lint_oldOptionsFile() async { +- writeFile(sourcePath(AnalysisEngine.ANALYSIS_OPTIONS_FILE), ''' +-linter: +- rules: +- - camel_case_types +-'''); +- +- String source = sourcePath('test.dart'); +- writeFile(source, ''' +-class a { // lint: not CamelCase +-}'''); +- +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- expect(currentAnalysisErrors[source], isList); +- List errors = currentAnalysisErrors[source]; +- expect(errors, hasLength(1)); +- AnalysisError error = errors[0]; +- expect(error.location.file, source); +- expect(error.severity, AnalysisErrorSeverity.INFO); +- expect(error.type, AnalysisErrorType.LINT); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/navigation_test.dart b/pkg/analysis_server/test/integration/analysis/navigation_test.dart +deleted file mode 100644 +index a5143236515..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/navigation_test.dart ++++ /dev/null +@@ -1,136 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisNavigationTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisNavigationTest extends AbstractAnalysisServerIntegrationTest { +- test_navigation() async { +- String pathname1 = sourcePath('test1.dart'); +- String text1 = r''' +-library foo; +- +-import 'dart:async'; +-part 'test2.dart'; +- +-class Class { +- Class.constructor(); /* constructor declaration */ +- +- TypeParameter field; +- +- method() {} +-} +- +-typedef FunctionTypeAlias(); +- +-function(FunctionTypeAlias parameter) { +- print(parameter()); +-} +- +-int topLevelVariable; +- +-main() { +- Class localVariable = new Class.constructor(); // usage +- function(() => localVariable.field); +- localVariable.method(); +- localVariable.field = 1; +-} +-'''; +- writeFile(pathname1, text1); +- String pathname2 = sourcePath('test2.dart'); +- String text2 = r''' +-part of foo; +-'''; +- writeFile(pathname2, text2); +- standardAnalysisSetup(); +- sendAnalysisSetSubscriptions({ +- AnalysisService.NAVIGATION: [pathname1] +- }); +- List regions; +- List targets; +- List targetFiles; +- onAnalysisNavigation.listen((AnalysisNavigationParams params) { +- expect(params.file, equals(pathname1)); +- regions = params.regions; +- targets = params.targets; +- targetFiles = params.files; +- }); +- +- await analysisFinished; +- +- // There should be a single error, due to the fact that 'dart:async' is not +- // used. +- expect(currentAnalysisErrors[pathname1], hasLength(1)); +- expect(currentAnalysisErrors[pathname2], isEmpty); +- NavigationTarget findTargetElement(int index) { +- for (NavigationRegion region in regions) { +- if (region.offset <= index && index < region.offset + region.length) { +- expect(region.targets, hasLength(1)); +- int targetIndex = region.targets[0]; +- return targets[targetIndex]; +- } +- } +- fail('No element found for index $index'); +- return null; +- } +- +- void checkLocal( +- String source, String expectedTarget, ElementKind expectedKind) { +- int sourceIndex = text1.indexOf(source); +- int targetIndex = text1.indexOf(expectedTarget); +- NavigationTarget element = findTargetElement(sourceIndex); +- expect(targetFiles[element.fileIndex], equals(pathname1)); +- expect(element.offset, equals(targetIndex)); +- expect(element.kind, equals(expectedKind)); +- } +- +- void checkRemote( +- String source, String expectedTargetRegexp, ElementKind expectedKind) { +- int sourceIndex = text1.indexOf(source); +- NavigationTarget element = findTargetElement(sourceIndex); +- expect(targetFiles[element.fileIndex], matches(expectedTargetRegexp)); +- expect(element.kind, equals(expectedKind)); +- } +- +- // TODO(paulberry): will the element type 'CLASS_TYPE_ALIAS' ever appear as +- // a navigation target? +- checkLocal('Class', 'Class', ElementKind.CLASS); +- checkRemote("'test2.dart';", r'test2.dart$', ElementKind.COMPILATION_UNIT); +- checkLocal( +- 'Class.constructor', +- 'constructor(); /* constructor declaration */', +- ElementKind.CONSTRUCTOR); +- checkLocal( +- 'constructor(); // usage', +- 'constructor(); /* constructor declaration */', +- ElementKind.CONSTRUCTOR); +- checkLocal('field;', 'field;', ElementKind.FIELD); +- checkLocal('function(() => localVariable.field)', +- 'function(FunctionTypeAlias parameter)', ElementKind.FUNCTION); +- checkLocal('FunctionTypeAlias parameter', 'FunctionTypeAlias();', +- ElementKind.FUNCTION_TYPE_ALIAS); +- checkLocal('field)', 'field;', ElementKind.GETTER); +- checkRemote("'dart:async'", r'async\.dart$', ElementKind.LIBRARY); +- checkLocal( +- 'localVariable.field', 'localVariable =', ElementKind.LOCAL_VARIABLE); +- checkLocal('method();', 'method() {', ElementKind.METHOD); +- checkLocal('parameter());', 'parameter) {', ElementKind.PARAMETER); +- checkLocal('field = 1', 'field;', ElementKind.SETTER); +- checkLocal('topLevelVariable;', 'topLevelVariable;', +- ElementKind.TOP_LEVEL_VARIABLE); +- checkLocal( +- 'TypeParameter field;', 'TypeParameter>', ElementKind.TYPE_PARAMETER); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/occurrences_test.dart b/pkg/analysis_server/test/integration/analysis/occurrences_test.dart +deleted file mode 100644 +index 94c942ceba8..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/occurrences_test.dart ++++ /dev/null +@@ -1,68 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OccurrencesTest); +- }); +-} +- +-@reflectiveTest +-class OccurrencesTest extends AbstractAnalysisServerIntegrationTest { +- test_occurrences() { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-main() { +- int sum = 0; +- for (int i = 0; i < 10; i++) { +- for (int j = 0; j < i; j++) { +- sum += j; +- } +- } +- print(sum); +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- sendAnalysisSetSubscriptions({ +- AnalysisService.OCCURRENCES: [pathname] +- }); +- List occurrences; +- onAnalysisOccurrences.listen((AnalysisOccurrencesParams params) { +- expect(params.file, equals(pathname)); +- occurrences = params.occurrences; +- }); +- return analysisFinished.then((_) { +- expect(currentAnalysisErrors[pathname], isEmpty); +- Set findOffsets(String elementName) { +- for (Occurrences occurrence in occurrences) { +- if (occurrence.element.name == elementName) { +- return occurrence.offsets.toSet(); +- } +- } +- fail('No element found matching $elementName'); +- return null; +- } +- +- void check(String elementName, Iterable expectedOccurrences) { +- Set expectedOffsets = expectedOccurrences +- .map((String substring) => text.indexOf(substring)) +- .toSet(); +- Set foundOffsets = findOffsets(elementName); +- expect(foundOffsets, equals(expectedOffsets)); +- } +- +- check('i', ['i = 0', 'i < 10', 'i++', 'i;']); +- check('j', ['j = 0', 'j < i', 'j++', 'j;']); +- check('sum', ['sum = 0', 'sum +=', 'sum)']); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/outline_test.dart b/pkg/analysis_server/test/integration/analysis/outline_test.dart +deleted file mode 100644 +index bef8bd257f1..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/outline_test.dart ++++ /dev/null +@@ -1,84 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OutlineTest); +- }); +-} +- +-@reflectiveTest +-class OutlineTest extends AbstractAnalysisServerIntegrationTest { +- /** +- * Verify that the range of source text covered by the given outline objects +- * is connected (the end of each object in the list corresponds to the start +- * of the next). +- */ +- void checkConnected(List outlineObjects) { +- for (int i = 0; i < outlineObjects.length - 1; i++) { +- expect(outlineObjects[i + 1].offset, +- equals(outlineObjects[i].offset + outlineObjects[i].length)); +- } +- } +- +- test_outline() { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-class Class1 { +- int field; +- +- void method() { +- } +- +- static staticMethod() { +- } +- +- get getter { +- return null; +- } +- +- set setter(value) { +- } +-} +- +-class Class2 { +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- sendAnalysisSetSubscriptions({ +- AnalysisService.OUTLINE: [pathname] +- }); +- Outline outline; +- onAnalysisOutline.listen((AnalysisOutlineParams params) { +- expect(params.file, equals(pathname)); +- outline = params.outline; +- }); +- return analysisFinished.then((_) { +- expect(outline.element.kind, equals(ElementKind.COMPILATION_UNIT)); +- expect(outline.offset, equals(0)); +- expect(outline.length, equals(text.length)); +- List classes = outline.children; +- expect(classes, hasLength(2)); +- expect(classes[0].element.name, equals('Class1')); +- expect(classes[1].element.name, equals('Class2')); +- checkConnected(classes); +- List members = classes[0].children; +- expect(members, hasLength(5)); +- expect(members[0].element.name, equals('field')); +- expect(members[1].element.name, equals('method')); +- expect(members[2].element.name, equals('staticMethod')); +- expect(members[3].element.name, equals('getter')); +- expect(members[4].element.name, equals('setter')); +- checkConnected(members); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/overrides_test.dart b/pkg/analysis_server/test/integration/analysis/overrides_test.dart +deleted file mode 100644 +index 32c238ca122..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/overrides_test.dart ++++ /dev/null +@@ -1,122 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OverridesTest); +- }); +-} +- +-@reflectiveTest +-class OverridesTest extends AbstractAnalysisServerIntegrationTest { +- test_overrides() { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-abstract class Interface1 { +- method0(); +- method1(); +- method2(); +- method3(); +-} +- +-abstract class Interface2 { +- method0(); +- method1(); +- method4(); +- method5(); +-} +- +-abstract class Base { +- method0(); +- method2(); +- method4(); +- method6(); +-} +- +-class Target extends Base implements Interface1, Interface2 { +- method0() {} +- method1() {} +- method2() {} +- method3() {} +- method4() {} +- method5() {} +- method6() {} +- method7() {} +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- sendAnalysisSetSubscriptions({ +- AnalysisService.OVERRIDES: [pathname] +- }); +- List overrides; +- onAnalysisOverrides.listen((AnalysisOverridesParams params) { +- expect(params.file, equals(pathname)); +- overrides = params.overrides; +- }); +- return analysisFinished.then((_) { +- int targetOffset = text.indexOf('Target'); +- Override findOverride(String methodName) { +- int methodOffset = text.indexOf(methodName, targetOffset); +- for (Override override in overrides) { +- if (override.offset == methodOffset) { +- return override; +- } +- } +- return null; +- } +- +- void checkOverrides(String methodName, bool expectedOverridesBase, +- List expectedOverridesInterfaces) { +- Override override = findOverride(methodName); +- if (!expectedOverridesBase && expectedOverridesInterfaces.isEmpty) { +- // This method overrides nothing, so it should not appear in the +- // overrides list. +- expect(override, isNull); +- return; +- } else { +- expect(override, isNotNull); +- } +- expect(override.length, equals(methodName.length)); +- OverriddenMember superclassMember = override.superclassMember; +- if (expectedOverridesBase) { +- expect(superclassMember.element.name, equals(methodName)); +- expect(superclassMember.className, equals('Base')); +- } else { +- expect(superclassMember, isNull); +- } +- List interfaceMembers = override.interfaceMembers; +- if (expectedOverridesInterfaces.isNotEmpty) { +- expect(interfaceMembers, isNotNull); +- Set actualOverridesInterfaces = new Set(); +- for (OverriddenMember overriddenMember in interfaceMembers) { +- expect(overriddenMember.element.name, equals(methodName)); +- String className = overriddenMember.className; +- bool wasAdded = actualOverridesInterfaces.add(className); +- expect(wasAdded, isTrue); +- } +- expect(actualOverridesInterfaces, +- equals(expectedOverridesInterfaces.toSet())); +- } else { +- expect(interfaceMembers, isNull); +- } +- } +- +- checkOverrides('method0', true, ['Interface1', 'Interface2']); +- checkOverrides('method1', false, ['Interface1', 'Interface2']); +- checkOverrides('method2', true, ['Interface1']); +- checkOverrides('method3', false, ['Interface1']); +- checkOverrides('method4', true, ['Interface2']); +- checkOverrides('method5', false, ['Interface2']); +- checkOverrides('method6', true, []); +- checkOverrides('method7', false, []); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/package_root_test.dart b/pkg/analysis_server/test/integration/analysis/package_root_test.dart +deleted file mode 100644 +index d2e1c2c1b98..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/package_root_test.dart ++++ /dev/null +@@ -1,79 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetAnalysisRootsTest); +- }); +-} +- +-@reflectiveTest +-class SetAnalysisRootsTest extends AbstractAnalysisServerIntegrationTest { +- test_package_root() { +- String projPath = sourcePath('project'); +- String mainPath = path.join(projPath, 'main.dart'); +- String packagesPath = sourcePath('packages'); +- String fooBarPath = path.join(packagesPath, 'foo', 'bar.dart'); +- String mainText = """ +-library main; +- +-import 'package:foo/bar.dart' +- +-main() { +- f(); +-} +-"""; +- String fooBarText = """ +-library foo.bar; +- +-f() {} +-"""; +- writeFile(mainPath, mainText); +- String normalizedFooBarPath = writeFile(fooBarPath, fooBarText); +- sendServerSetSubscriptions([ServerService.STATUS]); +- sendAnalysisSetSubscriptions({ +- AnalysisService.NAVIGATION: [mainPath] +- }); +- List navigationRegions; +- List navigationTargets; +- List navigationTargetFiles; +- onAnalysisNavigation.listen((AnalysisNavigationParams params) { +- expect(params.file, equals(mainPath)); +- navigationRegions = params.regions; +- navigationTargets = params.targets; +- navigationTargetFiles = params.files; +- }); +- sendAnalysisSetAnalysisRoots([projPath], [], +- packageRoots: {projPath: packagesPath}); +- sendAnalysisSetPriorityFiles([mainPath]); +- return analysisFinished.then((_) { +- // Verify that fooBarPath was properly resolved by checking that f() +- // refers to it. +- bool found = false; +- for (NavigationRegion region in navigationRegions) { +- String navigationSource = +- mainText.substring(region.offset, region.offset + region.length); +- if (navigationSource == 'f') { +- found = true; +- expect(region.targets, hasLength(1)); +- int navigationTargetIndex = region.targets[0]; +- NavigationTarget navigationTarget = +- navigationTargets[navigationTargetIndex]; +- String navigationFile = +- navigationTargetFiles[navigationTarget.fileIndex]; +- expect(navigationFile, equals(normalizedFooBarPath)); +- } +- } +- expect(found, isTrue); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart b/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart +deleted file mode 100644 +index 11b7ceb615c..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart ++++ /dev/null +@@ -1,49 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * This test verifies that if reanalysis is performed while reanalysis is in +- * progress, no problems occur. +- * +- * See dartbug.com/21448. +- */ +-import 'dart:async'; +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ReanalyzeTest); +- }); +-} +- +-@reflectiveTest +-class ReanalyzeTest extends AbstractAnalysisServerIntegrationTest { +- test_reanalyze_concurrent() { +- String pathname = sourcePath('test.dart'); +- String text = ''' +-// Do a bunch of imports so that analysis has some work to do. +-import 'dart:io'; +-import 'dart:convert'; +-import 'dart:async'; +- +-main() {}'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- return analysisFinished.then((_) { +- sendAnalysisReanalyze(); +- // Wait for reanalysis to start. +- return onServerStatus.first.then((_) { +- sendAnalysisReanalyze(); +- return analysisFinished.then((_) { +- // Now that reanalysis has finished, give the server an extra second +- // to make sure it doesn't crash. +- return new Future.delayed(new Duration(seconds: 1)); +- }); +- }); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart b/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart +deleted file mode 100644 +index 8740ef03f28..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart ++++ /dev/null +@@ -1,40 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ReanalyzeTest); +- }); +-} +- +-@reflectiveTest +-class ReanalyzeTest extends AbstractAnalysisServerIntegrationTest { +- test_reanalyze() { +- String pathname = sourcePath('test.dart'); +- String text = 'main() {}'; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- return analysisFinished.then((_) { +- // Make sure that reanalyze causes analysis to restart. +- bool analysisRestarted = false; +- onServerStatus.listen((ServerStatusParams data) { +- if (data.analysis != null) { +- if (data.analysis.isAnalyzing) { +- analysisRestarted = true; +- } +- } +- }); +- sendAnalysisReanalyze(); +- return analysisFinished.then((_) { +- expect(analysisRestarted, isTrue); +- }); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/set_analysis_roots_test.dart b/pkg/analysis_server/test/integration/analysis/set_analysis_roots_test.dart +deleted file mode 100644 +index f6c1d6125bd..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/set_analysis_roots_test.dart ++++ /dev/null +@@ -1,32 +0,0 @@ +-// 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 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetAnalysisRootsTest); +- }); +-} +- +-@reflectiveTest +-class SetAnalysisRootsTest extends AbstractAnalysisServerIntegrationTest { +- test_options() async { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-class Foo { +- void bar() {} +-} +-'''); +- +- // Calling this will call analysis.setAnalysisRoots. +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/set_general_subscriptions_test.dart b/pkg/analysis_server/test/integration/analysis/set_general_subscriptions_test.dart +deleted file mode 100644 +index 9d491570730..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/set_general_subscriptions_test.dart ++++ /dev/null +@@ -1,40 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetGeneralSubscriptionsTest); +- }); +-} +- +-@reflectiveTest +-class SetGeneralSubscriptionsTest +- extends AbstractAnalysisServerIntegrationTest { +- test_options() async { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-class Foo { +- void bar() {} +-} +-'''); +- +- standardAnalysisSetup(); +- +- await sendAnalysisSetGeneralSubscriptions( +- [GeneralAnalysisService.ANALYZED_FILES]); +- await analysisFinished; +- +- expect(lastAnalyzedFiles, isNotEmpty); +- expect(lastAnalyzedFiles, contains(pathname)); +- expect( +- lastAnalyzedFiles.any((String file) => file.endsWith('core/core.dart')), +- true); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart +deleted file mode 100644 +index 10cb1a07fbd..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/set_priority_files_test.dart ++++ /dev/null +@@ -1,30 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetPriorityFilesTest); +- }); +-} +- +-@reflectiveTest +-class SetPriorityFilesTest extends AbstractAnalysisServerIntegrationTest { +- test_options() async { +- String pathname = sourcePath('foo.dart'); +- writeFile(pathname, 'class Foo { void baz() {} }'); +- writeFile(sourcePath('bar.dart'), 'class Bar { void baz() {} }'); +- +- standardAnalysisSetup(); +- await sendAnalysisSetPriorityFiles([pathname]); +- +- ServerStatusParams status = await analysisFinished; +- expect(status.analysis.isAnalyzing, false); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/set_subscriptions_test.dart b/pkg/analysis_server/test/integration/analysis/set_subscriptions_test.dart +deleted file mode 100644 +index 9524b4dd443..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/set_subscriptions_test.dart ++++ /dev/null +@@ -1,32 +0,0 @@ +-// 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 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetSubscriptionsTest); +- }); +-} +- +-@reflectiveTest +-class SetSubscriptionsTest extends AbstractAnalysisServerIntegrationTest { +- test_subscriptions() async { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-class Foo { +- void bar() {} +-} +-'''); +- +- // Calling this will subscribe to ServerService.STATUS. +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart +deleted file mode 100644 +index e7a825d80c6..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/test_all.dart ++++ /dev/null +@@ -1,66 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'analysis_options_test.dart' as analysis_options_test; +-import 'error_test.dart' as error_test; +-import 'get_errors_nonStandard_sdk.dart' as get_errors_nonStandard_sdk; +-import 'get_errors_test.dart' as get_errors_test; +-import 'get_hover_test.dart' as get_hover_test; +-import 'get_imported_elements_test.dart' as get_imported_elements_test; +-import 'get_library_dependencies_test.dart' as get_library_dependencies_test; +-import 'get_navigation_test.dart' as get_navigation_test; +-import 'get_reachable_sources_test.dart' as get_reachable_sources_test; +-import 'highlights_test.dart' as highlights_test; +-import 'highlights_test2.dart' as highlights_test2; +-import 'lint_test.dart' as lint_test; +-import 'navigation_test.dart' as navigation_test; +-import 'occurrences_test.dart' as occurrences_test; +-import 'outline_test.dart' as outline_test; +-import 'overrides_test.dart' as overrides_test; +-import 'package_root_test.dart' as package_root_test; +-import 'reanalyze_concurrent_test.dart' as reanalyze_concurrent_test; +-import 'reanalyze_test.dart' as reanalyze_test; +-import 'set_analysis_roots_test.dart' as set_analysis_roots_test; +-import 'set_general_subscriptions_test.dart' as set_general_subscriptions_test; +-import 'set_priority_files_test.dart' as set_priority_files_test; +-import 'set_subscriptions_test.dart' as set_subscriptions_test; +-import 'update_content_list_test.dart' as update_content_list_test; +-import 'update_content_test.dart' as update_content_test; +-import 'update_options_test.dart' as update_options_test; +- +-/** +- * Utility for manually running all integration tests. +- */ +-main() { +- defineReflectiveSuite(() { +- analysis_options_test.main(); +- error_test.main(); +- get_errors_test.main(); +- get_errors_nonStandard_sdk.main(); +- get_library_dependencies_test.main(); +- get_hover_test.main(); +- get_imported_elements_test.main(); +- get_navigation_test.main(); +- get_reachable_sources_test.main(); +- highlights_test.main(); +- highlights_test2.main(); +- lint_test.main(); +- navigation_test.main(); +- occurrences_test.main(); +- outline_test.main(); +- overrides_test.main(); +- package_root_test.main(); +- reanalyze_concurrent_test.main(); +- reanalyze_test.main(); +- set_analysis_roots_test.main(); +- set_general_subscriptions_test.main(); +- set_priority_files_test.main(); +- set_subscriptions_test.main(); +- update_content_test.main(); +- update_content_list_test.main(); +- update_options_test.main(); +- }, name: 'analysis'); +-} +diff --git a/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart +deleted file mode 100644 +index d44cce76f90..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart ++++ /dev/null +@@ -1,52 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(UpdateContentTest); +- }); +-} +- +-@reflectiveTest +-class UpdateContentTest extends AbstractAnalysisServerIntegrationTest { +- test_updateContent_list() { +- String pathname = sourcePath('test.dart'); +- String goodText = r''' +-main() { +- print("Hello"); +- print("World!"); +-}'''; +- String badText = goodText.replaceAll('"', ''); +- // Create a dummy file +- writeFile(pathname, '// dummy text'); +- standardAnalysisSetup(); +- // Override file contents with badText. +- sendAnalysisUpdateContent({pathname: new AddContentOverlay(badText)}); +- return analysisFinished.then((_) { +- // The overridden contents (badText) are missing quotation marks. +- expect(currentAnalysisErrors[pathname], isNotEmpty); +- }).then((_) { +- // Prepare a set of edits which add the missing quotation marks, in the +- // order in which they appear in the file. If these edits are applied in +- // the wrong order, some of the quotation marks will be in the wrong +- // places, and there will still be errors. +- List edits = '"' +- .allMatches(goodText) +- .map((Match match) => new SourceEdit(match.start, 0, '"')) +- .toList(); +- sendAnalysisUpdateContent({pathname: new ChangeContentOverlay(edits)}); +- return analysisFinished; +- }).then((_) { +- // There should be no errors now, assuming that quotation marks have been +- // inserted in all the correct places. +- expect(currentAnalysisErrors[pathname], isEmpty); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/update_content_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_test.dart +deleted file mode 100644 +index 0e307b3aedc..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/update_content_test.dart ++++ /dev/null +@@ -1,107 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(UpdateContentTest); +- }); +-} +- +-@reflectiveTest +-class UpdateContentTest extends AbstractAnalysisServerIntegrationTest { +- test_updateContent() async { +- String path = sourcePath('test.dart'); +- String goodText = r''' +-main() { +- print("Hello, world!"); +-}'''; +- +- String badText = goodText.replaceAll(';', ''); +- writeFile(path, badText); +- standardAnalysisSetup(); +- +- // The contents on disk (badText) are missing a semicolon. +- await analysisFinished; +- expect(currentAnalysisErrors[path], isNotEmpty); +- +- // There should be no errors now because the contents on disk have been +- // overridden with goodText. +- sendAnalysisUpdateContent({path: new AddContentOverlay(goodText)}); +- await analysisFinished; +- expect(currentAnalysisErrors[path], isEmpty); +- +- // There should be errors now because we've removed the semicolon. +- sendAnalysisUpdateContent({ +- path: new ChangeContentOverlay( +- [new SourceEdit(goodText.indexOf(';'), 1, '')]) +- }); +- await analysisFinished; +- expect(currentAnalysisErrors[path], isNotEmpty); +- +- // There should be no errors now because we've added the semicolon back. +- sendAnalysisUpdateContent({ +- path: new ChangeContentOverlay( +- [new SourceEdit(goodText.indexOf(';'), 0, ';')]) +- }); +- await analysisFinished; +- expect(currentAnalysisErrors[path], isEmpty); +- +- // Now there should be errors again, because the contents on disk are no +- // longer overridden. +- sendAnalysisUpdateContent({path: new RemoveContentOverlay()}); +- await analysisFinished; +- expect(currentAnalysisErrors[path], isNotEmpty); +- } +- +- @failingTest +- test_updateContent_multipleAdds() async { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, r''' +-class Person { +- String _name; +- Person(this._name); +- String get name => this._name; +- String toString() => "Name: ${name}"; +-} +-void main() { +- var p = new Person("Skeletor"); +- p.xname = "Faker"; +- print(p); +-} +-'''); +- standardAnalysisSetup(); +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isList); +- List errors1 = currentAnalysisErrors[pathname]; +- expect(errors1, hasLength(1)); +- expect(errors1[0].location.file, equals(pathname)); +- +- await sendAnalysisUpdateContent({ +- pathname: new AddContentOverlay(r''' +-class Person { +- String _name; +- Person(this._name); +- String get name => this._name; +- String toString() => "Name: ${name}"; +-} +-void main() { +- var p = new Person("Skeletor"); +- p.name = "Faker"; +- print(p); +-} +-''') +- }); +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isList); +- List errors2 = currentAnalysisErrors[pathname]; +- expect(errors2, hasLength(1)); +- expect(errors2[0].location.file, equals(pathname)); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analysis/update_options_test.dart b/pkg/analysis_server/test/integration/analysis/update_options_test.dart +deleted file mode 100644 +index 1172d78e8ea..00000000000 +--- a/pkg/analysis_server/test/integration/analysis/update_options_test.dart ++++ /dev/null +@@ -1,47 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(UpdateOptionsTest); +- }); +-} +- +-@reflectiveTest +-class UpdateOptionsTest extends AbstractAnalysisServerIntegrationTest { +- @failingTest +- test_options() async { +- // We fail after the first analysis.updateOptions - we should not see a hint +- // for the unused import (#28800). +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-import 'dart:async'; // unused +- +-class Foo { +- void bar() {} +-} +-'''); +- standardAnalysisSetup(); +- +- // ignore: deprecated_member_use +- await sendAnalysisUpdateOptions( +- new AnalysisOptions()..generateHints = false); +- await sendAnalysisReanalyze(); +- await analysisFinished; +- expect(getErrors(pathname), isEmpty); +- +- // ignore: deprecated_member_use +- await sendAnalysisUpdateOptions( +- new AnalysisOptions()..generateHints = true); +- await sendAnalysisReanalyze(); +- await analysisFinished; +- expect(getErrors(pathname), hasLength(1)); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analytics/enable_test.dart b/pkg/analysis_server/test/integration/analytics/enable_test.dart +deleted file mode 100644 +index a32971f9458..00000000000 +--- a/pkg/analysis_server/test/integration/analytics/enable_test.dart ++++ /dev/null +@@ -1,33 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(EnableTest); +- }); +-} +- +-@reflectiveTest +-class EnableTest extends AbstractAnalysisServerIntegrationTest { +- test_call_enable() async { +- standardAnalysisSetup(); +- +- // Toggle the value twice, and verify the changes. +- AnalyticsIsEnabledResult result1 = await sendAnalyticsIsEnabled(); +- await sendAnalyticsEnable(!result1.enabled); +- +- AnalyticsIsEnabledResult result2 = await sendAnalyticsIsEnabled(); +- expect(result2.enabled, !result1.enabled); +- +- await sendAnalyticsEnable(result1.enabled); +- result2 = await sendAnalyticsIsEnabled(); +- expect(result2.enabled, result1.enabled); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analytics/is_enabled_test.dart b/pkg/analysis_server/test/integration/analytics/is_enabled_test.dart +deleted file mode 100644 +index 8e2ffd5aae1..00000000000 +--- a/pkg/analysis_server/test/integration/analytics/is_enabled_test.dart ++++ /dev/null +@@ -1,26 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(IsEnabledTest); +- }); +-} +- +-@reflectiveTest +-class IsEnabledTest extends AbstractAnalysisServerIntegrationTest { +- test_isEnabled() async { +- standardAnalysisSetup(); +- +- AnalyticsIsEnabledResult result = await sendAnalyticsIsEnabled(); +- // Very lightweight validation of the returned data. +- expect(result, isNotNull); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analytics/send_event_test.dart b/pkg/analysis_server/test/integration/analytics/send_event_test.dart +deleted file mode 100644 +index fbeb48adf19..00000000000 +--- a/pkg/analysis_server/test/integration/analytics/send_event_test.dart ++++ /dev/null +@@ -1,31 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SendEventTest); +- }); +-} +- +-@reflectiveTest +-class SendEventTest extends AbstractAnalysisServerIntegrationTest { +- test_send_event() async { +- standardAnalysisSetup(); +- +- // Disable analytics. +- AnalyticsIsEnabledResult result1 = await sendAnalyticsIsEnabled(); +- await sendAnalyticsEnable(false); +- +- // Send an event. +- await sendAnalyticsSendEvent('test-action'); +- +- // Restore the original value. +- await sendAnalyticsEnable(result1.enabled); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analytics/send_timing_test.dart b/pkg/analysis_server/test/integration/analytics/send_timing_test.dart +deleted file mode 100644 +index fb65d8a478c..00000000000 +--- a/pkg/analysis_server/test/integration/analytics/send_timing_test.dart ++++ /dev/null +@@ -1,31 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SendTimingTest); +- }); +-} +- +-@reflectiveTest +-class SendTimingTest extends AbstractAnalysisServerIntegrationTest { +- test_send_timing() async { +- standardAnalysisSetup(); +- +- // Disable analytics. +- AnalyticsIsEnabledResult result1 = await sendAnalyticsIsEnabled(); +- await sendAnalyticsEnable(false); +- +- // Send an event. +- await sendAnalyticsSendTiming('test-action', 100); +- +- // Restore the original value. +- await sendAnalyticsEnable(result1.enabled); +- } +-} +diff --git a/pkg/analysis_server/test/integration/analytics/test_all.dart b/pkg/analysis_server/test/integration/analytics/test_all.dart +deleted file mode 100644 +index d4352b7a485..00000000000 +--- a/pkg/analysis_server/test/integration/analytics/test_all.dart ++++ /dev/null +@@ -1,19 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'enable_test.dart' as enable_test; +-import 'is_enabled_test.dart' as is_enabled_test; +-import 'send_event_test.dart' as send_event_test; +-import 'send_timing_test.dart' as send_timing_test; +- +-main() { +- defineReflectiveSuite(() { +- enable_test.main(); +- is_enabled_test.main(); +- send_event_test.main(); +- send_timing_test.main(); +- }, name: 'analytics'); +-} +diff --git a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart +deleted file mode 100644 +index 1efd154b081..00000000000 +--- a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart ++++ /dev/null +@@ -1,118 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetSuggestionsTest); +- }); +-} +- +-@reflectiveTest +-class GetSuggestionsTest extends AbstractAnalysisServerIntegrationTest { +- String path; +- String content; +- int completionOffset; +- +- void setTestSource(String relPath, String content) { +- path = sourcePath(relPath); +- expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once'); +- completionOffset = content.indexOf('^'); +- expect(completionOffset, isNot(equals(-1)), reason: 'missing ^'); +- int nextOffset = content.indexOf('^', completionOffset + 1); +- expect(nextOffset, equals(-1), reason: 'too many ^'); +- this.content = content.substring(0, completionOffset) + +- content.substring(completionOffset + 1); +- } +- +- test_getSuggestions() async { +- setTestSource('test.dart', r''' +-String test = ''; +-main() { +- test.^ +-} +-'''); +- writeFile(path, content); +- await standardAnalysisSetup(); +- await analysisFinished; +- CompletionGetSuggestionsResult result = +- await sendCompletionGetSuggestions(path, completionOffset); +- String completionId = result.id; +- CompletionResultsParams param = await onCompletionResults.firstWhere( +- (CompletionResultsParams param) => +- param.id == completionId && param.isLast); +- expect(param.replacementOffset, completionOffset); +- expect(param.replacementLength, 0); +- param.results.firstWhere( +- (CompletionSuggestion suggestion) => suggestion.completion == 'length'); +- } +- +- test_getSuggestions_onlyOverlay() async { +- setTestSource('test.dart', r''' +-String test = ''; +-main() { +- test.^ +-} +-'''); +- // Create an overlay but do not write the file to "disk" +- // writeFile(pathname, text); +- await standardAnalysisSetup(); +- await sendAnalysisUpdateContent({path: new AddContentOverlay(content)}); +- await analysisFinished; +- CompletionGetSuggestionsResult result = +- await sendCompletionGetSuggestions(path, completionOffset); +- String completionId = result.id; +- CompletionResultsParams param = await onCompletionResults.firstWhere( +- (CompletionResultsParams param) => +- param.id == completionId && param.isLast); +- expect(param.replacementOffset, completionOffset); +- expect(param.replacementLength, 0); +- param.results.firstWhere( +- (CompletionSuggestion suggestion) => suggestion.completion == 'length'); +- } +- +- test_getSuggestions_onlyOverlay_noWait() async { +- setTestSource('test.dart', r''' +-String test = ''; +-main() { +- test.^ +-} +-'''); +- // Create an overlay but do not write the file to "disk" +- // writeFile(pathname, text); +- // Don't wait for any results except the completion notifications +- standardAnalysisSetup(subscribeStatus: false); +- sendAnalysisUpdateContent({path: new AddContentOverlay(content)}); +- sendCompletionGetSuggestions(path, completionOffset); +- CompletionResultsParams param = await onCompletionResults +- .firstWhere((CompletionResultsParams param) => param.isLast); +- expect(param.replacementOffset, completionOffset); +- expect(param.replacementLength, 0); +- param.results.firstWhere( +- (CompletionSuggestion suggestion) => suggestion.completion == 'length'); +- } +- +- test_getSuggestions_sourceMissing_noWait() { +- path = sourcePath('does_not_exist.dart'); +- // Do not write the file to "disk" +- // writeFile(pathname, text); +- // Don't wait for any results except the completion notifications +- standardAnalysisSetup(subscribeStatus: false); +- // Missing file and no overlay +- //sendAnalysisUpdateContent({path: new AddContentOverlay(content)}); +- var errorToken = 'exception from server'; +- return sendCompletionGetSuggestions(path, 0).catchError((e) { +- // Exception expected +- return errorToken; +- }).then((result) { +- expect(result, new isInstanceOf()); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/completion/test_all.dart b/pkg/analysis_server/test/integration/completion/test_all.dart +deleted file mode 100644 +index f07053b91ad..00000000000 +--- a/pkg/analysis_server/test/integration/completion/test_all.dart ++++ /dev/null +@@ -1,16 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'get_suggestions_test.dart' as get_suggestions_test; +- +-/** +- * Utility for manually running all integration tests. +- */ +-main() { +- defineReflectiveSuite(() { +- get_suggestions_test.main(); +- }, name: 'completion'); +-} +diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md +deleted file mode 100644 +index 9d0ac620842..00000000000 +--- a/pkg/analysis_server/test/integration/coverage.md ++++ /dev/null +@@ -1,83 +0,0 @@ +-Checklist to ensure that we have integration test coverage of all analysis +-server calls. This file is validated by `coverage_test.dart`. +- +-## analysis domain +-- [x] analysis.getErrors +-- [x] analysis.getHover +-- [x] analysis.getImportedElements +-- [x] analysis.getLibraryDependencies (failing - see #29310) +-- [x] analysis.getNavigation (failing - see #28799) +-- [x] analysis.getReachableSources (failing - see #29311) +-- [x] analysis.reanalyze +-- [x] analysis.setAnalysisRoots +-- [x] analysis.setGeneralSubscriptions +-- [x] analysis.setPriorityFiles +-- [x] analysis.setSubscriptions +-- [x] analysis.updateContent +-- [x] analysis.updateOptions (failing - see #28800) (deprecated) +-- [ ] analysis.analyzedFiles +-- [ ] analysis.closingLabels +-- [ ] analysis.errors +-- [ ] analysis.flushResults +-- [ ] analysis.folding +-- [x] analysis.highlights +-- [ ] analysis.implemented +-- [ ] analysis.invalidate +-- [x] analysis.navigation +-- [x] analysis.occurrences +-- [x] analysis.outline +-- [x] analysis.overrides +- +-## completion domain +-- [x] completion.getSuggestions +-- [ ] completion.results +- +-## diagnostic domain +-- [x] diagnostic.getDiagnostics +-- [x] diagnostic.getServerPort +- +-## edit domain +-- [x] edit.format +-- [x] edit.getAssists +-- [x] edit.getAvailableRefactorings +-- [x] edit.getFixes +-- [x] edit.getPostfixCompletion +-- [x] edit.getRefactoring +-- [x] edit.getStatementCompletion +-- [x] edit.importElements +-- [x] edit.isPostfixCompletionApplicable +-- [x] edit.listPostfixCompletionTemplates +-- [x] edit.sortMembers +-- [x] edit.organizeDirectives +- +-## execution domain +-- [x] execution.createContext +-- [x] execution.deleteContext +-- [x] execution.mapUri +-- [x] execution.setSubscriptions +-- [ ] execution.launchData +- +-## search domain +-- [x] search.findElementReferences +-- [x] search.findMemberDeclarations +-- [x] search.findMemberReferences +-- [x] search.findTopLevelDeclarations +-- [x] search.getTypeHierarchy +-- [ ] search.results +- +-## server domain +-- [x] server.getVersion +-- [x] server.shutdown +-- [x] server.setSubscriptions +-- [ ] server.connected +-- [ ] server.error +-- [x] server.status +- +-## analytics domain +-- [x] analytics.isEnabled +-- [x] analytics.enable +-- [x] analytics.sendEvent +-- [x] analytics.sendTiming +- +-## kythe domain +-- [x] kythe.getKytheEntries +diff --git a/pkg/analysis_server/test/integration/coverage_test.dart b/pkg/analysis_server/test/integration/coverage_test.dart +deleted file mode 100644 +index b8b3c14e237..00000000000 +--- a/pkg/analysis_server/test/integration/coverage_test.dart ++++ /dev/null +@@ -1,129 +0,0 @@ +-// 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:io'; +- +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +- +-import '../../tool/spec/api.dart'; +-import '../../tool/spec/from_html.dart'; +- +-/// Define tests to fail if there's no mention in the coverage file. +-main() { +- Api api; +- File coverageFile; +- String pathPrefix; +- +- // parse the API file +- if (FileSystemEntity +- .isFileSync(path.join('tool', 'spec', 'spec_input.html'))) { +- api = readApi('.'); +- pathPrefix = '.'; +- } else { +- api = readApi(path.join('pkg', 'analysis_server')); +- pathPrefix = path.join('pkg', 'analysis_server'); +- } +- +- coverageFile = +- new File(path.join(pathPrefix, 'test', 'integration', 'coverage.md')); +- List lines = coverageFile.readAsLinesSync(); +- +- // ## server domain +- Set coveredDomains = lines +- .where((line) => line.startsWith('## ') && line.endsWith(' domain')) +- .map((line) => +- line.substring('##'.length, line.length - 'domain'.length).trim()) +- .toSet(); +- +- // Remove any ' (test failed)' suffixes. +- lines = lines.map((String line) { +- int index = line.indexOf('('); +- return index != -1 ? line.substring(0, index).trim() : line; +- }).toList(); +- +- // - [ ] server.getVersion +- Set allMembers = lines +- .where((line) => line.startsWith('- ')) +- .map((line) => line.substring('- [ ]'.length).trim()) +- .toSet(); +- Set coveredMembers = lines +- .where((line) => line.startsWith('- [x]')) +- .map((line) => line.substring('- [x]'.length).trim()) +- .toSet(); +- +- // generate domain tests +- for (Domain domain in api.domains) { +- group('integration coverage of ${domain.name}', () { +- // domain +- test('domain', () { +- if (!coveredDomains.contains(domain.name)) { +- fail('${domain.name} domain not found in ${coverageFile.path}'); +- } +- }); +- +- // requests +- group('request', () { +- for (Request request in domain.requests) { +- String fullName = '${domain.name}.${request.method}'; +- test(fullName, () { +- if (!allMembers.contains(fullName)) { +- fail('$fullName not found in ${coverageFile.path}'); +- } +- +- final String fileName = getCamelWords(request.method) +- .map((s) => s.toLowerCase()) +- .join('_'); +- final String testName = +- path.join(domain.name, '${fileName}_test.dart'); +- final String testPath = +- path.join(pathPrefix, 'test', 'integration', testName); +- +- // Test that if checked, a test file exists; if not checked, no such +- // file exists. +- expect(FileSystemEntity.isFileSync(testPath), +- coveredMembers.contains(fullName), +- reason: '$testName state incorrect'); +- }); +- } +- }); +- +- // notifications +- group('notification', () { +- for (Notification notification in domain.notifications) { +- String fullName = '${domain.name}.${notification.event}'; +- test(fullName, () { +- if (!allMembers.contains(fullName)) { +- fail('$fullName not found in ${coverageFile.path}'); +- } +- +- final String fileName = getCamelWords(notification.event) +- .map((s) => s.toLowerCase()) +- .join('_'); +- final String testName = +- path.join(domain.name, '${fileName}_test.dart'); +- final String testPath = +- path.join(pathPrefix, 'test', 'integration', testName); +- +- // Test that if checked, a test file exists; if not checked, no such +- // file exists. +- expect(FileSystemEntity.isFileSync(testPath), +- coveredMembers.contains(fullName), +- reason: '$testName state incorrect'); +- }); +- } +- }); +- }); +- } +- +- // validate no unexpected domains +- group('integration coverage', () { +- test('no unexpected domains', () { +- for (String domain in coveredDomains) { +- expect(api.domains.map((d) => d.name), contains(domain)); +- } +- }); +- }); +-} +diff --git a/pkg/analysis_server/test/integration/diagnostic/get_diagnostics_test.dart b/pkg/analysis_server/test/integration/diagnostic/get_diagnostics_test.dart +deleted file mode 100644 +index e8bf76e8a8c..00000000000 +--- a/pkg/analysis_server/test/integration/diagnostic/get_diagnostics_test.dart ++++ /dev/null +@@ -1,30 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetDiagnosticsTest); +- }); +-} +- +-@reflectiveTest +-class GetDiagnosticsTest extends AbstractAnalysisServerIntegrationTest { +- test_getDiagnostics() async { +- standardAnalysisSetup(); +- +- DiagnosticGetDiagnosticsResult result = +- await sendDiagnosticGetDiagnostics(); +- +- // Do some lightweight validation of the returned data. +- expect(result.contexts, hasLength(1)); +- ContextData context = result.contexts.first; +- expect(context.name, isNotEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart b/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart +deleted file mode 100644 +index b04384f11da..00000000000 +--- a/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart ++++ /dev/null +@@ -1,37 +0,0 @@ +-// 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:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetServerPortTest); +- }); +-} +- +-@reflectiveTest +-class GetServerPortTest extends AbstractAnalysisServerIntegrationTest { +- test_connect() async { +- standardAnalysisSetup(); +- +- DiagnosticGetServerPortResult result = await sendDiagnosticGetServerPort(); +- expect(result.port, isNotNull); +- expect(result.port, isNonZero); +- +- // Connect to the server and verify that it's serving the status page. +- HttpClient client = new HttpClient(); +- HttpClientRequest request = await client +- .getUrl(Uri.parse('http://localhost:${result.port}/status')); +- HttpClientResponse response = await request.close(); +- String responseBody = await UTF8.decodeStream(response); +- expect(responseBody, contains('Analysis Server')); +- } +-} +diff --git a/pkg/analysis_server/test/integration/diagnostic/test_all.dart b/pkg/analysis_server/test/integration/diagnostic/test_all.dart +deleted file mode 100644 +index 4e45dea57d5..00000000000 +--- a/pkg/analysis_server/test/integration/diagnostic/test_all.dart ++++ /dev/null +@@ -1,15 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'get_diagnostics_test.dart' as get_diagnostics_test; +-import 'get_server_port_test.dart' as get_server_port_test; +- +-main() { +- defineReflectiveSuite(() { +- get_diagnostics_test.main(); +- get_server_port_test.main(); +- }, name: 'diagnostics'); +-} +diff --git a/pkg/analysis_server/test/integration/edit/format_test.dart b/pkg/analysis_server/test/integration/edit/format_test.dart +deleted file mode 100644 +index 89061094201..00000000000 +--- a/pkg/analysis_server/test/integration/edit/format_test.dart ++++ /dev/null +@@ -1,80 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FormatTest); +- }); +-} +- +-@reflectiveTest +-class FormatTest extends AbstractAnalysisServerIntegrationTest { +- String formatTestSetup({bool withErrors: false}) { +- String pathname = sourcePath('test.dart'); +- +- if (withErrors) { +- String text = r''' +-class Class1 { +- int field +- void foo() { +- } +-} +-'''; +- writeFile(pathname, text); +- } else { +- String text = r''' +-class Class1 { +- int field; +- +- void foo() { +- } +- +- void bar() { +- } +-} +-'''; +- writeFile(pathname, text); +- } +- standardAnalysisSetup(); +- return pathname; +- } +- +- test_format() async { +- String pathname = formatTestSetup(); +- +- EditFormatResult result = await sendEditFormat(pathname, 0, 0); +- expect(result.edits, isNotEmpty); +- expect(result.selectionOffset, 0); +- expect(result.selectionLength, 0); +- } +- +- test_format_preserve_selection() async { +- String pathname = formatTestSetup(); +- +- // format with 'bar' selected +- int initialPosition = readFile(pathname).indexOf('bar()'); +- EditFormatResult result = +- await sendEditFormat(pathname, initialPosition, 'bar'.length); +- expect(result.edits, isNotEmpty); +- expect(result.selectionOffset, initialPosition - 3); +- expect(result.selectionLength, 'bar'.length); +- } +- +- test_format_with_errors() async { +- String pathname = formatTestSetup(withErrors: true); +- +- try { +- await sendEditFormat(pathname, 0, 0); +- fail('expected FORMAT_WITH_ERRORS'); +- } on ServerErrorMessage catch (message) { +- expect(message.error['code'], 'FORMAT_WITH_ERRORS'); +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/get_assists_test.dart b/pkg/analysis_server/test/integration/edit/get_assists_test.dart +deleted file mode 100644 +index 69e10f093ea..00000000000 +--- a/pkg/analysis_server/test/integration/edit/get_assists_test.dart ++++ /dev/null +@@ -1,50 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetAssistsTest); +- }); +-} +- +-@reflectiveTest +-class GetAssistsTest extends AbstractAnalysisServerIntegrationTest { +- test_has_assists() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:async'; +- +-Future f; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- +- // expect at least one assist (add show combinator to the dart:async import) +- EditGetAssistsResult result = +- await sendEditGetAssists(pathname, text.indexOf('dart:async'), 0); +- expect(result.assists, isNotEmpty); +- +- // apply it and make sure that the code analyzing cleanly +- SourceChange change = result.assists.singleWhere((SourceChange change) => +- change.message == "Add explicit 'show' combinator"); +- expect(change.edits, hasLength(1)); +- expect(change.edits.first.edits, hasLength(1)); +- SourceEdit edit = change.edits.first.edits.first; +- text = text.replaceRange(edit.offset, edit.end, edit.replacement); +- writeFile(pathname, text); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/get_available_refactorings_test.dart b/pkg/analysis_server/test/integration/edit/get_available_refactorings_test.dart +deleted file mode 100644 +index 820b5862acd..00000000000 +--- a/pkg/analysis_server/test/integration/edit/get_available_refactorings_test.dart ++++ /dev/null +@@ -1,37 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetAvailableRefactoringsTest); +- }); +-} +- +-@reflectiveTest +-class GetAvailableRefactoringsTest +- extends AbstractAnalysisServerIntegrationTest { +- test_has_refactorings() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-void foo() { } +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- +- // expect at least one refactoring +- EditGetAvailableRefactoringsResult result = +- await sendEditGetAvailableRefactorings( +- pathname, text.indexOf('foo('), 0); +- expect(result.kinds, isNotEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/get_fixes_test.dart b/pkg/analysis_server/test/integration/edit/get_fixes_test.dart +deleted file mode 100644 +index a76680d76ed..00000000000 +--- a/pkg/analysis_server/test/integration/edit/get_fixes_test.dart ++++ /dev/null +@@ -1,60 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetFixesTest); +- }); +-} +- +-@reflectiveTest +-class GetFixesTest extends AbstractAnalysisServerIntegrationTest { +- test_has_fixes() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-Future f; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isNotEmpty); +- +- EditGetFixesResult result = +- await sendEditGetFixes(pathname, text.indexOf('Future f')); +- expect(result.fixes, hasLength(1)); +- +- // expect a suggestion to add the dart:async import +- AnalysisErrorFixes fix = result.fixes.first; +- expect(fix.error.code, 'undefined_class'); +- expect(fix.fixes, isNotEmpty); +- +- SourceChange change = fix.fixes.singleWhere( +- (SourceChange change) => change.message.startsWith('Import ')); +- expect(change.edits, hasLength(1)); +- expect(change.edits.first.edits, hasLength(1)); +- } +- +- test_no_fixes() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:async'; +- +-Future f; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- EditGetFixesResult result = +- await sendEditGetFixes(pathname, text.indexOf('Future f')); +- expect(result.fixes, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart b/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart +deleted file mode 100644 +index b4b3cd481c9..00000000000 +--- a/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart ++++ /dev/null +@@ -1,52 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetPostfixCompletionTest); +- }); +-} +- +-@reflectiveTest +-class GetPostfixCompletionTest extends AbstractAnalysisServerIntegrationTest { +- test_postfix_completion() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-void bar() { +- foo();.tryon +-} +-void foo() { } +-'''; +- int loc = text.indexOf('.tryon'); +- text = text.replaceAll('.tryon', ''); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- +- // expect a postfix completion result +- EditGetPostfixCompletionResult result = +- await sendEditGetPostfixCompletion(pathname, '.tryon', loc); +- expect(result.change.edits, isNotEmpty); +- +- // apply the edit, expect that the new code has no errors +- SourceChange change = result.change; +- expect(change.edits.first.edits, isNotEmpty); +- for (SourceEdit edit in change.edits.first.edits) { +- text = text.replaceRange(edit.offset, edit.end, edit.replacement); +- } +- await sendAnalysisUpdateContent({pathname: new AddContentOverlay(text)}); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart b/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart +deleted file mode 100644 +index c3e5553acf8..00000000000 +--- a/pkg/analysis_server/test/integration/edit/get_refactoring_test.dart ++++ /dev/null +@@ -1,66 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetRefactoringTest); +- }); +-} +- +-@reflectiveTest +-class GetRefactoringTest extends AbstractAnalysisServerIntegrationTest { +- test_rename() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-void foo() { } +- +-void bar() { +- foo(); +- foo(); +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- +- // expect no edits if no rename options specified +- EditGetRefactoringResult result = await sendEditGetRefactoring( +- RefactoringKind.RENAME, pathname, text.indexOf('foo('), 0, false); +- expect(result.initialProblems, isEmpty); +- expect(result.optionsProblems, isEmpty); +- expect(result.finalProblems, isEmpty); +- expect(result.potentialEdits, isNull); +- expect(result.change, isNull); +- +- // expect a valid rename refactoring +- result = await sendEditGetRefactoring( +- RefactoringKind.RENAME, pathname, text.indexOf('foo('), 0, false, +- options: new RenameOptions('baz')); +- expect(result.initialProblems, isEmpty); +- expect(result.optionsProblems, isEmpty); +- expect(result.finalProblems, isEmpty); +- expect(result.potentialEdits, isNull); +- expect(result.change.edits, isNotEmpty); +- +- // apply the refactoring, expect that the new code has no errors +- SourceChange change = result.change; +- expect(change.edits.first.edits, isNotEmpty); +- for (SourceEdit edit in change.edits.first.edits) { +- text = text.replaceRange(edit.offset, edit.end, edit.replacement); +- } +- await sendAnalysisUpdateContent({pathname: new AddContentOverlay(text)}); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/get_statement_completion_test.dart b/pkg/analysis_server/test/integration/edit/get_statement_completion_test.dart +deleted file mode 100644 +index 1adece605ac..00000000000 +--- a/pkg/analysis_server/test/integration/edit/get_statement_completion_test.dart ++++ /dev/null +@@ -1,47 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetStatementCompletionTest); +- }); +-} +- +-@reflectiveTest +-class GetStatementCompletionTest extends AbstractAnalysisServerIntegrationTest { +- test_statement_completion() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-void bar() { foo() } // missing semi-colon +-void foo() { }'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isNotEmpty); +- +- // expect a statement completion result +- EditGetStatementCompletionResult result = +- await sendEditGetStatementCompletion(pathname, text.indexOf('foo(')); +- expect(result.change.edits, isNotEmpty); +- +- // apply the edit, expect that the new code has no errors +- SourceChange change = result.change; +- expect(change.edits.first.edits, isNotEmpty); +- for (SourceEdit edit in change.edits.first.edits) { +- text = text.replaceRange(edit.offset, edit.end, edit.replacement); +- } +- await sendAnalysisUpdateContent({pathname: new AddContentOverlay(text)}); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/import_elements_test.dart b/pkg/analysis_server/test/integration/edit/import_elements_test.dart +deleted file mode 100644 +index b22fa39e121..00000000000 +--- a/pkg/analysis_server/test/integration/edit/import_elements_test.dart ++++ /dev/null +@@ -1,139 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer/src/dart/sdk/sdk.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisGetImportElementsIntegrationTest); +- }); +-} +- +-@reflectiveTest +-class AnalysisGetImportElementsIntegrationTest +- extends AbstractAnalysisServerIntegrationTest { +- /** +- * Pathname of the file containing Dart code. +- */ +- String pathname; +- +- /** +- * Check that an edit.importElements request with the given list of [elements] +- * produces the [expected] list of edits. +- */ +- checkEdits(List elements, List expected, +- {String expectedFile}) async { +- bool equals(SourceEdit actualEdit, SourceEdit expectedEdit) { +- return actualEdit.offset == expectedEdit.offset && +- actualEdit.length == expectedEdit.length && +- actualEdit.replacement == expectedEdit.replacement; +- } +- +- int find(List actual, SourceEdit expectedEdit) { +- for (int i = 0; i < actual.length; i++) { +- SourceEdit actualEdit = actual[i]; +- if (equals(actualEdit, expectedEdit)) { +- return i; +- } +- } +- return -1; +- } +- +- EditImportElementsResult result = +- await sendEditImportElements(pathname, elements); +- +- SourceFileEdit edit = result.edit; +- expect(edit, isNotNull); +- if (expectedFile == null) { +- expect(edit.file, pathname); +- } else { +- expect(edit.file, expectedFile); +- } +- List actual = edit.edits; +- expect(actual, hasLength(expected.length)); +- for (SourceEdit expectedEdit in expected) { +- int index = find(actual, expectedEdit); +- if (index < 0) { +- fail('Expected $expectedEdit; not found'); +- } +- actual.removeAt(index); +- } +- } +- +- /** +- * Check that an edit.importElements request with the given list of [elements] +- * produces no edits. +- */ +- Future checkNoEdits(List elements) async { +- EditImportElementsResult result = +- await sendEditImportElements(pathname, []); +- +- SourceFileEdit edit = result.edit; +- expect(edit, isNotNull); +- expect(edit.edits, hasLength(0)); +- } +- +- Future setUp() async { +- await super.setUp(); +- pathname = sourcePath('test.dart'); +- } +- +- test_importElements_definingUnit() async { +- writeFile(pathname, 'main() {}'); +- standardAnalysisSetup(); +- await analysisFinished; +- PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE; +- String sdkPath = FolderBasedDartSdk.defaultSdkDirectory(provider).path; +- String mathPath = +- provider.pathContext.join(sdkPath, 'lib', 'math', 'math.dart'); +- +- await checkEdits([ +- new ImportedElements(mathPath, '', ['Random']) +- ], [ +- new SourceEdit(0, 0, "import 'dart:math';\n\n") +- ]); +- } +- +- test_importElements_noEdits() async { +- writeFile(pathname, ''); +- standardAnalysisSetup(); +- await analysisFinished; +- +- await checkNoEdits([]); +- } +- +- test_importElements_part() async { +- String libName = sourcePath('lib.dart'); +- writeFile(libName, ''' +-part 'test.dart'; +-main() {} +-'''); +- writeFile(pathname, ''' +-part of 'lib.dart'; +- +-class C {} +-'''); +- standardAnalysisSetup(); +- await analysisFinished; +- PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE; +- String sdkPath = FolderBasedDartSdk.defaultSdkDirectory(provider).path; +- String mathPath = +- provider.pathContext.join(sdkPath, 'lib', 'math', 'math.dart'); +- +- await checkEdits([ +- new ImportedElements(mathPath, '', ['Random']) +- ], [ +- new SourceEdit(0, 0, "import 'dart:math';\n\n") +- ], expectedFile: libName); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/is_postfix_completion_applicable_test.dart b/pkg/analysis_server/test/integration/edit/is_postfix_completion_applicable_test.dart +deleted file mode 100644 +index be1ff11aa3f..00000000000 +--- a/pkg/analysis_server/test/integration/edit/is_postfix_completion_applicable_test.dart ++++ /dev/null +@@ -1,41 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(IsPostfixCompletionApplicableTest); +- }); +-} +- +-@reflectiveTest +-class IsPostfixCompletionApplicableTest +- extends AbstractAnalysisServerIntegrationTest { +- test_is_postfix_completion_applicable() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-void bar() { +- foo();.tryon +-} +-void foo() { } +-'''; +- int loc = text.indexOf('.tryon'); +- text = text.replaceAll('.tryon', ''); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- expect(currentAnalysisErrors[pathname], isEmpty); +- +- // expect a postfix completion applicable result +- EditIsPostfixCompletionApplicableResult result = +- await sendEditIsPostfixCompletionApplicable(pathname, '.tryon', loc); +- expect(result.value, isTrue); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/list_postfix_completion_templates_test.dart b/pkg/analysis_server/test/integration/edit/list_postfix_completion_templates_test.dart +deleted file mode 100644 +index f248e06aef0..00000000000 +--- a/pkg/analysis_server/test/integration/edit/list_postfix_completion_templates_test.dart ++++ /dev/null +@@ -1,41 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ListPostfixCompletionTemplatesTest); +- }); +-} +- +-@reflectiveTest +-class ListPostfixCompletionTemplatesTest +- extends AbstractAnalysisServerIntegrationTest { +- test_list_postfix_completion_templates() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-void bar() { +- foo();.tryon +-} +-void foo() { } +-'''; +- text = text.replaceAll('.tryon', ''); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- // expect a postfix template list result +- EditListPostfixCompletionTemplatesResult result = +- await sendEditListPostfixCompletionTemplates(); +- expect(result.templates, isNotNull); +- expect(result.templates.length, greaterThan(15)); +- expect(result.templates[0].runtimeType, PostfixTemplateDescriptor); +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/organize_directives_test.dart b/pkg/analysis_server/test/integration/edit/organize_directives_test.dart +deleted file mode 100644 +index 0e372f43f72..00000000000 +--- a/pkg/analysis_server/test/integration/edit/organize_directives_test.dart ++++ /dev/null +@@ -1,76 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OrganizeDirectivesTest); +- }); +-} +- +-@reflectiveTest +-class OrganizeDirectivesTest extends AbstractAnalysisServerIntegrationTest { +- test_organize_directives() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:math'; +-import 'dart:async'; +- +-Future foo; +-int minified(int x, int y) => min(x, y); +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- EditOrganizeDirectivesResult result = +- await sendEditOrganizeDirectives(pathname); +- SourceFileEdit edit = result.edit; +- expect(edit.edits, hasLength(1)); +- expect(edit.edits.first.replacement, +- "import 'dart:async';\nimport 'dart:math"); +- } +- +- test_organize_directives_no_changes() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:async'; +-import 'dart:math'; +- +-Future foo; +-int minified(int x, int y) => min(x, y); +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- EditOrganizeDirectivesResult result = +- await sendEditOrganizeDirectives(pathname); +- SourceFileEdit edit = result.edit; +- expect(edit.edits, isEmpty); +- } +- +- test_organize_directives_with_errors() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-import 'dart:async' +-import 'dart:math'; +- +-Future foo; +-int minified(int x, int y) => min(x, y); +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- try { +- await sendEditOrganizeDirectives(pathname); +- } on ServerErrorMessage catch (message) { +- expect(message.error['code'], 'ORGANIZE_DIRECTIVES_ERROR'); +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/sort_members_test.dart b/pkg/analysis_server/test/integration/edit/sort_members_test.dart +deleted file mode 100644 +index 3ff78a758be..00000000000 +--- a/pkg/analysis_server/test/integration/edit/sort_members_test.dart ++++ /dev/null +@@ -1,64 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SortMembersTest); +- }); +-} +- +-@reflectiveTest +-class SortMembersTest extends AbstractAnalysisServerIntegrationTest { +- test_sort() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-int foo; +-int bar; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- EditSortMembersResult result = await sendEditSortMembers(pathname); +- SourceFileEdit edit = result.edit; +- expect(edit.edits, hasLength(1)); +- expect(edit.edits.first.replacement, "bar;\nint foo"); +- } +- +- test_sort_no_changes() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-int bar; +-int foo; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- EditSortMembersResult result = await sendEditSortMembers(pathname); +- SourceFileEdit edit = result.edit; +- expect(edit.edits, isEmpty); +- } +- +- test_sort_with_errors() async { +- String pathname = sourcePath('test.dart'); +- String text = r''' +-int foo +-int bar; +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- try { +- await sendEditSortMembers(pathname); +- } on ServerErrorMessage catch (message) { +- expect(message.error['code'], 'SORT_MEMBERS_PARSE_ERRORS'); +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/edit/test_all.dart b/pkg/analysis_server/test/integration/edit/test_all.dart +deleted file mode 100644 +index 81aa1219c35..00000000000 +--- a/pkg/analysis_server/test/integration/edit/test_all.dart ++++ /dev/null +@@ -1,38 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'format_test.dart' as format_test; +-import 'get_assists_test.dart' as get_assists_test; +-import 'get_available_refactorings_test.dart' +- as get_available_refactorings_test; +-import 'get_fixes_test.dart' as get_fixes_test; +-import 'get_postfix_completion_test.dart' as get_postfix_completion_test; +-import 'get_refactoring_test.dart' as get_refactoring_test; +-import 'get_statement_completion_test.dart' as get_statement_completion_test; +-import 'import_elements_test.dart' as import_elements_test; +-import 'is_postfix_completion_applicable_test.dart' +- as is_postfix_completion_applicable_test; +-import 'list_postfix_completion_templates_test.dart' +- as list_postfix_completion_templates_test; +-import 'organize_directives_test.dart' as organize_directives_test; +-import 'sort_members_test.dart' as sort_members_test; +- +-main() { +- defineReflectiveSuite(() { +- format_test.main(); +- get_assists_test.main(); +- get_available_refactorings_test.main(); +- get_fixes_test.main(); +- get_refactoring_test.main(); +- get_postfix_completion_test.main(); +- get_statement_completion_test.main(); +- import_elements_test.main(); +- is_postfix_completion_applicable_test.main(); +- list_postfix_completion_templates_test.main(); +- organize_directives_test.main(); +- sort_members_test.main(); +- }, name: 'edit'); +-} +diff --git a/pkg/analysis_server/test/integration/execution/create_context_test.dart b/pkg/analysis_server/test/integration/execution/create_context_test.dart +deleted file mode 100644 +index 6564810a95c..00000000000 +--- a/pkg/analysis_server/test/integration/execution/create_context_test.dart ++++ /dev/null +@@ -1,24 +0,0 @@ +-// 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 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(CreateContextTest); +- }); +-} +- +-@reflectiveTest +-class CreateContextTest extends AbstractAnalysisServerIntegrationTest { +- test_create() async { +- standardAnalysisSetup(); +- String contextId = +- (await sendExecutionCreateContext(sourceDirectory.path)).id; +- expect(contextId, isNotNull); +- } +-} +diff --git a/pkg/analysis_server/test/integration/execution/delete_context_test.dart b/pkg/analysis_server/test/integration/execution/delete_context_test.dart +deleted file mode 100644 +index c807fa5b4e0..00000000000 +--- a/pkg/analysis_server/test/integration/execution/delete_context_test.dart ++++ /dev/null +@@ -1,43 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(DeleteContextTest); +- }); +-} +- +-@reflectiveTest +-class DeleteContextTest extends AbstractAnalysisServerIntegrationTest { +- test_delete() async { +- String pathname = sourcePath('lib/main.dart'); +- writeFile(pathname, '// dummy'); +- writeFile(sourcePath('.packages'), 'foo:lib/'); +- standardAnalysisSetup(); +- +- String contextId = +- (await sendExecutionCreateContext(sourceDirectory.path)).id; +- +- ExecutionMapUriResult result = +- await sendExecutionMapUri(contextId, uri: 'package:foo/main.dart'); +- expect(result.file, pathname); +- +- expect(await sendExecutionDeleteContext(contextId), isNull); +- +- // After the delete, expect this to fail. +- try { +- result = +- await sendExecutionMapUri(contextId, uri: 'package:foo/main.dart'); +- fail('expected exception after context delete'); +- } on ServerErrorMessage catch (message) { +- expect(message.error['code'], 'INVALID_PARAMETER'); +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/execution/map_uri_test.dart b/pkg/analysis_server/test/integration/execution/map_uri_test.dart +deleted file mode 100644 +index f5abbc0106c..00000000000 +--- a/pkg/analysis_server/test/integration/execution/map_uri_test.dart ++++ /dev/null +@@ -1,40 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(MapUriTest); +- }); +-} +- +-@reflectiveTest +-class MapUriTest extends AbstractAnalysisServerIntegrationTest { +- test_mapUri() async { +- String pathname = sourcePath('lib/main.dart'); +- writeFile(pathname, '// dummy'); +- writeFile(sourcePath('.packages'), 'foo:lib/'); +- standardAnalysisSetup(); +- +- String contextId = +- (await sendExecutionCreateContext(sourceDirectory.path))?.id; +- +- { +- ExecutionMapUriResult result = +- await sendExecutionMapUri(contextId, uri: 'package:foo/main.dart'); +- expect(result.file, pathname); +- } +- +- { +- ExecutionMapUriResult result = +- await sendExecutionMapUri(contextId, file: pathname); +- expect(result.uri, 'package:foo/main.dart'); +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart b/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart +deleted file mode 100644 +index 441093b35f3..00000000000 +--- a/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart ++++ /dev/null +@@ -1,23 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetSubscriptionsTest); +- }); +-} +- +-@reflectiveTest +-class SetSubscriptionsTest extends AbstractAnalysisServerIntegrationTest { +- test_subscribe() async { +- standardAnalysisSetup(); +- // ignore: deprecated_member_use +- await sendExecutionSetSubscriptions([ExecutionService.LAUNCH_DATA]); +- } +-} +diff --git a/pkg/analysis_server/test/integration/execution/test_all.dart b/pkg/analysis_server/test/integration/execution/test_all.dart +deleted file mode 100644 +index 6da630db1a0..00000000000 +--- a/pkg/analysis_server/test/integration/execution/test_all.dart ++++ /dev/null +@@ -1,19 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'create_context_test.dart' as create_context_test; +-import 'delete_context_test.dart' as delete_context_test; +-import 'map_uri_test.dart' as map_uri_test; +-import 'set_subscriptions_test.dart' as set_subscription_test; +- +-main() { +- defineReflectiveSuite(() { +- create_context_test.main(); +- delete_context_test.main(); +- map_uri_test.main(); +- set_subscription_test.main(); +- }, name: 'execution'); +-} +diff --git a/pkg/analysis_server/test/integration/kythe/get_kythe_entries_test.dart b/pkg/analysis_server/test/integration/kythe/get_kythe_entries_test.dart +deleted file mode 100644 +index ccd3c49572c..00000000000 +--- a/pkg/analysis_server/test/integration/kythe/get_kythe_entries_test.dart ++++ /dev/null +@@ -1,39 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetKytheEntriesTest); +- }); +-} +- +-@reflectiveTest +-class GetKytheEntriesTest extends AbstractAnalysisServerIntegrationTest { +- test_getKytheEntries() async { +- writeFile(sourcePath('WORKSPACE'), ''); +- String pathname = sourcePath('pkg/test.dart'); +- String text = r''' +-class Foo {} +- +-class Bar { +- Foo foo; +-} +-'''; +- writeFile(pathname, text); +- standardAnalysisSetup(); +- +- await analysisFinished; +- +- KytheGetKytheEntriesResult result = +- await sendKytheGetKytheEntries(pathname); +- expect(result.entries, isNotEmpty); +- expect(result.files, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/integration/kythe/test_all.dart b/pkg/analysis_server/test/integration/kythe/test_all.dart +deleted file mode 100644 +index d65cff4a1df..00000000000 +--- a/pkg/analysis_server/test/integration/kythe/test_all.dart ++++ /dev/null +@@ -1,13 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'get_kythe_entries_test.dart' as get_kythe_entries_test; +- +-main() { +- defineReflectiveSuite(() { +- get_kythe_entries_test.main(); +- }, name: 'kythe'); +-} +diff --git a/pkg/analysis_server/test/integration/search/find_element_references_test.dart b/pkg/analysis_server/test/integration/search/find_element_references_test.dart +deleted file mode 100644 +index 10bfbfa6af1..00000000000 +--- a/pkg/analysis_server/test/integration/search/find_element_references_test.dart ++++ /dev/null +@@ -1,72 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FindElementReferencesTest); +- }); +-} +- +-@reflectiveTest +-class FindElementReferencesTest extends AbstractAnalysisServerIntegrationTest { +- String pathname; +- +- test_badTarget() async { +- String text = r''' +-main() { +- if /* target */ (true) { +- print('Hello'); +- } +-} +-'''; +- +- pathname = sourcePath('foo.dart'); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- List results = await _findElementReferences(text); +- expect(results, isNull); +- } +- +- test_findReferences() async { +- String text = r''' +-main() { +- print /* target */ ('Hello'); +-} +-'''; +- +- pathname = sourcePath('foo.dart'); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- List results = await _findElementReferences(text); +- expect(results, hasLength(1)); +- SearchResult result = results.first; +- expect(result.location.file, pathname); +- expect(result.isPotential, isFalse); +- expect(result.kind.name, SearchResultKind.INVOCATION.name); +- expect(result.path.first.name, 'main'); +- } +- +- Future> _findElementReferences(String text) async { +- int offset = text.indexOf(' /* target */') - 1; +- SearchFindElementReferencesResult result = +- await sendSearchFindElementReferences(pathname, offset, false); +- if (result.id == null) return null; +- SearchResultsParams searchParams = await onSearchResults.first; +- expect(searchParams.id, result.id); +- expect(searchParams.isLast, isTrue); +- return searchParams.results; +- } +-} +diff --git a/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart b/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart +deleted file mode 100644 +index 81148c09ccc..00000000000 +--- a/pkg/analysis_server/test/integration/search/find_member_declarations_test.dart ++++ /dev/null +@@ -1,51 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FindMemberDeclarationsTest); +- }); +-} +- +-@reflectiveTest +-class FindMemberDeclarationsTest extends AbstractAnalysisServerIntegrationTest { +- String pathname; +- +- test_findMemberDeclarations() async { +- String text = r''' +-String qux() => 'qux'; +- +-class Foo { +- void bar() { }; +- int baz() => 0; +-} +-'''; +- +- pathname = sourcePath('foo.dart'); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- SearchFindMemberDeclarationsResult declarationsResult = +- await sendSearchFindMemberDeclarations('bar'); +- expect(declarationsResult.id, isNotNull); +- +- SearchResultsParams searchParams = await onSearchResults.first; +- expect(searchParams.id, declarationsResult.id); +- expect(searchParams.isLast, isTrue); +- expect(searchParams.results, isNotEmpty); +- +- SearchResult result = searchParams.results.first; +- expect(result.location.file, pathname); +- expect(result.isPotential, isFalse); +- expect(result.kind.name, SearchResultKind.DECLARATION.name); +- expect(result.path.first.name, 'bar'); +- } +-} +diff --git a/pkg/analysis_server/test/integration/search/find_member_references_test.dart b/pkg/analysis_server/test/integration/search/find_member_references_test.dart +deleted file mode 100644 +index 36fccbc35e4..00000000000 +--- a/pkg/analysis_server/test/integration/search/find_member_references_test.dart ++++ /dev/null +@@ -1,52 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FindMemberReferencesTest); +- }); +-} +- +-@reflectiveTest +-class FindMemberReferencesTest extends AbstractAnalysisServerIntegrationTest { +- String pathname; +- +- test_findMemberReferences() async { +- String text = r''' +-String qux() => 'qux'; +- +-class Foo { +- //int bar() => 1; +- baz() => bar() * bar(); +-} +-'''; +- +- pathname = sourcePath('foo.dart'); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- SearchFindMemberReferencesResult referencesResult = +- await sendSearchFindMemberReferences('bar'); +- expect(referencesResult.id, isNotNull); +- +- SearchResultsParams searchParams = await onSearchResults.first; +- expect(searchParams.id, referencesResult.id); +- expect(searchParams.isLast, isTrue); +- expect(searchParams.results, isNotEmpty); +- expect(searchParams.results, hasLength(2)); +- +- SearchResult result = searchParams.results.first; +- expect(result.location.file, pathname); +- expect(result.isPotential, isTrue); +- expect(result.kind.name, SearchResultKind.INVOCATION.name); +- expect(result.path.first.name, 'baz'); +- } +-} +diff --git a/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart b/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart +deleted file mode 100644 +index 66352f892d2..00000000000 +--- a/pkg/analysis_server/test/integration/search/find_top_level_declarations_test.dart ++++ /dev/null +@@ -1,56 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FindTopLevelDeclarationsTest); +- }); +-} +- +-@reflectiveTest +-class FindTopLevelDeclarationsTest +- extends AbstractAnalysisServerIntegrationTest { +- String pathname; +- +- test_findTopLevelDeclarations() async { +- String text = r''' +-String qux() => 'qux'; +- +-class Foo { +- void bar() { }; +- int baz() => 0; +-} +-'''; +- +- pathname = sourcePath('foo.dart'); +- writeFile(pathname, text); +- standardAnalysisSetup(); +- await analysisFinished; +- +- SearchFindTopLevelDeclarationsResult declarationsResult = +- await sendSearchFindTopLevelDeclarations(r'qu.*'); +- expect(declarationsResult.id, isNotNull); +- +- SearchResultsParams searchParams = await onSearchResults.first; +- expect(searchParams.id, declarationsResult.id); +- expect(searchParams.isLast, isTrue); +- expect(searchParams.results, isNotEmpty); +- +- for (SearchResult result in searchParams.results) { +- if (result.location.file == pathname) { +- expect(result.isPotential, isFalse); +- expect(result.kind.name, SearchResultKind.DECLARATION.name); +- expect(result.path.first.name, 'qux'); +- return; +- } +- } +- fail('No result for $pathname'); +- } +-} +diff --git a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart +deleted file mode 100644 +index 0919aa22957..00000000000 +--- a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart ++++ /dev/null +@@ -1,275 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetTypeHierarchyTest); +- }); +-} +- +-@reflectiveTest +-class GetTypeHierarchyTest extends AbstractAnalysisServerIntegrationTest { +- /** +- * Pathname of the main file to run tests in. +- */ +- String pathname; +- +- Future getTypeHierarchy_badTarget() { +- String text = r''' +-main() { +- if /* target */ (true) { +- print('Hello'); +- } +-} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results, isNull); +- }); +- } +- +- Future getTypeHierarchy_classElement() { +- String text = r''' +-class Base {} +-class Pivot /* target */ extends Base {} +-class Derived extends Pivot {} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(4)); +- expect(results.nameToIndex['Pivot'], equals(0)); +- void checkElement(String name) { +- // We don't check the full element data structure; just enough to make +- // sure that we're pointing to the correct element. +- Element element = results.items[results.nameToIndex[name]].classElement; +- expect(element.kind, equals(ElementKind.CLASS)); +- expect(element.name, equals(name)); +- if (name != 'Object') { +- expect(element.location.offset, +- equals(text.indexOf('class $name') + 'class '.length)); +- } +- } +- +- checkElement('Object'); +- checkElement('Base'); +- checkElement('Pivot'); +- checkElement('Derived'); +- }); +- } +- +- Future getTypeHierarchy_displayName() { +- String text = r''' +-class Base {} +-class Pivot /* target */ extends Base {} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(3)); +- expect(results.getItem('Object').displayName, isNull); +- expect(results.getItem('Base').displayName, equals('Base')); +- expect(results.getItem('Pivot').displayName, isNull); +- }); +- } +- +- Future getTypeHierarchy_functionTarget() { +- String text = r''' +-main /* target */ () { +-} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results, isNull); +- }); +- } +- +- Future getTypeHierarchy_interfaces() { +- String text = r''' +-class Interface1 {} +-class Interface2 {} +-class Pivot /* target */ implements Interface1, Interface2 {} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(4)); +- expect(results.pivot.interfaces, hasLength(2)); +- expect(results.pivot.interfaces, +- contains(results.nameToIndex['Interface1'])); +- expect(results.pivot.interfaces, +- contains(results.nameToIndex['Interface2'])); +- expect(results.getItem('Object').interfaces, isEmpty); +- expect(results.getItem('Interface1').interfaces, isEmpty); +- expect(results.getItem('Interface2').interfaces, isEmpty); +- }); +- } +- +- Future getTypeHierarchy_memberElement() { +- String text = r''' +-class Base1 { +- void foo /* base1 */ (); +-} +-class Base2 extends Base1 {} +-class Pivot extends Base2 { +- void foo /* target */ (); +-} +-class Derived1 extends Pivot {} +-class Derived2 extends Derived1 { +- void foo /* derived2 */ (); +-}'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(6)); +- expect(results.getItem('Object').memberElement, isNull); +- expect(results.getItem('Base1').memberElement.location.offset, +- equals(text.indexOf('foo /* base1 */'))); +- expect(results.getItem('Base2').memberElement, isNull); +- expect(results.getItem('Pivot').memberElement.location.offset, +- equals(text.indexOf('foo /* target */'))); +- expect(results.getItem('Derived1').memberElement, isNull); +- expect(results.getItem('Derived2').memberElement.location.offset, +- equals(text.indexOf('foo /* derived2 */'))); +- }); +- } +- +- Future getTypeHierarchy_mixins() { +- String text = r''' +-class Base {} +-class Mixin1 {} +-class Mixin2 {} +-class Pivot /* target */ extends Base with Mixin1, Mixin2 {} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(5)); +- expect(results.pivot.mixins, hasLength(2)); +- expect(results.pivot.mixins, contains(results.nameToIndex['Mixin1'])); +- expect(results.pivot.mixins, contains(results.nameToIndex['Mixin2'])); +- expect(results.getItem('Object').mixins, isEmpty); +- expect(results.getItem('Base').mixins, isEmpty); +- expect(results.getItem('Mixin1').mixins, isEmpty); +- expect(results.getItem('Mixin2').mixins, isEmpty); +- }); +- } +- +- Future getTypeHierarchy_subclasses() { +- String text = r''' +-class Base {} +-class Pivot /* target */ extends Base {} +-class Sub1 extends Pivot {} +-class Sub2 extends Pivot {} +-class Sub2a extends Sub2 {} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(6)); +- expect(results.pivot.subclasses, hasLength(2)); +- expect(results.pivot.subclasses, contains(results.nameToIndex['Sub1'])); +- expect(results.pivot.subclasses, contains(results.nameToIndex['Sub2'])); +- expect(results.getItem('Object').subclasses, isEmpty); +- expect(results.getItem('Base').subclasses, isEmpty); +- expect(results.getItem('Sub1').subclasses, isEmpty); +- expect(results.getItem('Sub2').subclasses, +- equals([results.nameToIndex['Sub2a']])); +- expect(results.getItem('Sub2a').subclasses, isEmpty); +- }); +- } +- +- Future getTypeHierarchy_superclass() { +- String text = r''' +-class Base1 {} +-class Base2 extends Base1 {} +-class Pivot /* target */ extends Base2 {} +-'''; +- return typeHierarchyTest(text).then((HierarchyResults results) { +- expect(results.items, hasLength(4)); +- expect(results.getItem('Object').superclass, isNull); +- expect(results.getItem('Base1').superclass, +- equals(results.nameToIndex['Object'])); +- expect(results.getItem('Base2').superclass, +- equals(results.nameToIndex['Base1'])); +- expect(results.getItem('Pivot').superclass, +- equals(results.nameToIndex['Base2'])); +- }); +- } +- +- test_getTypeHierarchy() { +- pathname = sourcePath('test.dart'); +- // Write a dummy file which will be overridden by tests using +- // [sendAnalysisUpdateContent]. +- writeFile(pathname, '// dummy'); +- standardAnalysisSetup(); +- +- // Run all the getTypeHierarchy tests at once so that the server can take +- // advantage of incremental analysis and the test doesn't time out. +- List tests = [ +- getTypeHierarchy_classElement, +- getTypeHierarchy_displayName, +- getTypeHierarchy_memberElement, +- getTypeHierarchy_superclass, +- getTypeHierarchy_interfaces, +- getTypeHierarchy_mixins, +- getTypeHierarchy_subclasses, +- getTypeHierarchy_badTarget, +- getTypeHierarchy_functionTarget +- ]; +- return Future.forEach(tests, (test) => test()); +- } +- +- Future typeHierarchyTest(String text) async { +- int offset = text.indexOf(' /* target */') - 1; +- sendAnalysisUpdateContent({pathname: new AddContentOverlay(text)}); +- await analysisFinished; +- var result = await sendSearchGetTypeHierarchy(pathname, offset); +- if (result.hierarchyItems == null) { +- return null; +- } else { +- return new HierarchyResults(result.hierarchyItems); +- } +- } +-} +- +-/** +- * Results of a getTypeHierarchy request, processed for easier testing. +- */ +-class HierarchyResults { +- /** +- * The list of hierarchy items from the result. +- */ +- List items; +- +- /** +- * The first hierarchy item from the result, which represents the pivot +- * class. +- */ +- TypeHierarchyItem pivot; +- +- /** +- * A map from element name to item index. +- */ +- Map nameToIndex; +- +- /** +- * Create a [HierarchyResults] object based on the result from a +- * getTypeHierarchy request. +- */ +- HierarchyResults(this.items) { +- pivot = items[0]; +- nameToIndex = {}; +- for (int i = 0; i < items.length; i++) { +- nameToIndex[items[i].classElement.name] = i; +- } +- } +- +- /** +- * Get an item by class name. +- */ +- TypeHierarchyItem getItem(String name) { +- if (nameToIndex.containsKey(name)) { +- return items[nameToIndex[name]]; +- } else { +- fail('Class $name not found in hierarchy results'); +- return null; +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/search/test_all.dart b/pkg/analysis_server/test/integration/search/test_all.dart +deleted file mode 100644 +index bf7e7a4a296..00000000000 +--- a/pkg/analysis_server/test/integration/search/test_all.dart ++++ /dev/null +@@ -1,25 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'find_element_references_test.dart' as find_element_references_test; +-import 'find_member_declarations_test.dart' as find_member_declarations_test; +-import 'find_member_references_test.dart' as find_member_references_test; +-import 'find_top_level_declarations_test.dart' +- as find_top_level_declarations_test; +-import 'get_type_hierarchy_test.dart' as get_type_hierarchy_test; +- +-/** +- * Utility for manually running all integration tests. +- */ +-main() { +- defineReflectiveSuite(() { +- find_element_references_test.main(); +- find_member_declarations_test.main(); +- find_member_references_test.main(); +- find_top_level_declarations_test.main(); +- get_type_hierarchy_test.main(); +- }, name: 'search'); +-} +diff --git a/pkg/analysis_server/test/integration/server/get_version_test.dart b/pkg/analysis_server/test/integration/server/get_version_test.dart +deleted file mode 100644 +index c3dc407c553..00000000000 +--- a/pkg/analysis_server/test/integration/server/get_version_test.dart ++++ /dev/null +@@ -1,20 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetVersionTest); +- }); +-} +- +-@reflectiveTest +-class GetVersionTest extends AbstractAnalysisServerIntegrationTest { +- test_getVersion() { +- return sendServerGetVersion(); +- } +-} +diff --git a/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart b/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart +deleted file mode 100644 +index c95e046a81a..00000000000 +--- a/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart ++++ /dev/null +@@ -1,30 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetSubscriptionsInvalidTest); +- }); +-} +- +-@reflectiveTest +-class SetSubscriptionsInvalidTest +- extends AbstractAnalysisServerIntegrationTest { +- test_setSubscriptions_invalidService() { +- // TODO(paulberry): verify that if an invalid service is specified, the +- // current subscriptions are unchanged. +- return server.send("server.setSubscriptions", { +- 'subscriptions': ['bogus'] +- }).then((_) { +- fail('setSubscriptions should have produced an error'); +- }, onError: (error) { +- // The expected error occurred. +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart b/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart +deleted file mode 100644 +index 9cfd81caa40..00000000000 +--- a/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart ++++ /dev/null +@@ -1,64 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SetSubscriptionsTest); +- }); +-} +- +-@reflectiveTest +-class SetSubscriptionsTest extends AbstractAnalysisServerIntegrationTest { +- @failingTest +- test_setSubscriptions() { +- // This test times out on the bots and has been disabled to keep them green. +- // We need to discover the cause and re-enable it. +- +- fail( +- 'This test times out on the bots and has been disabled to keep them green.' +- 'We need to discover the cause and re-enable it.'); +- +- bool statusReceived = false; +- Completer analysisBegun = new Completer(); +- onServerStatus.listen((_) { +- statusReceived = true; +- }); +- onAnalysisErrors.listen((_) { +- if (!analysisBegun.isCompleted) { +- analysisBegun.complete(); +- } +- }); +- return sendServerSetSubscriptions([]).then((_) { +- String pathname = sourcePath('test.dart'); +- writeFile(pathname, ''' +-main() { +- var x; +-}'''); +- standardAnalysisSetup(subscribeStatus: false); +- // Analysis should begin, but no server.status notification should be +- // received. +- return analysisBegun.future.then((_) { +- expect(statusReceived, isFalse); +- return sendServerSetSubscriptions([ServerService.STATUS]).then((_) { +- // Tickle test.dart just in case analysis has already completed. +- writeFile(pathname, ''' +-main() { +- var y; +-}'''); +- // Analysis should eventually complete, and we should be notified +- // about it. +- return analysisFinished; +- }); +- }); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/server/shutdown_test.dart b/pkg/analysis_server/test/integration/server/shutdown_test.dart +deleted file mode 100644 +index 8478d48020b..00000000000 +--- a/pkg/analysis_server/test/integration/server/shutdown_test.dart ++++ /dev/null +@@ -1,31 +0,0 @@ +-// Copyright (c) 2014, 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 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ShutdownTest); +- }); +-} +- +-@reflectiveTest +-class ShutdownTest extends AbstractAnalysisServerIntegrationTest { +- test_shutdown() { +- return sendServerShutdown().then((_) { +- return new Future.delayed(new Duration(seconds: 1)).then((_) { +- sendServerGetVersion().then((_) { +- fail('Server still alive after server.shutdown'); +- }); +- // Give the server time to respond before terminating the test. +- return new Future.delayed(new Duration(seconds: 1)); +- }); +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/server/status_test.dart b/pkg/analysis_server/test/integration/server/status_test.dart +deleted file mode 100644 +index 72163c354ab..00000000000 +--- a/pkg/analysis_server/test/integration/server/status_test.dart ++++ /dev/null +@@ -1,50 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../support/integration_tests.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(StatusTest); +- }); +-} +- +-@reflectiveTest +-class StatusTest extends AbstractAnalysisServerIntegrationTest { +- test_status() { +- // After we kick off analysis, we should get one server.status message with +- // analyzing=true, and another server.status message after that with +- // analyzing=false. +- Completer analysisBegun = new Completer(); +- Completer analysisFinished = new Completer(); +- onServerStatus.listen((ServerStatusParams params) { +- if (params.analysis != null) { +- if (params.analysis.isAnalyzing) { +- expect(analysisBegun.isCompleted, isFalse); +- analysisBegun.complete(); +- } else { +- expect(analysisFinished.isCompleted, isFalse); +- analysisFinished.complete(); +- } +- } +- }); +- writeFile(sourcePath('test.dart'), ''' +-main() { +- var x; +-}'''); +- standardAnalysisSetup(); +- expect(analysisBegun.isCompleted, isFalse); +- expect(analysisFinished.isCompleted, isFalse); +- return analysisBegun.future.then((_) { +- expect(analysisFinished.isCompleted, isFalse); +- return analysisFinished.future; +- }); +- } +-} +diff --git a/pkg/analysis_server/test/integration/server/test_all.dart b/pkg/analysis_server/test/integration/server/test_all.dart +deleted file mode 100644 +index 6ab8ac95174..00000000000 +--- a/pkg/analysis_server/test/integration/server/test_all.dart ++++ /dev/null +@@ -1,25 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'get_version_test.dart' as get_version_test; +-import 'set_subscriptions_invalid_service_test.dart' +- as set_subscriptions_invalid_service_test; +-import 'set_subscriptions_test.dart' as set_subscriptions_test; +-import 'shutdown_test.dart' as shutdown_test; +-import 'status_test.dart' as status_test; +- +-/** +- * Utility for manually running all integration tests. +- */ +-main() { +- defineReflectiveSuite(() { +- get_version_test.main(); +- set_subscriptions_test.main(); +- set_subscriptions_invalid_service_test.main(); +- shutdown_test.main(); +- status_test.main(); +- }, name: 'server'); +-} +diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart +deleted file mode 100644 +index 2580f2cfc85..00000000000 +--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart ++++ /dev/null +@@ -1,2240 +0,0 @@ +-// 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. +-// +-// This file has been automatically generated. Please do not edit it manually. +-// To regenerate the file, use the script +-// "pkg/analysis_server/tool/spec/generate_files". +- +-/** +- * Convenience methods for running integration tests +- */ +-import 'dart:async'; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart'; +-import 'package:test/test.dart'; +- +-import 'integration_tests.dart'; +-import 'protocol_matchers.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * Convenience methods for running integration tests +- */ +-abstract class IntegrationTestMixin { +- Server get server; +- +- /** +- * Return the version number of the analysis server. +- * +- * Returns +- * +- * version: String +- * +- * The version number of the analysis server. +- */ +- Future sendServerGetVersion() async { +- var result = await server.send("server.getVersion", null); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new ServerGetVersionResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Cleanly shutdown the analysis server. Requests that are received after +- * this request will not be processed. Requests that were received before +- * this request, but for which a response has not yet been sent, will not be +- * responded to. No further responses or notifications will be sent after the +- * response to this request has been sent. +- */ +- Future sendServerShutdown() async { +- var result = await server.send("server.shutdown", null); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Subscribe for services. All previous subscriptions are replaced by the +- * given set of services. +- * +- * It is an error if any of the elements in the list are not valid services. +- * If there is an error, then the current subscriptions will remain +- * unchanged. +- * +- * Parameters +- * +- * subscriptions: List +- * +- * A list of the services being subscribed to. +- */ +- Future sendServerSetSubscriptions(List subscriptions) async { +- var params = new ServerSetSubscriptionsParams(subscriptions).toJson(); +- var result = await server.send("server.setSubscriptions", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Reports that the server is running. This notification is issued once after +- * the server has started running but before any requests are processed to +- * let the client know that it started correctly. +- * +- * It is not possible to subscribe to or unsubscribe from this notification. +- * +- * Parameters +- * +- * version: String +- * +- * The version number of the analysis server. +- * +- * pid: int +- * +- * The process id of the analysis server process. +- * +- * sessionId: String (optional) +- * +- * The session id for this session. +- */ +- Stream onServerConnected; +- +- /** +- * Stream controller for [onServerConnected]. +- */ +- StreamController _onServerConnected; +- +- /** +- * Reports that an unexpected error has occurred while executing the server. +- * This notification is not used for problems with specific requests (which +- * are returned as part of the response) but is used for exceptions that +- * occur while performing other tasks, such as analysis or preparing +- * notifications. +- * +- * It is not possible to subscribe to or unsubscribe from this notification. +- * +- * Parameters +- * +- * isFatal: bool +- * +- * True if the error is a fatal error, meaning that the server will +- * shutdown automatically after sending this notification. +- * +- * message: String +- * +- * The error message indicating what kind of error was encountered. +- * +- * stackTrace: String +- * +- * The stack trace associated with the generation of the error, used for +- * debugging the server. +- */ +- Stream onServerError; +- +- /** +- * Stream controller for [onServerError]. +- */ +- StreamController _onServerError; +- +- /** +- * Reports the current status of the server. Parameters are omitted if there +- * has been no change in the status represented by that parameter. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "STATUS" in the list of services passed in a +- * server.setSubscriptions request. +- * +- * Parameters +- * +- * analysis: AnalysisStatus (optional) +- * +- * The current status of analysis, including whether analysis is being +- * performed and if so what is being analyzed. +- * +- * pub: PubStatus (optional) +- * +- * The current status of pub execution, indicating whether we are currently +- * running pub. +- */ +- Stream onServerStatus; +- +- /** +- * Stream controller for [onServerStatus]. +- */ +- StreamController _onServerStatus; +- +- /** +- * Return the errors associated with the given file. If the errors for the +- * given file have not yet been computed, or the most recently computed +- * errors for the given file are out of date, then the response for this +- * request will be delayed until they have been computed. If some or all of +- * the errors for the file cannot be computed, then the subset of the errors +- * that can be computed will be returned and the response will contain an +- * error to indicate why the errors could not be computed. If the content of +- * the file changes after this request was received but before a response +- * could be sent, then an error of type CONTENT_MODIFIED will be generated. +- * +- * This request is intended to be used by clients that cannot asynchronously +- * apply updated error information. Clients that can apply error information +- * as it becomes available should use the information provided by the +- * 'analysis.errors' notification. +- * +- * If a request is made for a file which does not exist, or which is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified to analysis.setAnalysisRoots), an error of type +- * GET_ERRORS_INVALID_FILE will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file for which errors are being requested. +- * +- * Returns +- * +- * errors: List +- * +- * The errors associated with the file. +- */ +- Future sendAnalysisGetErrors(String file) async { +- var params = new AnalysisGetErrorsParams(file).toJson(); +- var result = await server.send("analysis.getErrors", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetErrorsResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Return the hover information associate with the given location. If some or +- * all of the hover information is not available at the time this request is +- * processed the information will be omitted from the response. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which hover information is being requested. +- * +- * offset: int +- * +- * The offset for which hover information is being requested. +- * +- * Returns +- * +- * hovers: List +- * +- * The hover information associated with the location. The list will be +- * empty if no information could be determined for the location. The list +- * can contain multiple items if the file is being analyzed in multiple +- * contexts in conflicting ways (such as a part that is included in +- * multiple libraries). +- */ +- Future sendAnalysisGetHover( +- String file, int offset) async { +- var params = new AnalysisGetHoverParams(file, offset).toJson(); +- var result = await server.send("analysis.getHover", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetHoverResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Return a description of all of the elements referenced in a given region +- * of a given file that come from imported libraries. +- * +- * If a request is made for a file that does not exist, or that is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified via analysis.setAnalysisRoots), an error of type +- * GET_IMPORTED_ELEMENTS_INVALID_FILE will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which import information is being requested. +- * +- * offset: int +- * +- * The offset of the region for which import information is being +- * requested. +- * +- * length: int +- * +- * The length of the region for which import information is being +- * requested. +- * +- * Returns +- * +- * elements: List +- * +- * The information about the elements that are referenced in the specified +- * region of the specified file that come from imported libraries. +- */ +- Future sendAnalysisGetImportedElements( +- String file, int offset, int length) async { +- var params = +- new AnalysisGetImportedElementsParams(file, offset, length).toJson(); +- var result = await server.send("analysis.getImportedElements", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetImportedElementsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return library dependency information for use in client-side indexing and +- * package URI resolution. +- * +- * Clients that are only using the libraries field should consider using the +- * analyzedFiles notification instead. +- * +- * Returns +- * +- * libraries: List +- * +- * A list of the paths of library elements referenced by files in existing +- * analysis roots. +- * +- * packageMap: Map>> +- * +- * A mapping from context source roots to package maps which map package +- * names to source directories for use in client-side package URI +- * resolution. +- */ +- Future +- sendAnalysisGetLibraryDependencies() async { +- var result = await server.send("analysis.getLibraryDependencies", null); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetLibraryDependenciesResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return the navigation information associated with the given region of the +- * given file. If the navigation information for the given file has not yet +- * been computed, or the most recently computed navigation information for +- * the given file is out of date, then the response for this request will be +- * delayed until it has been computed. If the content of the file changes +- * after this request was received but before a response could be sent, then +- * an error of type CONTENT_MODIFIED will be generated. +- * +- * If a navigation region overlaps (but extends either before or after) the +- * given region of the file it will be included in the result. This means +- * that it is theoretically possible to get the same navigation region in +- * response to multiple requests. Clients can avoid this by always choosing a +- * region that starts at the beginning of a line and ends at the end of a +- * (possibly different) line in the file. +- * +- * If a request is made for a file which does not exist, or which is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified to analysis.setAnalysisRoots), an error of type +- * GET_NAVIGATION_INVALID_FILE will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which navigation information is being requested. +- * +- * offset: int +- * +- * The offset of the region for which navigation information is being +- * requested. +- * +- * length: int +- * +- * The length of the region for which navigation information is being +- * requested. +- * +- * Returns +- * +- * files: List +- * +- * A list of the paths of files that are referenced by the navigation +- * targets. +- * +- * targets: List +- * +- * A list of the navigation targets that are referenced by the navigation +- * regions. +- * +- * regions: List +- * +- * A list of the navigation regions within the requested region of the +- * file. +- */ +- Future sendAnalysisGetNavigation( +- String file, int offset, int length) async { +- var params = new AnalysisGetNavigationParams(file, offset, length).toJson(); +- var result = await server.send("analysis.getNavigation", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetNavigationResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Return the transitive closure of reachable sources for a given file. +- * +- * If a request is made for a file which does not exist, or which is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified to analysis.setAnalysisRoots), an error of type +- * GET_REACHABLE_SOURCES_INVALID_FILE will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file for which reachable source information is being requested. +- * +- * Returns +- * +- * sources: Map> +- * +- * A mapping from source URIs to directly reachable source URIs. For +- * example, a file "foo.dart" that imports "bar.dart" would have the +- * corresponding mapping { "file:///foo.dart" : ["file:///bar.dart"] }. If +- * "bar.dart" has further imports (or exports) there will be a mapping from +- * the URI "file:///bar.dart" to them. To check if a specific URI is +- * reachable from a given file, clients can check for its presence in the +- * resulting key set. +- */ +- Future sendAnalysisGetReachableSources( +- String file) async { +- var params = new AnalysisGetReachableSourcesParams(file).toJson(); +- var result = await server.send("analysis.getReachableSources", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetReachableSourcesResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Force the re-analysis of everything contained in the specified analysis +- * roots. This will cause all previously computed analysis results to be +- * discarded and recomputed, and will cause all subscribed notifications to +- * be re-sent. +- * +- * If no analysis roots are provided, then all current analysis roots will be +- * re-analyzed. If an empty list of analysis roots is provided, then nothing +- * will be re-analyzed. If the list contains one or more paths that are not +- * currently analysis roots, then an error of type INVALID_ANALYSIS_ROOT will +- * be generated. +- * +- * Parameters +- * +- * roots: List (optional) +- * +- * A list of the analysis roots that are to be re-analyzed. +- */ +- Future sendAnalysisReanalyze({List roots}) async { +- var params = new AnalysisReanalyzeParams(roots: roots).toJson(); +- var result = await server.send("analysis.reanalyze", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Sets the root paths used to determine which files to analyze. The set of +- * files to be analyzed are all of the files in one of the root paths that +- * are not either explicitly or implicitly excluded. A file is explicitly +- * excluded if it is in one of the excluded paths. A file is implicitly +- * excluded if it is in a subdirectory of one of the root paths where the +- * name of the subdirectory starts with a period (that is, a hidden +- * directory). +- * +- * Note that this request determines the set of requested analysis roots. The +- * actual set of analysis roots at any given time is the intersection of this +- * set with the set of files and directories actually present on the +- * filesystem. When the filesystem changes, the actual set of analysis roots +- * is automatically updated, but the set of requested analysis roots is +- * unchanged. This means that if the client sets an analysis root before the +- * root becomes visible to server in the filesystem, there is no error; once +- * the server sees the root in the filesystem it will start analyzing it. +- * Similarly, server will stop analyzing files that are removed from the file +- * system but they will remain in the set of requested roots. +- * +- * If an included path represents a file, then server will look in the +- * directory containing the file for a pubspec.yaml file. If none is found, +- * then the parents of the directory will be searched until such a file is +- * found or the root of the file system is reached. If such a file is found, +- * it will be used to resolve package: URI’s within the file. +- * +- * Parameters +- * +- * included: List +- * +- * A list of the files and directories that should be analyzed. +- * +- * excluded: List +- * +- * A list of the files and directories within the included directories that +- * should not be analyzed. +- * +- * packageRoots: Map (optional) +- * +- * A mapping from source directories to package roots that should override +- * the normal package: URI resolution mechanism. +- * +- * If a package root is a directory, then the analyzer will behave as +- * though the associated source directory in the map contains a special +- * pubspec.yaml file which resolves any package: URI to the corresponding +- * path within that package root directory. The effect is the same as +- * specifying the package root directory as a "--package_root" parameter to +- * the Dart VM when executing any Dart file inside the source directory. +- * +- * If a package root is a file, then the analyzer will behave as though +- * that file is a ".packages" file in the source directory. The effect is +- * the same as specifying the file as a "--packages" parameter to the Dart +- * VM when executing any Dart file inside the source directory. +- * +- * Files in any directories that are not overridden by this mapping have +- * their package: URI's resolved using the normal pubspec.yaml mechanism. +- * If this field is absent, or the empty map is specified, that indicates +- * that the normal pubspec.yaml mechanism should always be used. +- */ +- Future sendAnalysisSetAnalysisRoots( +- List included, List excluded, +- {Map packageRoots}) async { +- var params = new AnalysisSetAnalysisRootsParams(included, excluded, +- packageRoots: packageRoots) +- .toJson(); +- var result = await server.send("analysis.setAnalysisRoots", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Subscribe for general services (that is, services that are not specific to +- * individual files). All previous subscriptions are replaced by the given +- * set of services. +- * +- * It is an error if any of the elements in the list are not valid services. +- * If there is an error, then the current subscriptions will remain +- * unchanged. +- * +- * Parameters +- * +- * subscriptions: List +- * +- * A list of the services being subscribed to. +- */ +- Future sendAnalysisSetGeneralSubscriptions( +- List subscriptions) async { +- var params = +- new AnalysisSetGeneralSubscriptionsParams(subscriptions).toJson(); +- var result = await server.send("analysis.setGeneralSubscriptions", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Set the priority files to the files in the given list. A priority file is +- * a file that is given priority when scheduling which analysis work to do +- * first. The list typically contains those files that are visible to the +- * user and those for which analysis results will have the biggest impact on +- * the user experience. The order of the files within the list is +- * significant: the first file will be given higher priority than the second, +- * the second higher priority than the third, and so on. +- * +- * Note that this request determines the set of requested priority files. The +- * actual set of priority files is the intersection of the requested set of +- * priority files with the set of files currently subject to analysis. (See +- * analysis.setSubscriptions for a description of files that are subject to +- * analysis.) +- * +- * If a requested priority file is a directory it is ignored, but remains in +- * the set of requested priority files so that if it later becomes a file it +- * can be included in the set of actual priority files. +- * +- * Parameters +- * +- * files: List +- * +- * The files that are to be a priority for analysis. +- */ +- Future sendAnalysisSetPriorityFiles(List files) async { +- var params = new AnalysisSetPriorityFilesParams(files).toJson(); +- var result = await server.send("analysis.setPriorityFiles", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Subscribe for services that are specific to individual files. All previous +- * subscriptions are replaced by the current set of subscriptions. If a given +- * service is not included as a key in the map then no files will be +- * subscribed to the service, exactly as if the service had been included in +- * the map with an explicit empty list of files. +- * +- * Note that this request determines the set of requested subscriptions. The +- * actual set of subscriptions at any given time is the intersection of this +- * set with the set of files currently subject to analysis. The files +- * currently subject to analysis are the set of files contained within an +- * actual analysis root but not excluded, plus all of the files transitively +- * reachable from those files via import, export and part directives. (See +- * analysis.setAnalysisRoots for an explanation of how the actual analysis +- * roots are determined.) When the actual analysis roots change, the actual +- * set of subscriptions is automatically updated, but the set of requested +- * subscriptions is unchanged. +- * +- * If a requested subscription is a directory it is ignored, but remains in +- * the set of requested subscriptions so that if it later becomes a file it +- * can be included in the set of actual subscriptions. +- * +- * It is an error if any of the keys in the map are not valid services. If +- * there is an error, then the existing subscriptions will remain unchanged. +- * +- * Parameters +- * +- * subscriptions: Map> +- * +- * A table mapping services to a list of the files being subscribed to the +- * service. +- */ +- Future sendAnalysisSetSubscriptions( +- Map> subscriptions) async { +- var params = new AnalysisSetSubscriptionsParams(subscriptions).toJson(); +- var result = await server.send("analysis.setSubscriptions", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Update the content of one or more files. Files that were previously +- * updated but not included in this update remain unchanged. This effectively +- * represents an overlay of the filesystem. The files whose content is +- * overridden are therefore seen by server as being files with the given +- * content, even if the files do not exist on the filesystem or if the file +- * path represents the path to a directory on the filesystem. +- * +- * Parameters +- * +- * files: Map +- * +- * A table mapping the files whose content has changed to a description of +- * the content change. +- * +- * Returns +- */ +- Future sendAnalysisUpdateContent( +- Map files) async { +- var params = new AnalysisUpdateContentParams(files).toJson(); +- var result = await server.send("analysis.updateContent", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisUpdateContentResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Deprecated: all of the options can be set by users in an analysis options +- * file. +- * +- * Update the options controlling analysis based on the given set of options. +- * Any options that are not included in the analysis options will not be +- * changed. If there are options in the analysis options that are not valid, +- * they will be silently ignored. +- * +- * Parameters +- * +- * options: AnalysisOptions +- * +- * The options that are to be used to control analysis. +- */ +- @deprecated +- Future sendAnalysisUpdateOptions(AnalysisOptions options) async { +- var params = new AnalysisUpdateOptionsParams(options).toJson(); +- var result = await server.send("analysis.updateOptions", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Reports the paths of the files that are being analyzed. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "ANALYZED_FILES" in the list of services passed in +- * an analysis.setGeneralSubscriptions request. +- * +- * Parameters +- * +- * directories: List +- * +- * A list of the paths of the files that are being analyzed. +- */ +- Stream onAnalysisAnalyzedFiles; +- +- /** +- * Stream controller for [onAnalysisAnalyzedFiles]. +- */ +- StreamController _onAnalysisAnalyzedFiles; +- +- /** +- * Reports closing labels relevant to a given file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "CLOSING_LABELS" in the list of services passed in +- * an analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file the closing labels relate to. +- * +- * labels: List +- * +- * Closing labels relevant to the file. Each item represents a useful label +- * associated with some range with may be useful to display to the user +- * within the editor at the end of the range to indicate what construct is +- * closed at that location. Closing labels include constructor/method calls +- * and List arguments that span multiple lines. Note that the ranges that +- * are returned can overlap each other because they may be associated with +- * constructs that can be nested. +- */ +- Stream onAnalysisClosingLabels; +- +- /** +- * Stream controller for [onAnalysisClosingLabels]. +- */ +- StreamController _onAnalysisClosingLabels; +- +- /** +- * Reports the errors associated with a given file. The set of errors +- * included in the notification is always a complete list that supersedes any +- * previously reported errors. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the errors. +- * +- * errors: List +- * +- * The errors contained in the file. +- */ +- Stream onAnalysisErrors; +- +- /** +- * Stream controller for [onAnalysisErrors]. +- */ +- StreamController _onAnalysisErrors; +- +- /** +- * Reports that any analysis results that were previously associated with the +- * given files should be considered to be invalid because those files are no +- * longer being analyzed, either because the analysis root that contained it +- * is no longer being analyzed or because the file no longer exists. +- * +- * If a file is included in this notification and at some later time a +- * notification with results for the file is received, clients should assume +- * that the file is once again being analyzed and the information should be +- * processed. +- * +- * It is not possible to subscribe to or unsubscribe from this notification. +- * +- * Parameters +- * +- * files: List +- * +- * The files that are no longer being analyzed. +- */ +- Stream onAnalysisFlushResults; +- +- /** +- * Stream controller for [onAnalysisFlushResults]. +- */ +- StreamController _onAnalysisFlushResults; +- +- /** +- * Reports the folding regions associated with a given file. Folding regions +- * can be nested, but will not be overlapping. Nesting occurs when a foldable +- * element, such as a method, is nested inside another foldable element such +- * as a class. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "FOLDING" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the folding regions. +- * +- * regions: List +- * +- * The folding regions contained in the file. +- */ +- Stream onAnalysisFolding; +- +- /** +- * Stream controller for [onAnalysisFolding]. +- */ +- StreamController _onAnalysisFolding; +- +- /** +- * Reports the highlight regions associated with a given file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "HIGHLIGHTS" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the highlight regions. +- * +- * regions: List +- * +- * The highlight regions contained in the file. Each highlight region +- * represents a particular syntactic or semantic meaning associated with +- * some range. Note that the highlight regions that are returned can +- * overlap other highlight regions if there is more than one meaning +- * associated with a particular region. +- */ +- Stream onAnalysisHighlights; +- +- /** +- * Stream controller for [onAnalysisHighlights]. +- */ +- StreamController _onAnalysisHighlights; +- +- /** +- * Reports the classes that are implemented or extended and class members +- * that are implemented or overridden in a file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "IMPLEMENTED" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file with which the implementations are associated. +- * +- * classes: List +- * +- * The classes defined in the file that are implemented or extended. +- * +- * members: List +- * +- * The member defined in the file that are implemented or overridden. +- */ +- Stream onAnalysisImplemented; +- +- /** +- * Stream controller for [onAnalysisImplemented]. +- */ +- StreamController _onAnalysisImplemented; +- +- /** +- * Reports that the navigation information associated with a region of a +- * single file has become invalid and should be re-requested. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "INVALIDATE" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file whose information has been invalidated. +- * +- * offset: int +- * +- * The offset of the invalidated region. +- * +- * length: int +- * +- * The length of the invalidated region. +- * +- * delta: int +- * +- * The delta to be applied to the offsets in information that follows the +- * invalidated region in order to update it so that it doesn't need to be +- * re-requested. +- */ +- Stream onAnalysisInvalidate; +- +- /** +- * Stream controller for [onAnalysisInvalidate]. +- */ +- StreamController _onAnalysisInvalidate; +- +- /** +- * Reports the navigation targets associated with a given file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "NAVIGATION" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the navigation regions. +- * +- * regions: List +- * +- * The navigation regions contained in the file. The regions are sorted by +- * their offsets. Each navigation region represents a list of targets +- * associated with some range. The lists will usually contain a single +- * target, but can contain more in the case of a part that is included in +- * multiple libraries or in Dart code that is compiled against multiple +- * versions of a package. Note that the navigation regions that are +- * returned do not overlap other navigation regions. +- * +- * targets: List +- * +- * The navigation targets referenced in the file. They are referenced by +- * NavigationRegions by their index in this array. +- * +- * files: List +- * +- * The files containing navigation targets referenced in the file. They are +- * referenced by NavigationTargets by their index in this array. +- */ +- Stream onAnalysisNavigation; +- +- /** +- * Stream controller for [onAnalysisNavigation]. +- */ +- StreamController _onAnalysisNavigation; +- +- /** +- * Reports the occurrences of references to elements within a single file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "OCCURRENCES" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which the references occur. +- * +- * occurrences: List +- * +- * The occurrences of references to elements within the file. +- */ +- Stream onAnalysisOccurrences; +- +- /** +- * Stream controller for [onAnalysisOccurrences]. +- */ +- StreamController _onAnalysisOccurrences; +- +- /** +- * Reports the outline associated with a single file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "OUTLINE" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file with which the outline is associated. +- * +- * kind: FileKind +- * +- * The kind of the file. +- * +- * libraryName: String (optional) +- * +- * The name of the library defined by the file using a "library" directive, +- * or referenced by a "part of" directive. If both "library" and "part of" +- * directives are present, then the "library" directive takes precedence. +- * This field will be omitted if the file has neither "library" nor "part +- * of" directives. +- * +- * outline: Outline +- * +- * The outline associated with the file. +- */ +- Stream onAnalysisOutline; +- +- /** +- * Stream controller for [onAnalysisOutline]. +- */ +- StreamController _onAnalysisOutline; +- +- /** +- * Reports the overriding members in a file. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "OVERRIDES" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file with which the overrides are associated. +- * +- * overrides: List +- * +- * The overrides associated with the file. +- */ +- Stream onAnalysisOverrides; +- +- /** +- * Stream controller for [onAnalysisOverrides]. +- */ +- StreamController _onAnalysisOverrides; +- +- /** +- * Request that completion suggestions for the given offset in the given file +- * be returned. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the point at which suggestions are to be made. +- * +- * offset: int +- * +- * The offset within the file at which suggestions are to be made. +- * +- * Returns +- * +- * id: CompletionId +- * +- * The identifier used to associate results with this completion request. +- */ +- Future sendCompletionGetSuggestions( +- String file, int offset) async { +- var params = new CompletionGetSuggestionsParams(file, offset).toJson(); +- var result = await server.send("completion.getSuggestions", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new CompletionGetSuggestionsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Reports the completion suggestions that should be presented to the user. +- * The set of suggestions included in the notification is always a complete +- * list that supersedes any previously reported suggestions. +- * +- * Parameters +- * +- * id: CompletionId +- * +- * The id associated with the completion. +- * +- * replacementOffset: int +- * +- * The offset of the start of the text to be replaced. This will be +- * different than the offset used to request the completion suggestions if +- * there was a portion of an identifier before the original offset. In +- * particular, the replacementOffset will be the offset of the beginning of +- * said identifier. +- * +- * replacementLength: int +- * +- * The length of the text to be replaced if the remainder of the identifier +- * containing the cursor is to be replaced when the suggestion is applied +- * (that is, the number of characters in the existing identifier). +- * +- * results: List +- * +- * The completion suggestions being reported. The notification contains all +- * possible completions at the requested cursor position, even those that +- * do not match the characters the user has already typed. This allows the +- * client to respond to further keystrokes from the user without having to +- * make additional requests. +- * +- * isLast: bool +- * +- * True if this is that last set of results that will be returned for the +- * indicated completion. +- */ +- Stream onCompletionResults; +- +- /** +- * Stream controller for [onCompletionResults]. +- */ +- StreamController _onCompletionResults; +- +- /** +- * Perform a search for references to the element defined or referenced at +- * the given offset in the given file. +- * +- * An identifier is returned immediately, and individual results will be +- * returned via the search.results notification as they become available. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the declaration of or reference to the element used +- * to define the search. +- * +- * offset: int +- * +- * The offset within the file of the declaration of or reference to the +- * element. +- * +- * includePotential: bool +- * +- * True if potential matches are to be included in the results. +- * +- * Returns +- * +- * id: SearchId (optional) +- * +- * The identifier used to associate results with this search request. +- * +- * If no element was found at the given location, this field will be +- * absent, and no results will be reported via the search.results +- * notification. +- * +- * element: Element (optional) +- * +- * The element referenced or defined at the given offset and whose +- * references will be returned in the search results. +- * +- * If no element was found at the given location, this field will be +- * absent. +- */ +- Future sendSearchFindElementReferences( +- String file, int offset, bool includePotential) async { +- var params = +- new SearchFindElementReferencesParams(file, offset, includePotential) +- .toJson(); +- var result = await server.send("search.findElementReferences", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new SearchFindElementReferencesResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Perform a search for declarations of members whose name is equal to the +- * given name. +- * +- * An identifier is returned immediately, and individual results will be +- * returned via the search.results notification as they become available. +- * +- * Parameters +- * +- * name: String +- * +- * The name of the declarations to be found. +- * +- * Returns +- * +- * id: SearchId +- * +- * The identifier used to associate results with this search request. +- */ +- Future sendSearchFindMemberDeclarations( +- String name) async { +- var params = new SearchFindMemberDeclarationsParams(name).toJson(); +- var result = await server.send("search.findMemberDeclarations", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new SearchFindMemberDeclarationsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Perform a search for references to members whose name is equal to the +- * given name. This search does not check to see that there is a member +- * defined with the given name, so it is able to find references to undefined +- * members as well. +- * +- * An identifier is returned immediately, and individual results will be +- * returned via the search.results notification as they become available. +- * +- * Parameters +- * +- * name: String +- * +- * The name of the references to be found. +- * +- * Returns +- * +- * id: SearchId +- * +- * The identifier used to associate results with this search request. +- */ +- Future sendSearchFindMemberReferences( +- String name) async { +- var params = new SearchFindMemberReferencesParams(name).toJson(); +- var result = await server.send("search.findMemberReferences", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new SearchFindMemberReferencesResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Perform a search for declarations of top-level elements (classes, +- * typedefs, getters, setters, functions and fields) whose name matches the +- * given pattern. +- * +- * An identifier is returned immediately, and individual results will be +- * returned via the search.results notification as they become available. +- * +- * Parameters +- * +- * pattern: String +- * +- * The regular expression used to match the names of the declarations to be +- * found. +- * +- * Returns +- * +- * id: SearchId +- * +- * The identifier used to associate results with this search request. +- */ +- Future +- sendSearchFindTopLevelDeclarations(String pattern) async { +- var params = new SearchFindTopLevelDeclarationsParams(pattern).toJson(); +- var result = await server.send("search.findTopLevelDeclarations", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new SearchFindTopLevelDeclarationsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return the type hierarchy of the class declared or referenced at the given +- * location. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the declaration or reference to the type for which a +- * hierarchy is being requested. +- * +- * offset: int +- * +- * The offset of the name of the type within the file. +- * +- * superOnly: bool (optional) +- * +- * True if the client is only requesting superclasses and interfaces +- * hierarchy. +- * +- * Returns +- * +- * hierarchyItems: List (optional) +- * +- * A list of the types in the requested hierarchy. The first element of the +- * list is the item representing the type for which the hierarchy was +- * requested. The index of other elements of the list is unspecified, but +- * correspond to the integers used to reference supertype and subtype items +- * within the items. +- * +- * This field will be absent if the code at the given file and offset does +- * not represent a type, or if the file has not been sufficiently analyzed +- * to allow a type hierarchy to be produced. +- */ +- Future sendSearchGetTypeHierarchy( +- String file, int offset, +- {bool superOnly}) async { +- var params = +- new SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly) +- .toJson(); +- var result = await server.send("search.getTypeHierarchy", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new SearchGetTypeHierarchyResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Reports some or all of the results of performing a requested search. +- * Unlike other notifications, this notification contains search results that +- * should be added to any previously received search results associated with +- * the same search id. +- * +- * Parameters +- * +- * id: SearchId +- * +- * The id associated with the search. +- * +- * results: List +- * +- * The search results being reported. +- * +- * isLast: bool +- * +- * True if this is that last set of results that will be returned for the +- * indicated search. +- */ +- Stream onSearchResults; +- +- /** +- * Stream controller for [onSearchResults]. +- */ +- StreamController _onSearchResults; +- +- /** +- * Format the contents of a single file. The currently selected region of +- * text is passed in so that the selection can be preserved across the +- * formatting operation. The updated selection will be as close to matching +- * the original as possible, but whitespace at the beginning or end of the +- * selected region will be ignored. If preserving selection information is +- * not required, zero (0) can be specified for both the selection offset and +- * selection length. +- * +- * If a request is made for a file which does not exist, or which is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified to analysis.setAnalysisRoots), an error of type +- * FORMAT_INVALID_FILE will be generated. If the source contains syntax +- * errors, an error of type FORMAT_WITH_ERRORS will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code to be formatted. +- * +- * selectionOffset: int +- * +- * The offset of the current selection in the file. +- * +- * selectionLength: int +- * +- * The length of the current selection in the file. +- * +- * lineLength: int (optional) +- * +- * The line length to be used by the formatter. +- * +- * Returns +- * +- * edits: List +- * +- * The edit(s) to be applied in order to format the code. The list will be +- * empty if the code was already formatted (there are no changes). +- * +- * selectionOffset: int +- * +- * The offset of the selection after formatting the code. +- * +- * selectionLength: int +- * +- * The length of the selection after formatting the code. +- */ +- Future sendEditFormat( +- String file, int selectionOffset, int selectionLength, +- {int lineLength}) async { +- var params = new EditFormatParams(file, selectionOffset, selectionLength, +- lineLength: lineLength) +- .toJson(); +- var result = await server.send("edit.format", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditFormatResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Return the set of assists that are available at the given location. An +- * assist is distinguished from a refactoring primarily by the fact that it +- * affects a single file and does not require user input in order to be +- * performed. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code for which assists are being requested. +- * +- * offset: int +- * +- * The offset of the code for which assists are being requested. +- * +- * length: int +- * +- * The length of the code for which assists are being requested. +- * +- * Returns +- * +- * assists: List +- * +- * The assists that are available at the given location. +- */ +- Future sendEditGetAssists( +- String file, int offset, int length) async { +- var params = new EditGetAssistsParams(file, offset, length).toJson(); +- var result = await server.send("edit.getAssists", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetAssistsResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Get a list of the kinds of refactorings that are valid for the given +- * selection in the given file. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code on which the refactoring would be based. +- * +- * offset: int +- * +- * The offset of the code on which the refactoring would be based. +- * +- * length: int +- * +- * The length of the code on which the refactoring would be based. +- * +- * Returns +- * +- * kinds: List +- * +- * The kinds of refactorings that are valid for the given selection. +- */ +- Future sendEditGetAvailableRefactorings( +- String file, int offset, int length) async { +- var params = +- new EditGetAvailableRefactoringsParams(file, offset, length).toJson(); +- var result = await server.send("edit.getAvailableRefactorings", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetAvailableRefactoringsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return the set of fixes that are available for the errors at a given +- * offset in a given file. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the errors for which fixes are being requested. +- * +- * offset: int +- * +- * The offset used to select the errors for which fixes will be returned. +- * +- * Returns +- * +- * fixes: List +- * +- * The fixes that are available for the errors at the given offset. +- */ +- Future sendEditGetFixes(String file, int offset) async { +- var params = new EditGetFixesParams(file, offset).toJson(); +- var result = await server.send("edit.getFixes", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetFixesResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Get the changes required to convert the postfix template at the given +- * location into the template's expanded form. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the postfix template to be expanded. +- * +- * key: String +- * +- * The unique name that identifies the template in use. +- * +- * offset: int +- * +- * The offset used to identify the code to which the template will be +- * applied. +- * +- * Returns +- * +- * change: SourceChange +- * +- * The change to be applied in order to complete the statement. +- */ +- Future sendEditGetPostfixCompletion( +- String file, String key, int offset) async { +- var params = new EditGetPostfixCompletionParams(file, key, offset).toJson(); +- var result = await server.send("edit.getPostfixCompletion", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetPostfixCompletionResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Get the changes required to perform a refactoring. +- * +- * If another refactoring request is received during the processing of this +- * one, an error of type REFACTORING_REQUEST_CANCELLED will be generated. +- * +- * Parameters +- * +- * kind: RefactoringKind +- * +- * The kind of refactoring to be performed. +- * +- * file: FilePath +- * +- * The file containing the code involved in the refactoring. +- * +- * offset: int +- * +- * The offset of the region involved in the refactoring. +- * +- * length: int +- * +- * The length of the region involved in the refactoring. +- * +- * validateOnly: bool +- * +- * True if the client is only requesting that the values of the options be +- * validated and no change be generated. +- * +- * options: RefactoringOptions (optional) +- * +- * Data used to provide values provided by the user. The structure of the +- * data is dependent on the kind of refactoring being performed. The data +- * that is expected is documented in the section titled Refactorings, +- * labeled as "Options". This field can be omitted if the refactoring does +- * not require any options or if the values of those options are not known. +- * +- * Returns +- * +- * initialProblems: List +- * +- * The initial status of the refactoring, i.e. problems related to the +- * context in which the refactoring is requested. The array will be empty +- * if there are no known problems. +- * +- * optionsProblems: List +- * +- * The options validation status, i.e. problems in the given options, such +- * as light-weight validation of a new name, flags compatibility, etc. The +- * array will be empty if there are no known problems. +- * +- * finalProblems: List +- * +- * The final status of the refactoring, i.e. problems identified in the +- * result of a full, potentially expensive validation and / or change +- * creation. The array will be empty if there are no known problems. +- * +- * feedback: RefactoringFeedback (optional) +- * +- * Data used to provide feedback to the user. The structure of the data is +- * dependent on the kind of refactoring being created. The data that is +- * returned is documented in the section titled Refactorings, labeled as +- * "Feedback". +- * +- * change: SourceChange (optional) +- * +- * The changes that are to be applied to affect the refactoring. This field +- * will be omitted if there are problems that prevent a set of changes from +- * being computed, such as having no options specified for a refactoring +- * that requires them, or if only validation was requested. +- * +- * potentialEdits: List (optional) +- * +- * The ids of source edits that are not known to be valid. An edit is not +- * known to be valid if there was insufficient type information for the +- * server to be able to determine whether or not the code needs to be +- * modified, such as when a member is being renamed and there is a +- * reference to a member from an unknown type. This field will be omitted +- * if the change field is omitted or if there are no potential edits for +- * the refactoring. +- */ +- Future sendEditGetRefactoring(RefactoringKind kind, +- String file, int offset, int length, bool validateOnly, +- {RefactoringOptions options}) async { +- var params = new EditGetRefactoringParams( +- kind, file, offset, length, validateOnly, +- options: options) +- .toJson(); +- var result = await server.send("edit.getRefactoring", params); +- ResponseDecoder decoder = new ResponseDecoder(kind); +- return new EditGetRefactoringResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Get the changes required to convert the partial statement at the given +- * location into a syntactically valid statement. If the current statement is +- * already valid the change will insert a newline plus appropriate +- * indentation at the end of the line containing the offset. If a change that +- * makes the statement valid cannot be determined (perhaps because it has not +- * yet been implemented) the statement will be considered already valid and +- * the appropriate change returned. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the statement to be completed. +- * +- * offset: int +- * +- * The offset used to identify the statement to be completed. +- * +- * Returns +- * +- * change: SourceChange +- * +- * The change to be applied in order to complete the statement. +- * +- * whitespaceOnly: bool +- * +- * Will be true if the change contains nothing but whitespace characters, +- * or is empty. +- */ +- Future sendEditGetStatementCompletion( +- String file, int offset) async { +- var params = new EditGetStatementCompletionParams(file, offset).toJson(); +- var result = await server.send("edit.getStatementCompletion", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetStatementCompletionResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Determine if the request postfix completion template is applicable at the +- * given location in the given file. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the postfix template to be expanded. +- * +- * key: String +- * +- * The unique name that identifies the template in use. +- * +- * offset: int +- * +- * The offset used to identify the code to which the template will be +- * applied. +- * +- * Returns +- * +- * value: bool +- * +- * True if the template can be expanded at the given location. +- */ +- Future +- sendEditIsPostfixCompletionApplicable( +- String file, String key, int offset) async { +- var params = +- new EditIsPostfixCompletionApplicableParams(file, key, offset).toJson(); +- var result = +- await server.send("edit.isPostfixCompletionApplicable", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditIsPostfixCompletionApplicableResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return a list of all postfix templates currently available. +- * +- * Returns +- * +- * templates: List +- * +- * The list of available templates. +- */ +- Future +- sendEditListPostfixCompletionTemplates() async { +- var result = await server.send("edit.listPostfixCompletionTemplates", null); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditListPostfixCompletionTemplatesResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return a list of edits that would need to be applied in order to ensure +- * that all of the elements in the specified list of imported elements are +- * accessible within the library. +- * +- * If a request is made for a file that does not exist, or that is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified via analysis.setAnalysisRoots), an error of type +- * IMPORT_ELEMENTS_INVALID_FILE will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which the specified elements are to be made accessible. +- * +- * elements: List +- * +- * The elements to be made accessible in the specified file. +- * +- * Returns +- * +- * edit: SourceFileEdit +- * +- * The edits to be applied in order to make the specified elements +- * accessible. The file to be edited will be the defining compilation unit +- * of the library containing the file specified in the request, which can +- * be different than the file specified in the request if the specified +- * file is a part file. +- */ +- Future sendEditImportElements( +- String file, List elements) async { +- var params = new EditImportElementsParams(file, elements).toJson(); +- var result = await server.send("edit.importElements", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditImportElementsResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Sort all of the directives, unit and class members of the given Dart file. +- * +- * If a request is made for a file that does not exist, does not belong to an +- * analysis root or is not a Dart file, SORT_MEMBERS_INVALID_FILE will be +- * generated. +- * +- * If the Dart file has scan or parse errors, SORT_MEMBERS_PARSE_ERRORS will +- * be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The Dart file to sort. +- * +- * Returns +- * +- * edit: SourceFileEdit +- * +- * The file edit that is to be applied to the given file to effect the +- * sorting. +- */ +- Future sendEditSortMembers(String file) async { +- var params = new EditSortMembersParams(file).toJson(); +- var result = await server.send("edit.sortMembers", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditSortMembersResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Organizes all of the directives - removes unused imports and sorts +- * directives of the given Dart file according to the Dart Style Guide. +- * +- * If a request is made for a file that does not exist, does not belong to an +- * analysis root or is not a Dart file, FILE_NOT_ANALYZED will be generated. +- * +- * If directives of the Dart file cannot be organized, for example because it +- * has scan or parse errors, or by other reasons, ORGANIZE_DIRECTIVES_ERROR +- * will be generated. The message will provide details about the reason. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The Dart file to organize directives in. +- * +- * Returns +- * +- * edit: SourceFileEdit +- * +- * The file edit that is to be applied to the given file to effect the +- * organizing. +- */ +- Future sendEditOrganizeDirectives( +- String file) async { +- var params = new EditOrganizeDirectivesParams(file).toJson(); +- var result = await server.send("edit.organizeDirectives", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditOrganizeDirectivesResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Create an execution context for the executable file with the given path. +- * The context that is created will persist until execution.deleteContext is +- * used to delete it. Clients, therefore, are responsible for managing the +- * lifetime of execution contexts. +- * +- * Parameters +- * +- * contextRoot: FilePath +- * +- * The path of the Dart or HTML file that will be launched, or the path of +- * the directory containing the file. +- * +- * Returns +- * +- * id: ExecutionContextId +- * +- * The identifier used to refer to the execution context that was created. +- */ +- Future sendExecutionCreateContext( +- String contextRoot) async { +- var params = new ExecutionCreateContextParams(contextRoot).toJson(); +- var result = await server.send("execution.createContext", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new ExecutionCreateContextResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Delete the execution context with the given identifier. The context id is +- * no longer valid after this command. The server is allowed to re-use ids +- * when they are no longer valid. +- * +- * Parameters +- * +- * id: ExecutionContextId +- * +- * The identifier of the execution context that is to be deleted. +- */ +- Future sendExecutionDeleteContext(String id) async { +- var params = new ExecutionDeleteContextParams(id).toJson(); +- var result = await server.send("execution.deleteContext", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Map a URI from the execution context to the file that it corresponds to, +- * or map a file to the URI that it corresponds to in the execution context. +- * +- * Exactly one of the file and uri fields must be provided. If both fields +- * are provided, then an error of type INVALID_PARAMETER will be generated. +- * Similarly, if neither field is provided, then an error of type +- * INVALID_PARAMETER will be generated. +- * +- * If the file field is provided and the value is not the path of a file +- * (either the file does not exist or the path references something other +- * than a file), then an error of type INVALID_PARAMETER will be generated. +- * +- * If the uri field is provided and the value is not a valid URI or if the +- * URI references something that is not a file (either a file that does not +- * exist or something other than a file), then an error of type +- * INVALID_PARAMETER will be generated. +- * +- * If the contextRoot used to create the execution context does not exist, +- * then an error of type INVALID_EXECUTION_CONTEXT will be generated. +- * +- * Parameters +- * +- * id: ExecutionContextId +- * +- * The identifier of the execution context in which the URI is to be +- * mapped. +- * +- * file: FilePath (optional) +- * +- * The path of the file to be mapped into a URI. +- * +- * uri: String (optional) +- * +- * The URI to be mapped into a file path. +- * +- * Returns +- * +- * file: FilePath (optional) +- * +- * The file to which the URI was mapped. This field is omitted if the uri +- * field was not given in the request. +- * +- * uri: String (optional) +- * +- * The URI to which the file path was mapped. This field is omitted if the +- * file field was not given in the request. +- */ +- Future sendExecutionMapUri(String id, +- {String file, String uri}) async { +- var params = new ExecutionMapUriParams(id, file: file, uri: uri).toJson(); +- var result = await server.send("execution.mapUri", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new ExecutionMapUriResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Deprecated: the analysis server no longer fires LAUNCH_DATA events. +- * +- * Subscribe for services. All previous subscriptions are replaced by the +- * given set of services. +- * +- * It is an error if any of the elements in the list are not valid services. +- * If there is an error, then the current subscriptions will remain +- * unchanged. +- * +- * Parameters +- * +- * subscriptions: List +- * +- * A list of the services being subscribed to. +- */ +- @deprecated +- Future sendExecutionSetSubscriptions( +- List subscriptions) async { +- var params = new ExecutionSetSubscriptionsParams(subscriptions).toJson(); +- var result = await server.send("execution.setSubscriptions", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Reports information needed to allow a single file to be launched. +- * +- * This notification is not subscribed to by default. Clients can subscribe +- * by including the value "LAUNCH_DATA" in the list of services passed in an +- * execution.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file for which launch data is being provided. This will either be a +- * Dart library or an HTML file. +- * +- * kind: ExecutableKind (optional) +- * +- * The kind of the executable file. This field is omitted if the file is +- * not a Dart file. +- * +- * referencedFiles: List (optional) +- * +- * A list of the Dart files that are referenced by the file. This field is +- * omitted if the file is not an HTML file. +- */ +- Stream onExecutionLaunchData; +- +- /** +- * Stream controller for [onExecutionLaunchData]. +- */ +- StreamController _onExecutionLaunchData; +- +- /** +- * Return server diagnostics. +- * +- * Returns +- * +- * contexts: List +- * +- * The list of analysis contexts. +- */ +- Future sendDiagnosticGetDiagnostics() async { +- var result = await server.send("diagnostic.getDiagnostics", null); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new DiagnosticGetDiagnosticsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Return the port of the diagnostic web server. If the server is not running +- * this call will start the server. If unable to start the diagnostic web +- * server, this call will return an error of DEBUG_PORT_COULD_NOT_BE_OPENED. +- * +- * Returns +- * +- * port: int +- * +- * The diagnostic server port. +- */ +- Future sendDiagnosticGetServerPort() async { +- var result = await server.send("diagnostic.getServerPort", null); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new DiagnosticGetServerPortResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Query whether analytics is enabled. +- * +- * This flag controls whether the analysis server sends any analytics data to +- * the cloud. If disabled, the analysis server does not send any analytics +- * data, and any data sent to it by clients (from sendEvent and sendTiming) +- * will be ignored. +- * +- * The value of this flag can be changed by other tools outside of the +- * analysis server's process. When you query the flag, you get the value of +- * the flag at a given moment. Clients should not use the value returned to +- * decide whether or not to send the sendEvent and sendTiming requests. Those +- * requests should be used unconditionally and server will determine whether +- * or not it is appropriate to forward the information to the cloud at the +- * time each request is received. +- * +- * Returns +- * +- * enabled: bool +- * +- * Whether sending analytics is enabled or not. +- */ +- Future sendAnalyticsIsEnabled() async { +- var result = await server.send("analytics.isEnabled", null); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalyticsIsEnabledResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Enable or disable the sending of analytics data. Note that there are other +- * ways for users to change this setting, so clients cannot assume that they +- * have complete control over this setting. In particular, there is no +- * guarantee that the result returned by the isEnabled request will match the +- * last value set via this request. +- * +- * Parameters +- * +- * value: bool +- * +- * Enable or disable analytics. +- */ +- Future sendAnalyticsEnable(bool value) async { +- var params = new AnalyticsEnableParams(value).toJson(); +- var result = await server.send("analytics.enable", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Send information about client events. +- * +- * Ask the analysis server to include the fact that an action was performed +- * in the client as part of the analytics data being sent. The data will only +- * be included if the sending of analytics data is enabled at the time the +- * request is processed. The action that was performed is indicated by the +- * value of the action field. +- * +- * The value of the action field should not include the identity of the +- * client. The analytics data sent by server will include the client id +- * passed in using the --client-id command-line argument. The request will be +- * ignored if the client id was not provided when server was started. +- * +- * Parameters +- * +- * action: String +- * +- * The value used to indicate which action was performed. +- */ +- Future sendAnalyticsSendEvent(String action) async { +- var params = new AnalyticsSendEventParams(action).toJson(); +- var result = await server.send("analytics.sendEvent", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Send timing information for client events (e.g. code completions). +- * +- * Ask the analysis server to include the fact that a timed event occurred as +- * part of the analytics data being sent. The data will only be included if +- * the sending of analytics data is enabled at the time the request is +- * processed. +- * +- * The value of the event field should not include the identity of the +- * client. The analytics data sent by server will include the client id +- * passed in using the --client-id command-line argument. The request will be +- * ignored if the client id was not provided when server was started. +- * +- * Parameters +- * +- * event: String +- * +- * The name of the event. +- * +- * millis: int +- * +- * The duration of the event in milliseconds. +- */ +- Future sendAnalyticsSendTiming(String event, int millis) async { +- var params = new AnalyticsSendTimingParams(event, millis).toJson(); +- var result = await server.send("analytics.sendTiming", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Return the list of KytheEntry objects for some file, given the current +- * state of the file system populated by "analysis.updateContent". +- * +- * If a request is made for a file that does not exist, or that is not +- * currently subject to analysis (e.g. because it is not associated with any +- * analysis root specified to analysis.setAnalysisRoots), an error of type +- * GET_KYTHE_ENTRIES_INVALID_FILE will be generated. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code for which the Kythe Entry objects are being +- * requested. +- * +- * Returns +- * +- * entries: List +- * +- * The list of KytheEntry objects for the queried file. +- * +- * files: List +- * +- * The set of files paths that were required, but not in the file system, +- * to give a complete and accurate Kythe graph for the file. This could be +- * due to a referenced file that does not exist or generated files not +- * being generated or passed before the call to "getKytheEntries". +- */ +- Future sendKytheGetKytheEntries( +- String file) async { +- var params = new KytheGetKytheEntriesParams(file).toJson(); +- var result = await server.send("kythe.getKytheEntries", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new KytheGetKytheEntriesResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Initialize the fields in InttestMixin, and ensure that notifications will +- * be handled. +- */ +- void initializeInttestMixin() { +- _onServerConnected = +- new StreamController(sync: true); +- onServerConnected = _onServerConnected.stream.asBroadcastStream(); +- _onServerError = new StreamController(sync: true); +- onServerError = _onServerError.stream.asBroadcastStream(); +- _onServerStatus = new StreamController(sync: true); +- onServerStatus = _onServerStatus.stream.asBroadcastStream(); +- _onAnalysisAnalyzedFiles = +- new StreamController(sync: true); +- onAnalysisAnalyzedFiles = +- _onAnalysisAnalyzedFiles.stream.asBroadcastStream(); +- _onAnalysisClosingLabels = +- new StreamController(sync: true); +- onAnalysisClosingLabels = +- _onAnalysisClosingLabels.stream.asBroadcastStream(); +- _onAnalysisErrors = new StreamController(sync: true); +- onAnalysisErrors = _onAnalysisErrors.stream.asBroadcastStream(); +- _onAnalysisFlushResults = +- new StreamController(sync: true); +- onAnalysisFlushResults = _onAnalysisFlushResults.stream.asBroadcastStream(); +- _onAnalysisFolding = +- new StreamController(sync: true); +- onAnalysisFolding = _onAnalysisFolding.stream.asBroadcastStream(); +- _onAnalysisHighlights = +- new StreamController(sync: true); +- onAnalysisHighlights = _onAnalysisHighlights.stream.asBroadcastStream(); +- _onAnalysisImplemented = +- new StreamController(sync: true); +- onAnalysisImplemented = _onAnalysisImplemented.stream.asBroadcastStream(); +- _onAnalysisInvalidate = +- new StreamController(sync: true); +- onAnalysisInvalidate = _onAnalysisInvalidate.stream.asBroadcastStream(); +- _onAnalysisNavigation = +- new StreamController(sync: true); +- onAnalysisNavigation = _onAnalysisNavigation.stream.asBroadcastStream(); +- _onAnalysisOccurrences = +- new StreamController(sync: true); +- onAnalysisOccurrences = _onAnalysisOccurrences.stream.asBroadcastStream(); +- _onAnalysisOutline = +- new StreamController(sync: true); +- onAnalysisOutline = _onAnalysisOutline.stream.asBroadcastStream(); +- _onAnalysisOverrides = +- new StreamController(sync: true); +- onAnalysisOverrides = _onAnalysisOverrides.stream.asBroadcastStream(); +- _onCompletionResults = +- new StreamController(sync: true); +- onCompletionResults = _onCompletionResults.stream.asBroadcastStream(); +- _onSearchResults = new StreamController(sync: true); +- onSearchResults = _onSearchResults.stream.asBroadcastStream(); +- _onExecutionLaunchData = +- new StreamController(sync: true); +- onExecutionLaunchData = _onExecutionLaunchData.stream.asBroadcastStream(); +- } +- +- /** +- * Dispatch the notification named [event], and containing parameters +- * [params], to the appropriate stream. +- */ +- void dispatchNotification(String event, params) { +- ResponseDecoder decoder = new ResponseDecoder(null); +- switch (event) { +- case "server.connected": +- outOfTestExpect(params, isServerConnectedParams); +- _onServerConnected +- .add(new ServerConnectedParams.fromJson(decoder, 'params', params)); +- break; +- case "server.error": +- outOfTestExpect(params, isServerErrorParams); +- _onServerError +- .add(new ServerErrorParams.fromJson(decoder, 'params', params)); +- break; +- case "server.status": +- outOfTestExpect(params, isServerStatusParams); +- _onServerStatus +- .add(new ServerStatusParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.analyzedFiles": +- outOfTestExpect(params, isAnalysisAnalyzedFilesParams); +- _onAnalysisAnalyzedFiles.add(new AnalysisAnalyzedFilesParams.fromJson( +- decoder, 'params', params)); +- break; +- case "analysis.closingLabels": +- outOfTestExpect(params, isAnalysisClosingLabelsParams); +- _onAnalysisClosingLabels.add(new AnalysisClosingLabelsParams.fromJson( +- decoder, 'params', params)); +- break; +- case "analysis.errors": +- outOfTestExpect(params, isAnalysisErrorsParams); +- _onAnalysisErrors +- .add(new AnalysisErrorsParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.flushResults": +- outOfTestExpect(params, isAnalysisFlushResultsParams); +- _onAnalysisFlushResults.add( +- new AnalysisFlushResultsParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.folding": +- outOfTestExpect(params, isAnalysisFoldingParams); +- _onAnalysisFolding +- .add(new AnalysisFoldingParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.highlights": +- outOfTestExpect(params, isAnalysisHighlightsParams); +- _onAnalysisHighlights.add( +- new AnalysisHighlightsParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.implemented": +- outOfTestExpect(params, isAnalysisImplementedParams); +- _onAnalysisImplemented.add( +- new AnalysisImplementedParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.invalidate": +- outOfTestExpect(params, isAnalysisInvalidateParams); +- _onAnalysisInvalidate.add( +- new AnalysisInvalidateParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.navigation": +- outOfTestExpect(params, isAnalysisNavigationParams); +- _onAnalysisNavigation.add( +- new AnalysisNavigationParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.occurrences": +- outOfTestExpect(params, isAnalysisOccurrencesParams); +- _onAnalysisOccurrences.add( +- new AnalysisOccurrencesParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.outline": +- outOfTestExpect(params, isAnalysisOutlineParams); +- _onAnalysisOutline +- .add(new AnalysisOutlineParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.overrides": +- outOfTestExpect(params, isAnalysisOverridesParams); +- _onAnalysisOverrides.add( +- new AnalysisOverridesParams.fromJson(decoder, 'params', params)); +- break; +- case "completion.results": +- outOfTestExpect(params, isCompletionResultsParams); +- _onCompletionResults.add( +- new CompletionResultsParams.fromJson(decoder, 'params', params)); +- break; +- case "search.results": +- outOfTestExpect(params, isSearchResultsParams); +- _onSearchResults +- .add(new SearchResultsParams.fromJson(decoder, 'params', params)); +- break; +- case "execution.launchData": +- outOfTestExpect(params, isExecutionLaunchDataParams); +- _onExecutionLaunchData.add( +- new ExecutionLaunchDataParams.fromJson(decoder, 'params', params)); +- break; +- default: +- fail('Unexpected notification: $event'); +- break; +- } +- } +-} +diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart +deleted file mode 100644 +index e025849a09b..00000000000 +--- a/pkg/analysis_server/test/integration/support/integration_tests.dart ++++ /dev/null +@@ -1,1003 +0,0 @@ +-// Copyright (c) 2014, 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 'dart:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:path/path.dart'; +-import 'package:test/test.dart'; +- +-import 'integration_test_methods.dart'; +-import 'protocol_matchers.dart'; +- +-const Matcher isBool = const isInstanceOf(); +- +-const Matcher isInt = const isInstanceOf(); +- +-const Matcher isNotification = const MatchesJsonObject( +- 'notification', const {'event': isString}, +- optionalFields: const {'params': isMap}); +- +-const Matcher isObject = isMap; +- +-const Matcher isString = const isInstanceOf(); +- +-final Matcher isResponse = new MatchesJsonObject('response', {'id': isString}, +- optionalFields: {'result': anything, 'error': isRequestError}); +- +-Matcher isListOf(Matcher elementMatcher) => new _ListOf(elementMatcher); +- +-Matcher isMapOf(Matcher keyMatcher, Matcher valueMatcher) => +- new _MapOf(keyMatcher, valueMatcher); +- +-Matcher isOneOf(List choiceMatchers) => new _OneOf(choiceMatchers); +- +-/** +- * Assert that [actual] matches [matcher]. +- */ +-void outOfTestExpect(actual, matcher, +- {String reason, skip, bool verbose: false}) { +- var matchState = {}; +- try { +- if (matcher.matches(actual, matchState)) return; +- } catch (e, trace) { +- if (reason == null) { +- reason = '${(e is String) ? e : e.toString()} at $trace'; +- } +- } +- fail(_defaultFailFormatter(actual, matcher, reason, matchState, verbose)); +-} +- +-String _defaultFailFormatter( +- actual, Matcher matcher, String reason, Map matchState, bool verbose) { +- var description = new StringDescription(); +- description.add('Expected: ').addDescriptionOf(matcher).add('\n'); +- description.add(' Actual: ').addDescriptionOf(actual).add('\n'); +- +- var mismatchDescription = new StringDescription(); +- matcher.describeMismatch(actual, mismatchDescription, matchState, verbose); +- +- if (mismatchDescription.length > 0) { +- description.add(' Which: $mismatchDescription\n'); +- } +- if (reason != null) description.add(reason).add('\n'); +- return description.toString(); +-} +- +-/** +- * Type of closures used by LazyMatcher. +- */ +-typedef Matcher MatcherCreator(); +- +-/** +- * Type of closures used by MatchesJsonObject to record field mismatches. +- */ +-typedef Description MismatchDescriber(Description mismatchDescription); +- +-/** +- * Type of callbacks used to process notifications. +- */ +-typedef void NotificationProcessor(String event, params); +- +-/** +- * Base class for analysis server integration tests. +- */ +-abstract class AbstractAnalysisServerIntegrationTest +- extends IntegrationTestMixin { +- /** +- * Amount of time to give the server to respond to a shutdown request before +- * forcibly terminating it. +- */ +- static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5); +- +- /** +- * Connection to the analysis server. +- */ +- final Server server = new Server(); +- +- /** +- * Temporary directory in which source files can be stored. +- */ +- Directory sourceDirectory; +- +- /** +- * Map from file path to the list of analysis errors which have most recently +- * been received for the file. +- */ +- HashMap> currentAnalysisErrors = +- new HashMap>(); +- +- /** +- * The last list of analyzed files received. +- */ +- List lastAnalyzedFiles; +- +- /** +- * True if the teardown process should skip sending a "server.shutdown" +- * request (e.g. because the server is known to have already shutdown). +- */ +- bool skipShutdown = false; +- +- /** +- * True if we are currently subscribed to [SERVER_NOTIFICATION_STATUS] updates. +- */ +- bool _subscribedToServerStatus = false; +- +- AbstractAnalysisServerIntegrationTest() { +- initializeInttestMixin(); +- } +- +- /** +- * Return a future which will complete when a 'server.status' notification is +- * received from the server with 'analyzing' set to false. +- * +- * The future will only be completed by 'server.status' notifications that are +- * received after this function call. So it is safe to use this getter +- * multiple times in one test; each time it is used it will wait afresh for +- * analysis to finish. +- */ +- Future get analysisFinished { +- Completer completer = new Completer(); +- StreamSubscription subscription; +- // This will only work if the caller has already subscribed to +- // SERVER_STATUS (e.g. using sendServerSetSubscriptions(['STATUS'])) +- outOfTestExpect(_subscribedToServerStatus, isTrue); +- subscription = onServerStatus.listen((ServerStatusParams params) { +- if (params.analysis != null && !params.analysis.isAnalyzing) { +- completer.complete(params); +- subscription.cancel(); +- } +- }); +- return completer.future; +- } +- +- /** +- * Print out any messages exchanged with the server. If some messages have +- * already been exchanged with the server, they are printed out immediately. +- */ +- void debugStdio() { +- server.debugStdio(); +- } +- +- List getErrors(String pathname) => +- currentAnalysisErrors[pathname]; +- +- /** +- * Read a source file with the given absolute [pathname]. +- */ +- String readFile(String pathname) => new File(pathname).readAsStringSync(); +- +- @override +- Future sendServerSetSubscriptions(List subscriptions) { +- _subscribedToServerStatus = subscriptions.contains(ServerService.STATUS); +- return super.sendServerSetSubscriptions(subscriptions); +- } +- +- /** +- * The server is automatically started before every test, and a temporary +- * [sourceDirectory] is created. +- */ +- Future setUp() async { +- sourceDirectory = new Directory(Directory.systemTemp +- .createTempSync('analysisServer') +- .resolveSymbolicLinksSync()); +- +- onAnalysisErrors.listen((AnalysisErrorsParams params) { +- currentAnalysisErrors[params.file] = params.errors; +- }); +- onAnalysisAnalyzedFiles.listen((AnalysisAnalyzedFilesParams params) { +- lastAnalyzedFiles = params.directories; +- }); +- Completer serverConnected = new Completer(); +- onServerConnected.listen((_) { +- outOfTestExpect(serverConnected.isCompleted, isFalse); +- serverConnected.complete(); +- }); +- onServerError.listen((ServerErrorParams params) { +- // A server error should never happen during an integration test. +- fail('${params.message}\n${params.stackTrace}'); +- }); +- await startServer(); +- server.listenToOutput(dispatchNotification); +- server.exitCode.then((_) { +- skipShutdown = true; +- }); +- return serverConnected.future; +- } +- +- /** +- * If [skipShutdown] is not set, shut down the server. +- */ +- Future shutdownIfNeeded() { +- if (skipShutdown) { +- return new Future.value(); +- } +- // Give the server a short time to comply with the shutdown request; if it +- // doesn't exit, then forcibly terminate it. +- sendServerShutdown(); +- return server.exitCode.timeout(SHUTDOWN_TIMEOUT, onTimeout: () { +- // The integer value of the exit code isn't used, but we have to return +- // an integer to keep the typing correct. +- return server.kill('server failed to exit').then((_) => -1); +- }); +- } +- +- /** +- * Convert the given [relativePath] to an absolute path, by interpreting it +- * relative to [sourceDirectory]. On Windows any forward slashes in +- * [relativePath] are converted to backslashes. +- */ +- String sourcePath(String relativePath) { +- return join(sourceDirectory.path, relativePath.replaceAll('/', separator)); +- } +- +- /** +- * Send the server an 'analysis.setAnalysisRoots' command directing it to +- * analyze [sourceDirectory]. If [subscribeStatus] is true (the default), +- * then also enable [SERVER_NOTIFICATION_STATUS] notifications so that +- * [analysisFinished] can be used. +- */ +- Future standardAnalysisSetup({bool subscribeStatus: true}) { +- List futures = []; +- if (subscribeStatus) { +- futures.add(sendServerSetSubscriptions([ServerService.STATUS])); +- } +- futures.add(sendAnalysisSetAnalysisRoots([sourceDirectory.path], [])); +- return Future.wait(futures); +- } +- +- /** +- * Start [server]. +- */ +- Future startServer({ +- bool checked: true, +- int diagnosticPort, +- int servicesPort, +- bool previewDart2: false, +- }) { +- return server.start( +- checked: checked, +- diagnosticPort: diagnosticPort, +- servicesPort: servicesPort, +- previewDart2: previewDart2); +- } +- +- /** +- * After every test, the server is stopped and [sourceDirectory] is deleted. +- */ +- Future tearDown() { +- return shutdownIfNeeded().then((_) { +- sourceDirectory.deleteSync(recursive: true); +- }); +- } +- +- /** +- * Write a source file with the given absolute [pathname] and [contents]. +- * +- * If the file didn't previously exist, it is created. If it did, it is +- * overwritten. +- * +- * Parent directories are created as necessary. +- * +- * Return a normalized path to the file (with symbolic links resolved). +- */ +- String writeFile(String pathname, String contents) { +- new Directory(dirname(pathname)).createSync(recursive: true); +- File file = new File(pathname); +- file.writeAsStringSync(contents); +- return file.resolveSymbolicLinksSync(); +- } +-} +- +-/** +- * Wrapper class for Matcher which doesn't create the underlying Matcher object +- * until it is needed. This is necessary in order to create matchers that can +- * refer to themselves (so that recursive data structures can be represented). +- */ +-class LazyMatcher implements Matcher { +- /** +- * Callback that will be used to create the matcher the first time it is +- * needed. +- */ +- final MatcherCreator _creator; +- +- /** +- * The matcher returned by [_creator], if it has already been called. +- * Otherwise null. +- */ +- Matcher _wrappedMatcher; +- +- LazyMatcher(this._creator); +- +- @override +- Description describe(Description description) { +- _createMatcher(); +- return _wrappedMatcher.describe(description); +- } +- +- @override +- Description describeMismatch( +- item, Description mismatchDescription, Map matchState, bool verbose) { +- _createMatcher(); +- return _wrappedMatcher.describeMismatch( +- item, mismatchDescription, matchState, verbose); +- } +- +- @override +- bool matches(item, Map matchState) { +- _createMatcher(); +- return _wrappedMatcher.matches(item, matchState); +- } +- +- /** +- * Create the wrapped matcher object, if it hasn't been created already. +- */ +- void _createMatcher() { +- if (_wrappedMatcher == null) { +- _wrappedMatcher = _creator(); +- } +- } +-} +- +-/** +- * Matcher that matches a String drawn from a limited set. +- */ +-class MatchesEnum extends Matcher { +- /** +- * Short description of the expected type. +- */ +- final String description; +- +- /** +- * The set of enum values that are allowed. +- */ +- final List allowedValues; +- +- const MatchesEnum(this.description, this.allowedValues); +- +- @override +- Description describe(Description description) => +- description.add(this.description); +- +- @override +- bool matches(item, Map matchState) { +- return allowedValues.contains(item); +- } +-} +- +-/** +- * Matcher that matches a JSON object, with a given set of required and +- * optional fields, and their associated types (expressed as [Matcher]s). +- */ +-class MatchesJsonObject extends _RecursiveMatcher { +- /** +- * Short description of the expected type. +- */ +- final String description; +- +- /** +- * Fields that are required to be in the JSON object, and [Matcher]s describing +- * their expected types. +- */ +- final Map requiredFields; +- +- /** +- * Fields that are optional in the JSON object, and [Matcher]s describing +- * their expected types. +- */ +- final Map optionalFields; +- +- const MatchesJsonObject(this.description, this.requiredFields, +- {this.optionalFields}); +- +- @override +- Description describe(Description description) => +- description.add(this.description); +- +- @override +- void populateMismatches(item, List mismatches) { +- if (item is! Map) { +- mismatches.add(simpleDescription('is not a map')); +- return; +- } +- if (requiredFields != null) { +- requiredFields.forEach((String key, Matcher valueMatcher) { +- if (!item.containsKey(key)) { +- mismatches.add((Description mismatchDescription) => +- mismatchDescription +- .add('is missing field ') +- .addDescriptionOf(key) +- .add(' (') +- .addDescriptionOf(valueMatcher) +- .add(')')); +- } else { +- _checkField(key, item[key], valueMatcher, mismatches); +- } +- }); +- } +- item.forEach((key, value) { +- if (requiredFields != null && requiredFields.containsKey(key)) { +- // Already checked this field +- } else if (optionalFields != null && optionalFields.containsKey(key)) { +- _checkField(key, value, optionalFields[key], mismatches); +- } else { +- mismatches.add((Description mismatchDescription) => mismatchDescription +- .add('has unexpected field ') +- .addDescriptionOf(key)); +- } +- }); +- } +- +- /** +- * Check the type of a field called [key], having value [value], using +- * [valueMatcher]. If it doesn't match, record a closure in [mismatches] +- * which can describe the mismatch. +- */ +- void _checkField(String key, value, Matcher valueMatcher, +- List mismatches) { +- checkSubstructure( +- value, +- valueMatcher, +- mismatches, +- (Description description) => +- description.add('field ').addDescriptionOf(key)); +- } +-} +- +-/** +- * Instances of the class [Server] manage a connection to a server process, and +- * facilitate communication to and from the server. +- */ +-class Server { +- /** +- * Server process object, or null if server hasn't been started yet. +- */ +- Process _process; +- +- /** +- * Commands that have been sent to the server but not yet acknowledged, and +- * the [Completer] objects which should be completed when acknowledgement is +- * received. +- */ +- final Map>> _pendingCommands = +- >>{}; +- +- /** +- * Number which should be used to compute the 'id' to send in the next command +- * sent to the server. +- */ +- int _nextId = 0; +- +- /** +- * Messages which have been exchanged with the server; we buffer these +- * up until the test finishes, so that they can be examined in the debugger +- * or printed out in response to a call to [debugStdio]. +- */ +- final List _recordedStdio = []; +- +- /** +- * True if we are currently printing out messages exchanged with the server. +- */ +- bool _debuggingStdio = false; +- +- /** +- * True if we've received bad data from the server, and we are aborting the +- * test. +- */ +- bool _receivedBadDataFromServer = false; +- +- /** +- * Stopwatch that we use to generate timing information for debug output. +- */ +- Stopwatch _time = new Stopwatch(); +- +- /** +- * The [currentElapseTime] at which the last communication was received from the server +- * or `null` if no communication has been received. +- */ +- double lastCommunicationTime; +- +- /** +- * The current elapse time (seconds) since the server was started. +- */ +- double get currentElapseTime => _time.elapsedTicks / _time.frequency; +- +- /** +- * Future that completes when the server process exits. +- */ +- Future get exitCode => _process.exitCode; +- +- /** +- * Print out any messages exchanged with the server. If some messages have +- * already been exchanged with the server, they are printed out immediately. +- */ +- void debugStdio() { +- if (_debuggingStdio) { +- return; +- } +- _debuggingStdio = true; +- for (String line in _recordedStdio) { +- print(line); +- } +- } +- +- /** +- * Find the root directory of the analysis_server package by proceeding +- * upward to the 'test' dir, and then going up one more directory. +- */ +- String findRoot(String pathname) { +- while (!['benchmark', 'test'].contains(basename(pathname))) { +- String parent = dirname(pathname); +- if (parent.length >= pathname.length) { +- throw new Exception("Can't find root directory"); +- } +- pathname = parent; +- } +- return dirname(pathname); +- } +- +- /** +- * Return a future that will complete when all commands that have been sent +- * to the server so far have been flushed to the OS buffer. +- */ +- Future flushCommands() { +- return _process.stdin.flush(); +- } +- +- /** +- * Stop the server. +- */ +- Future kill(String reason) { +- debugStdio(); +- _recordStdio('FORCIBLY TERMINATING PROCESS: $reason'); +- _process.kill(); +- return _process.exitCode; +- } +- +- /** +- * Start listening to output from the server, and deliver notifications to +- * [notificationProcessor]. +- */ +- void listenToOutput(NotificationProcessor notificationProcessor) { +- _process.stdout +- .transform((new Utf8Codec()).decoder) +- .transform(new LineSplitter()) +- .listen((String line) { +- lastCommunicationTime = currentElapseTime; +- String trimmedLine = line.trim(); +- if (trimmedLine.startsWith('Observatory listening on ')) { +- return; +- } +- _recordStdio('RECV: $trimmedLine'); +- var message; +- try { +- message = JSON.decoder.convert(trimmedLine); +- } catch (exception) { +- _badDataFromServer('JSON decode failure: $exception'); +- return; +- } +- outOfTestExpect(message, isMap); +- Map messageAsMap = message; +- if (messageAsMap.containsKey('id')) { +- outOfTestExpect(messageAsMap['id'], isString); +- String id = message['id']; +- Completer> completer = _pendingCommands[id]; +- if (completer == null) { +- fail('Unexpected response from server: id=$id'); +- } else { +- _pendingCommands.remove(id); +- } +- if (messageAsMap.containsKey('error')) { +- completer.completeError(new ServerErrorMessage(messageAsMap)); +- } else { +- completer.complete(messageAsMap['result']); +- } +- // Check that the message is well-formed. We do this after calling +- // completer.complete() or completer.completeError() so that we don't +- // stall the test in the event of an error. +- outOfTestExpect(message, isResponse); +- } else { +- // Message is a notification. It should have an event and possibly +- // params. +- outOfTestExpect(messageAsMap, contains('event')); +- outOfTestExpect(messageAsMap['event'], isString); +- notificationProcessor(messageAsMap['event'], messageAsMap['params']); +- // Check that the message is well-formed. We do this after calling +- // notificationController.add() so that we don't stall the test in the +- // event of an error. +- outOfTestExpect(message, isNotification); +- } +- }); +- _process.stderr +- .transform((new Utf8Codec()).decoder) +- .transform(new LineSplitter()) +- .listen((String line) { +- String trimmedLine = line.trim(); +- _recordStdio('ERR: $trimmedLine'); +- _badDataFromServer('Message received on stderr', silent: true); +- }); +- } +- +- /** +- * Send a command to the server. An 'id' will be automatically assigned. +- * The returned [Future] will be completed when the server acknowledges the +- * command with a response. If the server acknowledges the command with a +- * normal (non-error) response, the future will be completed with the 'result' +- * field from the response. If the server acknowledges the command with an +- * error response, the future will be completed with an error. +- */ +- Future> send( +- String method, Map params) { +- String id = '${_nextId++}'; +- Map command = { +- 'id': id, +- 'method': method +- }; +- if (params != null) { +- command['params'] = params; +- } +- Completer> completer = +- new Completer>(); +- _pendingCommands[id] = completer; +- String line = JSON.encode(command); +- _recordStdio('SEND: $line'); +- _process.stdin.add(UTF8.encoder.convert("$line\n")); +- return completer.future; +- } +- +- /** +- * Start the server. If [profileServer] is `true`, the server will be started +- * with "--observe" and "--pause-isolates-on-exit", allowing the observatory +- * to be used. +- */ +- Future start({ +- bool checked: true, +- int diagnosticPort, +- String instrumentationLogFile, +- bool profileServer: false, +- String sdkPath, +- int servicesPort, +- bool previewDart2: false, +- bool useAnalysisHighlight2: false, +- }) async { +- if (_process != null) { +- throw new Exception('Process already started'); +- } +- _time.start(); +- String dartBinary = Platform.executable; +- String rootDir = +- findRoot(Platform.script.toFilePath(windows: Platform.isWindows)); +- String serverPath = normalize(join(rootDir, 'bin', 'server.dart')); +- List arguments = []; +- // +- // Add VM arguments. +- // +- if (profileServer) { +- if (servicesPort == null) { +- arguments.add('--observe'); +- } else { +- arguments.add('--observe=$servicesPort'); +- } +- arguments.add('--pause-isolates-on-exit'); +- } else if (servicesPort != null) { +- arguments.add('--enable-vm-service=$servicesPort'); +- } +- if (Platform.packageRoot != null) { +- arguments.add('--package-root=${Platform.packageRoot}'); +- } +- if (Platform.packageConfig != null) { +- arguments.add('--packages=${Platform.packageConfig}'); +- } +- if (checked) { +- arguments.add('--checked'); +- } +- // +- // Add the server executable. +- // +- arguments.add(serverPath); +- // +- // Add server arguments. +- // +- arguments.add('--suppress-analytics'); +- if (diagnosticPort != null) { +- arguments.add('--port'); +- arguments.add(diagnosticPort.toString()); +- } +- if (instrumentationLogFile != null) { +- arguments.add('--instrumentation-log-file=$instrumentationLogFile'); +- } +- if (sdkPath != null) { +- arguments.add('--sdk=$sdkPath'); +- } +- if (useAnalysisHighlight2) { +- arguments.add('--useAnalysisHighlight2'); +- } +- if (previewDart2) { +- arguments.add('--preview-dart-2'); +- } +- // TODO(devoncarew): We could experiment with instead launching the analysis +- // server in a separate isolate. This would make it easier to debug the +- // integration tests, and would likely speed up the tests as well. +- _process = await Process.start(dartBinary, arguments); +- _process.exitCode.then((int code) { +- if (code != 0) { +- _badDataFromServer('server terminated with exit code $code'); +- } +- }); +- } +- +- /** +- * Deal with bad data received from the server. +- */ +- void _badDataFromServer(String details, {bool silent: false}) { +- if (!silent) { +- _recordStdio('BAD DATA FROM SERVER: $details'); +- } +- if (_receivedBadDataFromServer) { +- // We're already dealing with it. +- return; +- } +- _receivedBadDataFromServer = true; +- debugStdio(); +- // Give the server 1 second to continue outputting bad data before we kill +- // the test. This is helpful if the server has had an unhandled exception +- // and is outputting a stacktrace, because it ensures that we see the +- // entire stacktrace. Use expectAsync() to prevent the test from +- // ending during this 1 second. +- new Future.delayed(new Duration(seconds: 1), expectAsync0(() { +- fail('Bad data received from server: $details'); +- })); +- } +- +- /** +- * Record a message that was exchanged with the server, and print it out if +- * [debugStdio] has been called. +- */ +- void _recordStdio(String line) { +- double elapsedTime = currentElapseTime; +- line = "$elapsedTime: $line"; +- if (_debuggingStdio) { +- print(line); +- } +- _recordedStdio.add(line); +- } +-} +- +-/** +- * An error result from a server request. +- */ +-class ServerErrorMessage { +- final Map message; +- +- ServerErrorMessage(this.message); +- +- dynamic get error => message['error']; +- +- String toString() => message.toString(); +-} +- +-/** +- * Matcher that matches a list of objects, each of which satisfies the given +- * matcher. +- */ +-class _ListOf extends Matcher { +- /** +- * Matcher which every element of the list must satisfy. +- */ +- final Matcher elementMatcher; +- +- /** +- * Iterable matcher which we use to test the contents of the list. +- */ +- final Matcher iterableMatcher; +- +- _ListOf(elementMatcher) +- : elementMatcher = elementMatcher, +- iterableMatcher = everyElement(elementMatcher); +- +- @override +- Description describe(Description description) => +- description.add('List of ').addDescriptionOf(elementMatcher); +- +- @override +- Description describeMismatch( +- item, Description mismatchDescription, Map matchState, bool verbose) { +- if (item is! List) { +- return super +- .describeMismatch(item, mismatchDescription, matchState, verbose); +- } else { +- return iterableMatcher.describeMismatch( +- item, mismatchDescription, matchState, verbose); +- } +- } +- +- @override +- bool matches(item, Map matchState) { +- if (item is! List) { +- return false; +- } +- return iterableMatcher.matches(item, matchState); +- } +-} +- +-/** +- * Matcher that matches a map of objects, where each key/value pair in the +- * map satisies the given key and value matchers. +- */ +-class _MapOf extends _RecursiveMatcher { +- /** +- * Matcher which every key in the map must satisfy. +- */ +- final Matcher keyMatcher; +- +- /** +- * Matcher which every value in the map must satisfy. +- */ +- final Matcher valueMatcher; +- +- _MapOf(this.keyMatcher, this.valueMatcher); +- +- @override +- Description describe(Description description) => description +- .add('Map from ') +- .addDescriptionOf(keyMatcher) +- .add(' to ') +- .addDescriptionOf(valueMatcher); +- +- @override +- void populateMismatches(item, List mismatches) { +- if (item is! Map) { +- mismatches.add(simpleDescription('is not a map')); +- return; +- } +- item.forEach((key, value) { +- checkSubstructure( +- key, +- keyMatcher, +- mismatches, +- (Description description) => +- description.add('key ').addDescriptionOf(key)); +- checkSubstructure( +- value, +- valueMatcher, +- mismatches, +- (Description description) => +- description.add('field ').addDescriptionOf(key)); +- }); +- } +-} +- +-/** +- * Matcher that matches a union of different types, each of which is described +- * by a matcher. +- */ +-class _OneOf extends Matcher { +- /** +- * Matchers for the individual choices. +- */ +- final List choiceMatchers; +- +- _OneOf(this.choiceMatchers); +- +- @override +- Description describe(Description description) { +- for (int i = 0; i < choiceMatchers.length; i++) { +- if (i != 0) { +- if (choiceMatchers.length == 2) { +- description = description.add(' or '); +- } else { +- description = description.add(', '); +- if (i == choiceMatchers.length - 1) { +- description = description.add('or '); +- } +- } +- } +- description = description.addDescriptionOf(choiceMatchers[i]); +- } +- return description; +- } +- +- @override +- bool matches(item, Map matchState) { +- for (Matcher choiceMatcher in choiceMatchers) { +- Map subState = {}; +- if (choiceMatcher.matches(item, subState)) { +- return true; +- } +- } +- return false; +- } +-} +- +-/** +- * Base class for matchers that operate by recursing through the contents of +- * an object. +- */ +-abstract class _RecursiveMatcher extends Matcher { +- const _RecursiveMatcher(); +- +- /** +- * Check the type of a substructure whose value is [item], using [matcher]. +- * If it doesn't match, record a closure in [mismatches] which can describe +- * the mismatch. [describeSubstructure] is used to describe which +- * substructure did not match. +- */ +- checkSubstructure(item, Matcher matcher, List mismatches, +- Description describeSubstructure(Description description)) { +- Map subState = {}; +- if (!matcher.matches(item, subState)) { +- mismatches.add((Description mismatchDescription) { +- mismatchDescription = mismatchDescription.add('contains malformed '); +- mismatchDescription = describeSubstructure(mismatchDescription); +- mismatchDescription = +- mismatchDescription.add(' (should be ').addDescriptionOf(matcher); +- String subDescription = matcher +- .describeMismatch(item, new StringDescription(), subState, false) +- .toString(); +- if (subDescription.isNotEmpty) { +- mismatchDescription = +- mismatchDescription.add('; ').add(subDescription); +- } +- return mismatchDescription.add(')'); +- }); +- } +- } +- +- @override +- Description describeMismatch( +- item, Description mismatchDescription, Map matchState, bool verbose) { +- List mismatches = +- matchState['mismatches'] as List; +- if (mismatches != null) { +- for (int i = 0; i < mismatches.length; i++) { +- MismatchDescriber mismatch = mismatches[i]; +- if (i > 0) { +- if (mismatches.length == 2) { +- mismatchDescription = mismatchDescription.add(' and '); +- } else if (i == mismatches.length - 1) { +- mismatchDescription = mismatchDescription.add(', and '); +- } else { +- mismatchDescription = mismatchDescription.add(', '); +- } +- } +- mismatchDescription = mismatch(mismatchDescription); +- } +- return mismatchDescription; +- } else { +- return super +- .describeMismatch(item, mismatchDescription, matchState, verbose); +- } +- } +- +- @override +- bool matches(item, Map matchState) { +- List mismatches = []; +- populateMismatches(item, mismatches); +- if (mismatches.isEmpty) { +- return true; +- } else { +- addStateInfo(matchState, {'mismatches': mismatches}); +- return false; +- } +- } +- +- /** +- * Populate [mismatches] with descriptions of all the ways in which [item] +- * does not match. +- */ +- void populateMismatches(item, List mismatches); +- +- /** +- * Create a [MismatchDescriber] describing a mismatch with a simple string. +- */ +- MismatchDescriber simpleDescription(String description) => +- (Description mismatchDescription) { +- mismatchDescription.add(description); +- }; +-} +diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart +deleted file mode 100644 +index 53e4f7c0ae6..00000000000 +--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart ++++ /dev/null +@@ -1,2644 +0,0 @@ +-// 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. +-// +-// This file has been automatically generated. Please do not edit it manually. +-// To regenerate the file, use the script +-// "pkg/analysis_server/tool/spec/generate_files". +- +-/** +- * Matchers for data types defined in the analysis server API +- */ +-import 'package:test/test.dart'; +- +-import 'integration_tests.dart'; +- +-/** +- * AddContentOverlay +- * +- * { +- * "type": "add" +- * "content": String +- * } +- */ +-final Matcher isAddContentOverlay = new LazyMatcher(() => new MatchesJsonObject( +- "AddContentOverlay", {"type": equals("add"), "content": isString})); +- +-/** +- * AnalysisError +- * +- * { +- * "severity": AnalysisErrorSeverity +- * "type": AnalysisErrorType +- * "location": Location +- * "message": String +- * "correction": optional String +- * "code": String +- * "hasFix": optional bool +- * } +- */ +-final Matcher isAnalysisError = +- new LazyMatcher(() => new MatchesJsonObject("AnalysisError", { +- "severity": isAnalysisErrorSeverity, +- "type": isAnalysisErrorType, +- "location": isLocation, +- "message": isString, +- "code": isString +- }, optionalFields: { +- "correction": isString, +- "hasFix": isBool +- })); +- +-/** +- * AnalysisErrorFixes +- * +- * { +- * "error": AnalysisError +- * "fixes": List +- * } +- */ +-final Matcher isAnalysisErrorFixes = new LazyMatcher(() => +- new MatchesJsonObject("AnalysisErrorFixes", +- {"error": isAnalysisError, "fixes": isListOf(isSourceChange)})); +- +-/** +- * AnalysisErrorSeverity +- * +- * enum { +- * INFO +- * WARNING +- * ERROR +- * } +- */ +-final Matcher isAnalysisErrorSeverity = +- new MatchesEnum("AnalysisErrorSeverity", ["INFO", "WARNING", "ERROR"]); +- +-/** +- * AnalysisErrorType +- * +- * enum { +- * CHECKED_MODE_COMPILE_TIME_ERROR +- * COMPILE_TIME_ERROR +- * HINT +- * LINT +- * STATIC_TYPE_WARNING +- * STATIC_WARNING +- * SYNTACTIC_ERROR +- * TODO +- * } +- */ +-final Matcher isAnalysisErrorType = new MatchesEnum("AnalysisErrorType", [ +- "CHECKED_MODE_COMPILE_TIME_ERROR", +- "COMPILE_TIME_ERROR", +- "HINT", +- "LINT", +- "STATIC_TYPE_WARNING", +- "STATIC_WARNING", +- "SYNTACTIC_ERROR", +- "TODO" +-]); +- +-/** +- * AnalysisOptions +- * +- * { +- * "enableAsync": optional bool +- * "enableDeferredLoading": optional bool +- * "enableEnums": optional bool +- * "enableNullAwareOperators": optional bool +- * "enableSuperMixins": optional bool +- * "generateDart2jsHints": optional bool +- * "generateHints": optional bool +- * "generateLints": optional bool +- * } +- */ +-final Matcher isAnalysisOptions = new LazyMatcher( +- () => new MatchesJsonObject("AnalysisOptions", null, optionalFields: { +- "enableAsync": isBool, +- "enableDeferredLoading": isBool, +- "enableEnums": isBool, +- "enableNullAwareOperators": isBool, +- "enableSuperMixins": isBool, +- "generateDart2jsHints": isBool, +- "generateHints": isBool, +- "generateLints": isBool +- })); +- +-/** +- * AnalysisService +- * +- * enum { +- * CLOSING_LABELS +- * FOLDING +- * HIGHLIGHTS +- * IMPLEMENTED +- * INVALIDATE +- * NAVIGATION +- * OCCURRENCES +- * OUTLINE +- * OVERRIDES +- * } +- */ +-final Matcher isAnalysisService = new MatchesEnum("AnalysisService", [ +- "CLOSING_LABELS", +- "FOLDING", +- "HIGHLIGHTS", +- "IMPLEMENTED", +- "INVALIDATE", +- "NAVIGATION", +- "OCCURRENCES", +- "OUTLINE", +- "OVERRIDES" +-]); +- +-/** +- * AnalysisStatus +- * +- * { +- * "isAnalyzing": bool +- * "analysisTarget": optional String +- * } +- */ +-final Matcher isAnalysisStatus = new LazyMatcher(() => new MatchesJsonObject( +- "AnalysisStatus", {"isAnalyzing": isBool}, +- optionalFields: {"analysisTarget": isString})); +- +-/** +- * ChangeContentOverlay +- * +- * { +- * "type": "change" +- * "edits": List +- * } +- */ +-final Matcher isChangeContentOverlay = new LazyMatcher(() => +- new MatchesJsonObject("ChangeContentOverlay", +- {"type": equals("change"), "edits": isListOf(isSourceEdit)})); +- +-/** +- * ClosingLabel +- * +- * { +- * "offset": int +- * "length": int +- * "label": String +- * } +- */ +-final Matcher isClosingLabel = new LazyMatcher(() => new MatchesJsonObject( +- "ClosingLabel", {"offset": isInt, "length": isInt, "label": isString})); +- +-/** +- * CompletionId +- * +- * String +- */ +-final Matcher isCompletionId = isString; +- +-/** +- * CompletionSuggestion +- * +- * { +- * "kind": CompletionSuggestionKind +- * "relevance": int +- * "completion": String +- * "selectionOffset": int +- * "selectionLength": int +- * "isDeprecated": bool +- * "isPotential": bool +- * "docSummary": optional String +- * "docComplete": optional String +- * "declaringType": optional String +- * "defaultArgumentListString": optional String +- * "defaultArgumentListTextRanges": optional List +- * "element": optional Element +- * "returnType": optional String +- * "parameterNames": optional List +- * "parameterTypes": optional List +- * "requiredParameterCount": optional int +- * "hasNamedParameters": optional bool +- * "parameterName": optional String +- * "parameterType": optional String +- * "importUri": optional String +- * } +- */ +-final Matcher isCompletionSuggestion = +- new LazyMatcher(() => new MatchesJsonObject("CompletionSuggestion", { +- "kind": isCompletionSuggestionKind, +- "relevance": isInt, +- "completion": isString, +- "selectionOffset": isInt, +- "selectionLength": isInt, +- "isDeprecated": isBool, +- "isPotential": isBool +- }, optionalFields: { +- "docSummary": isString, +- "docComplete": isString, +- "declaringType": isString, +- "defaultArgumentListString": isString, +- "defaultArgumentListTextRanges": isListOf(isInt), +- "element": isElement, +- "returnType": isString, +- "parameterNames": isListOf(isString), +- "parameterTypes": isListOf(isString), +- "requiredParameterCount": isInt, +- "hasNamedParameters": isBool, +- "parameterName": isString, +- "parameterType": isString, +- "importUri": isString +- })); +- +-/** +- * CompletionSuggestionKind +- * +- * enum { +- * ARGUMENT_LIST +- * IMPORT +- * IDENTIFIER +- * INVOCATION +- * KEYWORD +- * NAMED_ARGUMENT +- * OPTIONAL_ARGUMENT +- * PARAMETER +- * } +- */ +-final Matcher isCompletionSuggestionKind = +- new MatchesEnum("CompletionSuggestionKind", [ +- "ARGUMENT_LIST", +- "IMPORT", +- "IDENTIFIER", +- "INVOCATION", +- "KEYWORD", +- "NAMED_ARGUMENT", +- "OPTIONAL_ARGUMENT", +- "PARAMETER" +-]); +- +-/** +- * ContextData +- * +- * { +- * "name": String +- * "explicitFileCount": int +- * "implicitFileCount": int +- * "workItemQueueLength": int +- * "cacheEntryExceptions": List +- * } +- */ +-final Matcher isContextData = +- new LazyMatcher(() => new MatchesJsonObject("ContextData", { +- "name": isString, +- "explicitFileCount": isInt, +- "implicitFileCount": isInt, +- "workItemQueueLength": isInt, +- "cacheEntryExceptions": isListOf(isString) +- })); +- +-/** +- * Element +- * +- * { +- * "kind": ElementKind +- * "name": String +- * "location": optional Location +- * "flags": int +- * "parameters": optional String +- * "returnType": optional String +- * "typeParameters": optional String +- * } +- */ +-final Matcher isElement = +- new LazyMatcher(() => new MatchesJsonObject("Element", { +- "kind": isElementKind, +- "name": isString, +- "flags": isInt +- }, optionalFields: { +- "location": isLocation, +- "parameters": isString, +- "returnType": isString, +- "typeParameters": isString +- })); +- +-/** +- * ElementKind +- * +- * enum { +- * CLASS +- * CLASS_TYPE_ALIAS +- * COMPILATION_UNIT +- * CONSTRUCTOR +- * CONSTRUCTOR_INVOCATION +- * ENUM +- * ENUM_CONSTANT +- * FIELD +- * FILE +- * FUNCTION +- * FUNCTION_INVOCATION +- * FUNCTION_TYPE_ALIAS +- * GETTER +- * LABEL +- * LIBRARY +- * LOCAL_VARIABLE +- * METHOD +- * PARAMETER +- * PREFIX +- * SETTER +- * TOP_LEVEL_VARIABLE +- * TYPE_PARAMETER +- * UNIT_TEST_GROUP +- * UNIT_TEST_TEST +- * UNKNOWN +- * } +- */ +-final Matcher isElementKind = new MatchesEnum("ElementKind", [ +- "CLASS", +- "CLASS_TYPE_ALIAS", +- "COMPILATION_UNIT", +- "CONSTRUCTOR", +- "CONSTRUCTOR_INVOCATION", +- "ENUM", +- "ENUM_CONSTANT", +- "FIELD", +- "FILE", +- "FUNCTION", +- "FUNCTION_INVOCATION", +- "FUNCTION_TYPE_ALIAS", +- "GETTER", +- "LABEL", +- "LIBRARY", +- "LOCAL_VARIABLE", +- "METHOD", +- "PARAMETER", +- "PREFIX", +- "SETTER", +- "TOP_LEVEL_VARIABLE", +- "TYPE_PARAMETER", +- "UNIT_TEST_GROUP", +- "UNIT_TEST_TEST", +- "UNKNOWN" +-]); +- +-/** +- * ExecutableFile +- * +- * { +- * "file": FilePath +- * "kind": ExecutableKind +- * } +- */ +-final Matcher isExecutableFile = new LazyMatcher(() => new MatchesJsonObject( +- "ExecutableFile", {"file": isFilePath, "kind": isExecutableKind})); +- +-/** +- * ExecutableKind +- * +- * enum { +- * CLIENT +- * EITHER +- * NOT_EXECUTABLE +- * SERVER +- * } +- */ +-final Matcher isExecutableKind = new MatchesEnum( +- "ExecutableKind", ["CLIENT", "EITHER", "NOT_EXECUTABLE", "SERVER"]); +- +-/** +- * ExecutionContextId +- * +- * String +- */ +-final Matcher isExecutionContextId = isString; +- +-/** +- * ExecutionService +- * +- * enum { +- * LAUNCH_DATA +- * } +- */ +-final Matcher isExecutionService = +- new MatchesEnum("ExecutionService", ["LAUNCH_DATA"]); +- +-/** +- * FileKind +- * +- * enum { +- * LIBRARY +- * PART +- * } +- */ +-final Matcher isFileKind = new MatchesEnum("FileKind", ["LIBRARY", "PART"]); +- +-/** +- * FilePath +- * +- * String +- */ +-final Matcher isFilePath = isString; +- +-/** +- * FoldingKind +- * +- * enum { +- * COMMENT +- * CLASS_MEMBER +- * DIRECTIVES +- * DOCUMENTATION_COMMENT +- * TOP_LEVEL_DECLARATION +- * } +- */ +-final Matcher isFoldingKind = new MatchesEnum("FoldingKind", [ +- "COMMENT", +- "CLASS_MEMBER", +- "DIRECTIVES", +- "DOCUMENTATION_COMMENT", +- "TOP_LEVEL_DECLARATION" +-]); +- +-/** +- * FoldingRegion +- * +- * { +- * "kind": FoldingKind +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isFoldingRegion = new LazyMatcher(() => new MatchesJsonObject( +- "FoldingRegion", +- {"kind": isFoldingKind, "offset": isInt, "length": isInt})); +- +-/** +- * GeneralAnalysisService +- * +- * enum { +- * ANALYZED_FILES +- * } +- */ +-final Matcher isGeneralAnalysisService = +- new MatchesEnum("GeneralAnalysisService", ["ANALYZED_FILES"]); +- +-/** +- * HighlightRegion +- * +- * { +- * "type": HighlightRegionType +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isHighlightRegion = new LazyMatcher(() => new MatchesJsonObject( +- "HighlightRegion", +- {"type": isHighlightRegionType, "offset": isInt, "length": isInt})); +- +-/** +- * HighlightRegionType +- * +- * enum { +- * ANNOTATION +- * BUILT_IN +- * CLASS +- * COMMENT_BLOCK +- * COMMENT_DOCUMENTATION +- * COMMENT_END_OF_LINE +- * CONSTRUCTOR +- * DIRECTIVE +- * DYNAMIC_TYPE +- * DYNAMIC_LOCAL_VARIABLE_DECLARATION +- * DYNAMIC_LOCAL_VARIABLE_REFERENCE +- * DYNAMIC_PARAMETER_DECLARATION +- * DYNAMIC_PARAMETER_REFERENCE +- * ENUM +- * ENUM_CONSTANT +- * FIELD +- * FIELD_STATIC +- * FUNCTION +- * FUNCTION_DECLARATION +- * FUNCTION_TYPE_ALIAS +- * GETTER_DECLARATION +- * IDENTIFIER_DEFAULT +- * IMPORT_PREFIX +- * INSTANCE_FIELD_DECLARATION +- * INSTANCE_FIELD_REFERENCE +- * INSTANCE_GETTER_DECLARATION +- * INSTANCE_GETTER_REFERENCE +- * INSTANCE_METHOD_DECLARATION +- * INSTANCE_METHOD_REFERENCE +- * INSTANCE_SETTER_DECLARATION +- * INSTANCE_SETTER_REFERENCE +- * INVALID_STRING_ESCAPE +- * KEYWORD +- * LABEL +- * LIBRARY_NAME +- * LITERAL_BOOLEAN +- * LITERAL_DOUBLE +- * LITERAL_INTEGER +- * LITERAL_LIST +- * LITERAL_MAP +- * LITERAL_STRING +- * LOCAL_FUNCTION_DECLARATION +- * LOCAL_FUNCTION_REFERENCE +- * LOCAL_VARIABLE +- * LOCAL_VARIABLE_DECLARATION +- * LOCAL_VARIABLE_REFERENCE +- * METHOD +- * METHOD_DECLARATION +- * METHOD_DECLARATION_STATIC +- * METHOD_STATIC +- * PARAMETER +- * SETTER_DECLARATION +- * TOP_LEVEL_VARIABLE +- * PARAMETER_DECLARATION +- * PARAMETER_REFERENCE +- * STATIC_FIELD_DECLARATION +- * STATIC_GETTER_DECLARATION +- * STATIC_GETTER_REFERENCE +- * STATIC_METHOD_DECLARATION +- * STATIC_METHOD_REFERENCE +- * STATIC_SETTER_DECLARATION +- * STATIC_SETTER_REFERENCE +- * TOP_LEVEL_FUNCTION_DECLARATION +- * TOP_LEVEL_FUNCTION_REFERENCE +- * TOP_LEVEL_GETTER_DECLARATION +- * TOP_LEVEL_GETTER_REFERENCE +- * TOP_LEVEL_SETTER_DECLARATION +- * TOP_LEVEL_SETTER_REFERENCE +- * TOP_LEVEL_VARIABLE_DECLARATION +- * TYPE_NAME_DYNAMIC +- * TYPE_PARAMETER +- * UNRESOLVED_INSTANCE_MEMBER_REFERENCE +- * VALID_STRING_ESCAPE +- * } +- */ +-final Matcher isHighlightRegionType = new MatchesEnum("HighlightRegionType", [ +- "ANNOTATION", +- "BUILT_IN", +- "CLASS", +- "COMMENT_BLOCK", +- "COMMENT_DOCUMENTATION", +- "COMMENT_END_OF_LINE", +- "CONSTRUCTOR", +- "DIRECTIVE", +- "DYNAMIC_TYPE", +- "DYNAMIC_LOCAL_VARIABLE_DECLARATION", +- "DYNAMIC_LOCAL_VARIABLE_REFERENCE", +- "DYNAMIC_PARAMETER_DECLARATION", +- "DYNAMIC_PARAMETER_REFERENCE", +- "ENUM", +- "ENUM_CONSTANT", +- "FIELD", +- "FIELD_STATIC", +- "FUNCTION", +- "FUNCTION_DECLARATION", +- "FUNCTION_TYPE_ALIAS", +- "GETTER_DECLARATION", +- "IDENTIFIER_DEFAULT", +- "IMPORT_PREFIX", +- "INSTANCE_FIELD_DECLARATION", +- "INSTANCE_FIELD_REFERENCE", +- "INSTANCE_GETTER_DECLARATION", +- "INSTANCE_GETTER_REFERENCE", +- "INSTANCE_METHOD_DECLARATION", +- "INSTANCE_METHOD_REFERENCE", +- "INSTANCE_SETTER_DECLARATION", +- "INSTANCE_SETTER_REFERENCE", +- "INVALID_STRING_ESCAPE", +- "KEYWORD", +- "LABEL", +- "LIBRARY_NAME", +- "LITERAL_BOOLEAN", +- "LITERAL_DOUBLE", +- "LITERAL_INTEGER", +- "LITERAL_LIST", +- "LITERAL_MAP", +- "LITERAL_STRING", +- "LOCAL_FUNCTION_DECLARATION", +- "LOCAL_FUNCTION_REFERENCE", +- "LOCAL_VARIABLE", +- "LOCAL_VARIABLE_DECLARATION", +- "LOCAL_VARIABLE_REFERENCE", +- "METHOD", +- "METHOD_DECLARATION", +- "METHOD_DECLARATION_STATIC", +- "METHOD_STATIC", +- "PARAMETER", +- "SETTER_DECLARATION", +- "TOP_LEVEL_VARIABLE", +- "PARAMETER_DECLARATION", +- "PARAMETER_REFERENCE", +- "STATIC_FIELD_DECLARATION", +- "STATIC_GETTER_DECLARATION", +- "STATIC_GETTER_REFERENCE", +- "STATIC_METHOD_DECLARATION", +- "STATIC_METHOD_REFERENCE", +- "STATIC_SETTER_DECLARATION", +- "STATIC_SETTER_REFERENCE", +- "TOP_LEVEL_FUNCTION_DECLARATION", +- "TOP_LEVEL_FUNCTION_REFERENCE", +- "TOP_LEVEL_GETTER_DECLARATION", +- "TOP_LEVEL_GETTER_REFERENCE", +- "TOP_LEVEL_SETTER_DECLARATION", +- "TOP_LEVEL_SETTER_REFERENCE", +- "TOP_LEVEL_VARIABLE_DECLARATION", +- "TYPE_NAME_DYNAMIC", +- "TYPE_PARAMETER", +- "UNRESOLVED_INSTANCE_MEMBER_REFERENCE", +- "VALID_STRING_ESCAPE" +-]); +- +-/** +- * HoverInformation +- * +- * { +- * "offset": int +- * "length": int +- * "containingLibraryPath": optional String +- * "containingLibraryName": optional String +- * "containingClassDescription": optional String +- * "dartdoc": optional String +- * "elementDescription": optional String +- * "elementKind": optional String +- * "isDeprecated": optional bool +- * "parameter": optional String +- * "propagatedType": optional String +- * "staticType": optional String +- * } +- */ +-final Matcher isHoverInformation = +- new LazyMatcher(() => new MatchesJsonObject("HoverInformation", { +- "offset": isInt, +- "length": isInt +- }, optionalFields: { +- "containingLibraryPath": isString, +- "containingLibraryName": isString, +- "containingClassDescription": isString, +- "dartdoc": isString, +- "elementDescription": isString, +- "elementKind": isString, +- "isDeprecated": isBool, +- "parameter": isString, +- "propagatedType": isString, +- "staticType": isString +- })); +- +-/** +- * ImplementedClass +- * +- * { +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isImplementedClass = new LazyMatcher(() => new MatchesJsonObject( +- "ImplementedClass", {"offset": isInt, "length": isInt})); +- +-/** +- * ImplementedMember +- * +- * { +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isImplementedMember = new LazyMatcher(() => new MatchesJsonObject( +- "ImplementedMember", {"offset": isInt, "length": isInt})); +- +-/** +- * ImportedElements +- * +- * { +- * "path": FilePath +- * "prefix": String +- * "elements": List +- * } +- */ +-final Matcher isImportedElements = new LazyMatcher(() => new MatchesJsonObject( +- "ImportedElements", +- {"path": isFilePath, "prefix": isString, "elements": isListOf(isString)})); +- +-/** +- * KytheEntry +- * +- * { +- * "source": KytheVName +- * "kind": optional String +- * "target": optional KytheVName +- * "fact": String +- * "value": optional List +- * } +- */ +-final Matcher isKytheEntry = new LazyMatcher(() => new MatchesJsonObject( +- "KytheEntry", { +- "source": isKytheVName, +- "fact": isString +- }, optionalFields: { +- "kind": isString, +- "target": isKytheVName, +- "value": isListOf(isInt) +- })); +- +-/** +- * KytheVName +- * +- * { +- * "signature": String +- * "corpus": String +- * "root": String +- * "path": String +- * "language": String +- * } +- */ +-final Matcher isKytheVName = +- new LazyMatcher(() => new MatchesJsonObject("KytheVName", { +- "signature": isString, +- "corpus": isString, +- "root": isString, +- "path": isString, +- "language": isString +- })); +- +-/** +- * LinkedEditGroup +- * +- * { +- * "positions": List +- * "length": int +- * "suggestions": List +- * } +- */ +-final Matcher isLinkedEditGroup = +- new LazyMatcher(() => new MatchesJsonObject("LinkedEditGroup", { +- "positions": isListOf(isPosition), +- "length": isInt, +- "suggestions": isListOf(isLinkedEditSuggestion) +- })); +- +-/** +- * LinkedEditSuggestion +- * +- * { +- * "value": String +- * "kind": LinkedEditSuggestionKind +- * } +- */ +-final Matcher isLinkedEditSuggestion = new LazyMatcher(() => +- new MatchesJsonObject("LinkedEditSuggestion", +- {"value": isString, "kind": isLinkedEditSuggestionKind})); +- +-/** +- * LinkedEditSuggestionKind +- * +- * enum { +- * METHOD +- * PARAMETER +- * TYPE +- * VARIABLE +- * } +- */ +-final Matcher isLinkedEditSuggestionKind = new MatchesEnum( +- "LinkedEditSuggestionKind", ["METHOD", "PARAMETER", "TYPE", "VARIABLE"]); +- +-/** +- * Location +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * "startLine": int +- * "startColumn": int +- * } +- */ +-final Matcher isLocation = +- new LazyMatcher(() => new MatchesJsonObject("Location", { +- "file": isFilePath, +- "offset": isInt, +- "length": isInt, +- "startLine": isInt, +- "startColumn": isInt +- })); +- +-/** +- * NavigationRegion +- * +- * { +- * "offset": int +- * "length": int +- * "targets": List +- * } +- */ +-final Matcher isNavigationRegion = new LazyMatcher(() => new MatchesJsonObject( +- "NavigationRegion", +- {"offset": isInt, "length": isInt, "targets": isListOf(isInt)})); +- +-/** +- * NavigationTarget +- * +- * { +- * "kind": ElementKind +- * "fileIndex": int +- * "offset": int +- * "length": int +- * "startLine": int +- * "startColumn": int +- * } +- */ +-final Matcher isNavigationTarget = +- new LazyMatcher(() => new MatchesJsonObject("NavigationTarget", { +- "kind": isElementKind, +- "fileIndex": isInt, +- "offset": isInt, +- "length": isInt, +- "startLine": isInt, +- "startColumn": isInt +- })); +- +-/** +- * Occurrences +- * +- * { +- * "element": Element +- * "offsets": List +- * "length": int +- * } +- */ +-final Matcher isOccurrences = new LazyMatcher(() => new MatchesJsonObject( +- "Occurrences", +- {"element": isElement, "offsets": isListOf(isInt), "length": isInt})); +- +-/** +- * Outline +- * +- * { +- * "element": Element +- * "offset": int +- * "length": int +- * "children": optional List +- * } +- */ +-final Matcher isOutline = new LazyMatcher(() => new MatchesJsonObject( +- "Outline", {"element": isElement, "offset": isInt, "length": isInt}, +- optionalFields: {"children": isListOf(isOutline)})); +- +-/** +- * OverriddenMember +- * +- * { +- * "element": Element +- * "className": String +- * } +- */ +-final Matcher isOverriddenMember = new LazyMatcher(() => new MatchesJsonObject( +- "OverriddenMember", {"element": isElement, "className": isString})); +- +-/** +- * Override +- * +- * { +- * "offset": int +- * "length": int +- * "superclassMember": optional OverriddenMember +- * "interfaceMembers": optional List +- * } +- */ +-final Matcher isOverride = +- new LazyMatcher(() => new MatchesJsonObject("Override", { +- "offset": isInt, +- "length": isInt +- }, optionalFields: { +- "superclassMember": isOverriddenMember, +- "interfaceMembers": isListOf(isOverriddenMember) +- })); +- +-/** +- * Position +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- */ +-final Matcher isPosition = new LazyMatcher(() => +- new MatchesJsonObject("Position", {"file": isFilePath, "offset": isInt})); +- +-/** +- * PostfixTemplateDescriptor +- * +- * { +- * "name": String +- * "key": String +- * "example": String +- * } +- */ +-final Matcher isPostfixTemplateDescriptor = new LazyMatcher(() => +- new MatchesJsonObject("PostfixTemplateDescriptor", +- {"name": isString, "key": isString, "example": isString})); +- +-/** +- * PubStatus +- * +- * { +- * "isListingPackageDirs": bool +- * } +- */ +-final Matcher isPubStatus = new LazyMatcher( +- () => new MatchesJsonObject("PubStatus", {"isListingPackageDirs": isBool})); +- +-/** +- * RefactoringFeedback +- * +- * { +- * } +- */ +-final Matcher isRefactoringFeedback = +- new LazyMatcher(() => new MatchesJsonObject("RefactoringFeedback", null)); +- +-/** +- * RefactoringKind +- * +- * enum { +- * CONVERT_GETTER_TO_METHOD +- * CONVERT_METHOD_TO_GETTER +- * EXTRACT_LOCAL_VARIABLE +- * EXTRACT_METHOD +- * INLINE_LOCAL_VARIABLE +- * INLINE_METHOD +- * MOVE_FILE +- * RENAME +- * SORT_MEMBERS +- * } +- */ +-final Matcher isRefactoringKind = new MatchesEnum("RefactoringKind", [ +- "CONVERT_GETTER_TO_METHOD", +- "CONVERT_METHOD_TO_GETTER", +- "EXTRACT_LOCAL_VARIABLE", +- "EXTRACT_METHOD", +- "INLINE_LOCAL_VARIABLE", +- "INLINE_METHOD", +- "MOVE_FILE", +- "RENAME", +- "SORT_MEMBERS" +-]); +- +-/** +- * RefactoringMethodParameter +- * +- * { +- * "id": optional String +- * "kind": RefactoringMethodParameterKind +- * "type": String +- * "name": String +- * "parameters": optional String +- * } +- */ +-final Matcher isRefactoringMethodParameter = new LazyMatcher(() => +- new MatchesJsonObject("RefactoringMethodParameter", { +- "kind": isRefactoringMethodParameterKind, +- "type": isString, +- "name": isString +- }, optionalFields: { +- "id": isString, +- "parameters": isString +- })); +- +-/** +- * RefactoringMethodParameterKind +- * +- * enum { +- * REQUIRED +- * POSITIONAL +- * NAMED +- * } +- */ +-final Matcher isRefactoringMethodParameterKind = new MatchesEnum( +- "RefactoringMethodParameterKind", ["REQUIRED", "POSITIONAL", "NAMED"]); +- +-/** +- * RefactoringOptions +- * +- * { +- * } +- */ +-final Matcher isRefactoringOptions = +- new LazyMatcher(() => new MatchesJsonObject("RefactoringOptions", null)); +- +-/** +- * RefactoringProblem +- * +- * { +- * "severity": RefactoringProblemSeverity +- * "message": String +- * "location": optional Location +- * } +- */ +-final Matcher isRefactoringProblem = new LazyMatcher(() => +- new MatchesJsonObject("RefactoringProblem", +- {"severity": isRefactoringProblemSeverity, "message": isString}, +- optionalFields: {"location": isLocation})); +- +-/** +- * RefactoringProblemSeverity +- * +- * enum { +- * INFO +- * WARNING +- * ERROR +- * FATAL +- * } +- */ +-final Matcher isRefactoringProblemSeverity = new MatchesEnum( +- "RefactoringProblemSeverity", ["INFO", "WARNING", "ERROR", "FATAL"]); +- +-/** +- * RemoveContentOverlay +- * +- * { +- * "type": "remove" +- * } +- */ +-final Matcher isRemoveContentOverlay = new LazyMatcher(() => +- new MatchesJsonObject("RemoveContentOverlay", {"type": equals("remove")})); +- +-/** +- * RequestError +- * +- * { +- * "code": RequestErrorCode +- * "message": String +- * "stackTrace": optional String +- * } +- */ +-final Matcher isRequestError = new LazyMatcher(() => new MatchesJsonObject( +- "RequestError", {"code": isRequestErrorCode, "message": isString}, +- optionalFields: {"stackTrace": isString})); +- +-/** +- * RequestErrorCode +- * +- * enum { +- * CONTENT_MODIFIED +- * DEBUG_PORT_COULD_NOT_BE_OPENED +- * FILE_NOT_ANALYZED +- * FORMAT_INVALID_FILE +- * FORMAT_WITH_ERRORS +- * GET_ERRORS_INVALID_FILE +- * GET_IMPORTED_ELEMENTS_INVALID_FILE +- * GET_KYTHE_ENTRIES_INVALID_FILE +- * GET_NAVIGATION_INVALID_FILE +- * GET_REACHABLE_SOURCES_INVALID_FILE +- * IMPORT_ELEMENTS_INVALID_FILE +- * INVALID_ANALYSIS_ROOT +- * INVALID_EXECUTION_CONTEXT +- * INVALID_FILE_PATH_FORMAT +- * INVALID_OVERLAY_CHANGE +- * INVALID_PARAMETER +- * INVALID_REQUEST +- * ORGANIZE_DIRECTIVES_ERROR +- * REFACTORING_REQUEST_CANCELLED +- * SERVER_ALREADY_STARTED +- * SERVER_ERROR +- * SORT_MEMBERS_INVALID_FILE +- * SORT_MEMBERS_PARSE_ERRORS +- * UNANALYZED_PRIORITY_FILES +- * UNKNOWN_REQUEST +- * UNKNOWN_SOURCE +- * UNSUPPORTED_FEATURE +- * } +- */ +-final Matcher isRequestErrorCode = new MatchesEnum("RequestErrorCode", [ +- "CONTENT_MODIFIED", +- "DEBUG_PORT_COULD_NOT_BE_OPENED", +- "FILE_NOT_ANALYZED", +- "FORMAT_INVALID_FILE", +- "FORMAT_WITH_ERRORS", +- "GET_ERRORS_INVALID_FILE", +- "GET_IMPORTED_ELEMENTS_INVALID_FILE", +- "GET_KYTHE_ENTRIES_INVALID_FILE", +- "GET_NAVIGATION_INVALID_FILE", +- "GET_REACHABLE_SOURCES_INVALID_FILE", +- "IMPORT_ELEMENTS_INVALID_FILE", +- "INVALID_ANALYSIS_ROOT", +- "INVALID_EXECUTION_CONTEXT", +- "INVALID_FILE_PATH_FORMAT", +- "INVALID_OVERLAY_CHANGE", +- "INVALID_PARAMETER", +- "INVALID_REQUEST", +- "ORGANIZE_DIRECTIVES_ERROR", +- "REFACTORING_REQUEST_CANCELLED", +- "SERVER_ALREADY_STARTED", +- "SERVER_ERROR", +- "SORT_MEMBERS_INVALID_FILE", +- "SORT_MEMBERS_PARSE_ERRORS", +- "UNANALYZED_PRIORITY_FILES", +- "UNKNOWN_REQUEST", +- "UNKNOWN_SOURCE", +- "UNSUPPORTED_FEATURE" +-]); +- +-/** +- * SearchId +- * +- * String +- */ +-final Matcher isSearchId = isString; +- +-/** +- * SearchResult +- * +- * { +- * "location": Location +- * "kind": SearchResultKind +- * "isPotential": bool +- * "path": List +- * } +- */ +-final Matcher isSearchResult = +- new LazyMatcher(() => new MatchesJsonObject("SearchResult", { +- "location": isLocation, +- "kind": isSearchResultKind, +- "isPotential": isBool, +- "path": isListOf(isElement) +- })); +- +-/** +- * SearchResultKind +- * +- * enum { +- * DECLARATION +- * INVOCATION +- * READ +- * READ_WRITE +- * REFERENCE +- * UNKNOWN +- * WRITE +- * } +- */ +-final Matcher isSearchResultKind = new MatchesEnum("SearchResultKind", [ +- "DECLARATION", +- "INVOCATION", +- "READ", +- "READ_WRITE", +- "REFERENCE", +- "UNKNOWN", +- "WRITE" +-]); +- +-/** +- * ServerService +- * +- * enum { +- * STATUS +- * } +- */ +-final Matcher isServerService = new MatchesEnum("ServerService", ["STATUS"]); +- +-/** +- * SourceChange +- * +- * { +- * "message": String +- * "edits": List +- * "linkedEditGroups": List +- * "selection": optional Position +- * } +- */ +-final Matcher isSourceChange = +- new LazyMatcher(() => new MatchesJsonObject("SourceChange", { +- "message": isString, +- "edits": isListOf(isSourceFileEdit), +- "linkedEditGroups": isListOf(isLinkedEditGroup) +- }, optionalFields: { +- "selection": isPosition +- })); +- +-/** +- * SourceEdit +- * +- * { +- * "offset": int +- * "length": int +- * "replacement": String +- * "id": optional String +- * } +- */ +-final Matcher isSourceEdit = new LazyMatcher(() => new MatchesJsonObject( +- "SourceEdit", {"offset": isInt, "length": isInt, "replacement": isString}, +- optionalFields: {"id": isString})); +- +-/** +- * SourceFileEdit +- * +- * { +- * "file": FilePath +- * "fileStamp": long +- * "edits": List +- * } +- */ +-final Matcher isSourceFileEdit = new LazyMatcher(() => new MatchesJsonObject( +- "SourceFileEdit", +- {"file": isFilePath, "fileStamp": isInt, "edits": isListOf(isSourceEdit)})); +- +-/** +- * TypeHierarchyItem +- * +- * { +- * "classElement": Element +- * "displayName": optional String +- * "memberElement": optional Element +- * "superclass": optional int +- * "interfaces": List +- * "mixins": List +- * "subclasses": List +- * } +- */ +-final Matcher isTypeHierarchyItem = +- new LazyMatcher(() => new MatchesJsonObject("TypeHierarchyItem", { +- "classElement": isElement, +- "interfaces": isListOf(isInt), +- "mixins": isListOf(isInt), +- "subclasses": isListOf(isInt) +- }, optionalFields: { +- "displayName": isString, +- "memberElement": isElement, +- "superclass": isInt +- })); +- +-/** +- * analysis.analyzedFiles params +- * +- * { +- * "directories": List +- * } +- */ +-final Matcher isAnalysisAnalyzedFilesParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.analyzedFiles params", +- {"directories": isListOf(isFilePath)})); +- +-/** +- * analysis.closingLabels params +- * +- * { +- * "file": FilePath +- * "labels": List +- * } +- */ +-final Matcher isAnalysisClosingLabelsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.closingLabels params", +- {"file": isFilePath, "labels": isListOf(isClosingLabel)})); +- +-/** +- * analysis.errors params +- * +- * { +- * "file": FilePath +- * "errors": List +- * } +- */ +-final Matcher isAnalysisErrorsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.errors params", +- {"file": isFilePath, "errors": isListOf(isAnalysisError)})); +- +-/** +- * analysis.flushResults params +- * +- * { +- * "files": List +- * } +- */ +-final Matcher isAnalysisFlushResultsParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.flushResults params", {"files": isListOf(isFilePath)})); +- +-/** +- * analysis.folding params +- * +- * { +- * "file": FilePath +- * "regions": List +- * } +- */ +-final Matcher isAnalysisFoldingParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.folding params", +- {"file": isFilePath, "regions": isListOf(isFoldingRegion)})); +- +-/** +- * analysis.getErrors params +- * +- * { +- * "file": FilePath +- * } +- */ +-final Matcher isAnalysisGetErrorsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.getErrors params", {"file": isFilePath})); +- +-/** +- * analysis.getErrors result +- * +- * { +- * "errors": List +- * } +- */ +-final Matcher isAnalysisGetErrorsResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.getErrors result", {"errors": isListOf(isAnalysisError)})); +- +-/** +- * analysis.getHover params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- */ +-final Matcher isAnalysisGetHoverParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.getHover params", {"file": isFilePath, "offset": isInt})); +- +-/** +- * analysis.getHover result +- * +- * { +- * "hovers": List +- * } +- */ +-final Matcher isAnalysisGetHoverResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.getHover result", {"hovers": isListOf(isHoverInformation)})); +- +-/** +- * analysis.getImportedElements params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isAnalysisGetImportedElementsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.getImportedElements params", +- {"file": isFilePath, "offset": isInt, "length": isInt})); +- +-/** +- * analysis.getImportedElements result +- * +- * { +- * "elements": List +- * } +- */ +-final Matcher isAnalysisGetImportedElementsResult = new LazyMatcher(() => +- new MatchesJsonObject("analysis.getImportedElements result", +- {"elements": isListOf(isImportedElements)})); +- +-/** +- * analysis.getLibraryDependencies params +- */ +-final Matcher isAnalysisGetLibraryDependenciesParams = isNull; +- +-/** +- * analysis.getLibraryDependencies result +- * +- * { +- * "libraries": List +- * "packageMap": Map>> +- * } +- */ +-final Matcher isAnalysisGetLibraryDependenciesResult = new LazyMatcher( +- () => new MatchesJsonObject("analysis.getLibraryDependencies result", { +- "libraries": isListOf(isFilePath), +- "packageMap": +- isMapOf(isString, isMapOf(isString, isListOf(isFilePath))) +- })); +- +-/** +- * analysis.getNavigation params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isAnalysisGetNavigationParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.getNavigation params", +- {"file": isFilePath, "offset": isInt, "length": isInt})); +- +-/** +- * analysis.getNavigation result +- * +- * { +- * "files": List +- * "targets": List +- * "regions": List +- * } +- */ +-final Matcher isAnalysisGetNavigationResult = new LazyMatcher( +- () => new MatchesJsonObject("analysis.getNavigation result", { +- "files": isListOf(isFilePath), +- "targets": isListOf(isNavigationTarget), +- "regions": isListOf(isNavigationRegion) +- })); +- +-/** +- * analysis.getReachableSources params +- * +- * { +- * "file": FilePath +- * } +- */ +-final Matcher isAnalysisGetReachableSourcesParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.getReachableSources params", {"file": isFilePath})); +- +-/** +- * analysis.getReachableSources result +- * +- * { +- * "sources": Map> +- * } +- */ +-final Matcher isAnalysisGetReachableSourcesResult = new LazyMatcher(() => +- new MatchesJsonObject("analysis.getReachableSources result", +- {"sources": isMapOf(isString, isListOf(isString))})); +- +-/** +- * analysis.highlights params +- * +- * { +- * "file": FilePath +- * "regions": List +- * } +- */ +-final Matcher isAnalysisHighlightsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.highlights params", +- {"file": isFilePath, "regions": isListOf(isHighlightRegion)})); +- +-/** +- * analysis.implemented params +- * +- * { +- * "file": FilePath +- * "classes": List +- * "members": List +- * } +- */ +-final Matcher isAnalysisImplementedParams = +- new LazyMatcher(() => new MatchesJsonObject("analysis.implemented params", { +- "file": isFilePath, +- "classes": isListOf(isImplementedClass), +- "members": isListOf(isImplementedMember) +- })); +- +-/** +- * analysis.invalidate params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * "delta": int +- * } +- */ +-final Matcher isAnalysisInvalidateParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.invalidate params", { +- "file": isFilePath, +- "offset": isInt, +- "length": isInt, +- "delta": isInt +- })); +- +-/** +- * analysis.navigation params +- * +- * { +- * "file": FilePath +- * "regions": List +- * "targets": List +- * "files": List +- * } +- */ +-final Matcher isAnalysisNavigationParams = +- new LazyMatcher(() => new MatchesJsonObject("analysis.navigation params", { +- "file": isFilePath, +- "regions": isListOf(isNavigationRegion), +- "targets": isListOf(isNavigationTarget), +- "files": isListOf(isFilePath) +- })); +- +-/** +- * analysis.occurrences params +- * +- * { +- * "file": FilePath +- * "occurrences": List +- * } +- */ +-final Matcher isAnalysisOccurrencesParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.occurrences params", +- {"file": isFilePath, "occurrences": isListOf(isOccurrences)})); +- +-/** +- * analysis.outline params +- * +- * { +- * "file": FilePath +- * "kind": FileKind +- * "libraryName": optional String +- * "outline": Outline +- * } +- */ +-final Matcher isAnalysisOutlineParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.outline params", +- {"file": isFilePath, "kind": isFileKind, "outline": isOutline}, +- optionalFields: {"libraryName": isString})); +- +-/** +- * analysis.overrides params +- * +- * { +- * "file": FilePath +- * "overrides": List +- * } +- */ +-final Matcher isAnalysisOverridesParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.overrides params", +- {"file": isFilePath, "overrides": isListOf(isOverride)})); +- +-/** +- * analysis.reanalyze params +- * +- * { +- * "roots": optional List +- * } +- */ +-final Matcher isAnalysisReanalyzeParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.reanalyze params", null, +- optionalFields: {"roots": isListOf(isFilePath)})); +- +-/** +- * analysis.reanalyze result +- */ +-final Matcher isAnalysisReanalyzeResult = isNull; +- +-/** +- * analysis.setAnalysisRoots params +- * +- * { +- * "included": List +- * "excluded": List +- * "packageRoots": optional Map +- * } +- */ +-final Matcher isAnalysisSetAnalysisRootsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.setAnalysisRoots params", +- {"included": isListOf(isFilePath), "excluded": isListOf(isFilePath)}, +- optionalFields: {"packageRoots": isMapOf(isFilePath, isFilePath)})); +- +-/** +- * analysis.setAnalysisRoots result +- */ +-final Matcher isAnalysisSetAnalysisRootsResult = isNull; +- +-/** +- * analysis.setGeneralSubscriptions params +- * +- * { +- * "subscriptions": List +- * } +- */ +-final Matcher isAnalysisSetGeneralSubscriptionsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.setGeneralSubscriptions params", +- {"subscriptions": isListOf(isGeneralAnalysisService)})); +- +-/** +- * analysis.setGeneralSubscriptions result +- */ +-final Matcher isAnalysisSetGeneralSubscriptionsResult = isNull; +- +-/** +- * analysis.setPriorityFiles params +- * +- * { +- * "files": List +- * } +- */ +-final Matcher isAnalysisSetPriorityFilesParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.setPriorityFiles params", {"files": isListOf(isFilePath)})); +- +-/** +- * analysis.setPriorityFiles result +- */ +-final Matcher isAnalysisSetPriorityFilesResult = isNull; +- +-/** +- * analysis.setSubscriptions params +- * +- * { +- * "subscriptions": Map> +- * } +- */ +-final Matcher isAnalysisSetSubscriptionsParams = new LazyMatcher(() => +- new MatchesJsonObject("analysis.setSubscriptions params", +- {"subscriptions": isMapOf(isAnalysisService, isListOf(isFilePath))})); +- +-/** +- * analysis.setSubscriptions result +- */ +-final Matcher isAnalysisSetSubscriptionsResult = isNull; +- +-/** +- * analysis.updateContent params +- * +- * { +- * "files": Map +- * } +- */ +-final Matcher isAnalysisUpdateContentParams = new LazyMatcher( +- () => new MatchesJsonObject("analysis.updateContent params", { +- "files": isMapOf( +- isFilePath, +- isOneOf([ +- isAddContentOverlay, +- isChangeContentOverlay, +- isRemoveContentOverlay +- ])) +- })); +- +-/** +- * analysis.updateContent result +- * +- * { +- * } +- */ +-final Matcher isAnalysisUpdateContentResult = new LazyMatcher( +- () => new MatchesJsonObject("analysis.updateContent result", null)); +- +-/** +- * analysis.updateOptions params +- * +- * { +- * "options": AnalysisOptions +- * } +- */ +-final Matcher isAnalysisUpdateOptionsParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "analysis.updateOptions params", {"options": isAnalysisOptions})); +- +-/** +- * analysis.updateOptions result +- */ +-final Matcher isAnalysisUpdateOptionsResult = isNull; +- +-/** +- * analytics.enable params +- * +- * { +- * "value": bool +- * } +- */ +-final Matcher isAnalyticsEnableParams = new LazyMatcher( +- () => new MatchesJsonObject("analytics.enable params", {"value": isBool})); +- +-/** +- * analytics.enable result +- */ +-final Matcher isAnalyticsEnableResult = isNull; +- +-/** +- * analytics.isEnabled params +- */ +-final Matcher isAnalyticsIsEnabledParams = isNull; +- +-/** +- * analytics.isEnabled result +- * +- * { +- * "enabled": bool +- * } +- */ +-final Matcher isAnalyticsIsEnabledResult = new LazyMatcher(() => +- new MatchesJsonObject("analytics.isEnabled result", {"enabled": isBool})); +- +-/** +- * analytics.sendEvent params +- * +- * { +- * "action": String +- * } +- */ +-final Matcher isAnalyticsSendEventParams = new LazyMatcher(() => +- new MatchesJsonObject("analytics.sendEvent params", {"action": isString})); +- +-/** +- * analytics.sendEvent result +- */ +-final Matcher isAnalyticsSendEventResult = isNull; +- +-/** +- * analytics.sendTiming params +- * +- * { +- * "event": String +- * "millis": int +- * } +- */ +-final Matcher isAnalyticsSendTimingParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "analytics.sendTiming params", {"event": isString, "millis": isInt})); +- +-/** +- * analytics.sendTiming result +- */ +-final Matcher isAnalyticsSendTimingResult = isNull; +- +-/** +- * completion.getSuggestions params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- */ +-final Matcher isCompletionGetSuggestionsParams = new LazyMatcher(() => +- new MatchesJsonObject("completion.getSuggestions params", +- {"file": isFilePath, "offset": isInt})); +- +-/** +- * completion.getSuggestions result +- * +- * { +- * "id": CompletionId +- * } +- */ +-final Matcher isCompletionGetSuggestionsResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "completion.getSuggestions result", {"id": isCompletionId})); +- +-/** +- * completion.results params +- * +- * { +- * "id": CompletionId +- * "replacementOffset": int +- * "replacementLength": int +- * "results": List +- * "isLast": bool +- * } +- */ +-final Matcher isCompletionResultsParams = +- new LazyMatcher(() => new MatchesJsonObject("completion.results params", { +- "id": isCompletionId, +- "replacementOffset": isInt, +- "replacementLength": isInt, +- "results": isListOf(isCompletionSuggestion), +- "isLast": isBool +- })); +- +-/** +- * convertGetterToMethod feedback +- */ +-final Matcher isConvertGetterToMethodFeedback = isNull; +- +-/** +- * convertGetterToMethod options +- */ +-final Matcher isConvertGetterToMethodOptions = isNull; +- +-/** +- * convertMethodToGetter feedback +- */ +-final Matcher isConvertMethodToGetterFeedback = isNull; +- +-/** +- * convertMethodToGetter options +- */ +-final Matcher isConvertMethodToGetterOptions = isNull; +- +-/** +- * diagnostic.getDiagnostics params +- */ +-final Matcher isDiagnosticGetDiagnosticsParams = isNull; +- +-/** +- * diagnostic.getDiagnostics result +- * +- * { +- * "contexts": List +- * } +- */ +-final Matcher isDiagnosticGetDiagnosticsResult = new LazyMatcher(() => +- new MatchesJsonObject("diagnostic.getDiagnostics result", +- {"contexts": isListOf(isContextData)})); +- +-/** +- * diagnostic.getServerPort params +- */ +-final Matcher isDiagnosticGetServerPortParams = isNull; +- +-/** +- * diagnostic.getServerPort result +- * +- * { +- * "port": int +- * } +- */ +-final Matcher isDiagnosticGetServerPortResult = new LazyMatcher(() => +- new MatchesJsonObject("diagnostic.getServerPort result", {"port": isInt})); +- +-/** +- * edit.format params +- * +- * { +- * "file": FilePath +- * "selectionOffset": int +- * "selectionLength": int +- * "lineLength": optional int +- * } +- */ +-final Matcher isEditFormatParams = new LazyMatcher(() => new MatchesJsonObject( +- "edit.format params", +- {"file": isFilePath, "selectionOffset": isInt, "selectionLength": isInt}, +- optionalFields: {"lineLength": isInt})); +- +-/** +- * edit.format result +- * +- * { +- * "edits": List +- * "selectionOffset": int +- * "selectionLength": int +- * } +- */ +-final Matcher isEditFormatResult = +- new LazyMatcher(() => new MatchesJsonObject("edit.format result", { +- "edits": isListOf(isSourceEdit), +- "selectionOffset": isInt, +- "selectionLength": isInt +- })); +- +-/** +- * edit.getAssists params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isEditGetAssistsParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.getAssists params", +- {"file": isFilePath, "offset": isInt, "length": isInt})); +- +-/** +- * edit.getAssists result +- * +- * { +- * "assists": List +- * } +- */ +-final Matcher isEditGetAssistsResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.getAssists result", {"assists": isListOf(isSourceChange)})); +- +-/** +- * edit.getAvailableRefactorings params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "length": int +- * } +- */ +-final Matcher isEditGetAvailableRefactoringsParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.getAvailableRefactorings params", +- {"file": isFilePath, "offset": isInt, "length": isInt})); +- +-/** +- * edit.getAvailableRefactorings result +- * +- * { +- * "kinds": List +- * } +- */ +-final Matcher isEditGetAvailableRefactoringsResult = new LazyMatcher(() => +- new MatchesJsonObject("edit.getAvailableRefactorings result", +- {"kinds": isListOf(isRefactoringKind)})); +- +-/** +- * edit.getFixes params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- */ +-final Matcher isEditGetFixesParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.getFixes params", {"file": isFilePath, "offset": isInt})); +- +-/** +- * edit.getFixes result +- * +- * { +- * "fixes": List +- * } +- */ +-final Matcher isEditGetFixesResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.getFixes result", {"fixes": isListOf(isAnalysisErrorFixes)})); +- +-/** +- * edit.getPostfixCompletion params +- * +- * { +- * "file": FilePath +- * "key": String +- * "offset": int +- * } +- */ +-final Matcher isEditGetPostfixCompletionParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.getPostfixCompletion params", +- {"file": isFilePath, "key": isString, "offset": isInt})); +- +-/** +- * edit.getPostfixCompletion result +- * +- * { +- * "change": SourceChange +- * } +- */ +-final Matcher isEditGetPostfixCompletionResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.getPostfixCompletion result", {"change": isSourceChange})); +- +-/** +- * edit.getRefactoring params +- * +- * { +- * "kind": RefactoringKind +- * "file": FilePath +- * "offset": int +- * "length": int +- * "validateOnly": bool +- * "options": optional RefactoringOptions +- * } +- */ +-final Matcher isEditGetRefactoringParams = +- new LazyMatcher(() => new MatchesJsonObject("edit.getRefactoring params", { +- "kind": isRefactoringKind, +- "file": isFilePath, +- "offset": isInt, +- "length": isInt, +- "validateOnly": isBool +- }, optionalFields: { +- "options": isRefactoringOptions +- })); +- +-/** +- * edit.getRefactoring result +- * +- * { +- * "initialProblems": List +- * "optionsProblems": List +- * "finalProblems": List +- * "feedback": optional RefactoringFeedback +- * "change": optional SourceChange +- * "potentialEdits": optional List +- * } +- */ +-final Matcher isEditGetRefactoringResult = +- new LazyMatcher(() => new MatchesJsonObject("edit.getRefactoring result", { +- "initialProblems": isListOf(isRefactoringProblem), +- "optionsProblems": isListOf(isRefactoringProblem), +- "finalProblems": isListOf(isRefactoringProblem) +- }, optionalFields: { +- "feedback": isRefactoringFeedback, +- "change": isSourceChange, +- "potentialEdits": isListOf(isString) +- })); +- +-/** +- * edit.getStatementCompletion params +- * +- * { +- * "file": FilePath +- * "offset": int +- * } +- */ +-final Matcher isEditGetStatementCompletionParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.getStatementCompletion params", +- {"file": isFilePath, "offset": isInt})); +- +-/** +- * edit.getStatementCompletion result +- * +- * { +- * "change": SourceChange +- * "whitespaceOnly": bool +- * } +- */ +-final Matcher isEditGetStatementCompletionResult = new LazyMatcher(() => +- new MatchesJsonObject("edit.getStatementCompletion result", +- {"change": isSourceChange, "whitespaceOnly": isBool})); +- +-/** +- * edit.importElements params +- * +- * { +- * "file": FilePath +- * "elements": List +- * } +- */ +-final Matcher isEditImportElementsParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.importElements params", +- {"file": isFilePath, "elements": isListOf(isImportedElements)})); +- +-/** +- * edit.importElements result +- * +- * { +- * "edit": SourceFileEdit +- * } +- */ +-final Matcher isEditImportElementsResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.importElements result", {"edit": isSourceFileEdit})); +- +-/** +- * edit.isPostfixCompletionApplicable params +- * +- * { +- * "file": FilePath +- * "key": String +- * "offset": int +- * } +- */ +-final Matcher isEditIsPostfixCompletionApplicableParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.isPostfixCompletionApplicable params", +- {"file": isFilePath, "key": isString, "offset": isInt})); +- +-/** +- * edit.isPostfixCompletionApplicable result +- * +- * { +- * "value": bool +- * } +- */ +-final Matcher isEditIsPostfixCompletionApplicableResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.isPostfixCompletionApplicable result", {"value": isBool})); +- +-/** +- * edit.listPostfixCompletionTemplates params +- */ +-final Matcher isEditListPostfixCompletionTemplatesParams = isNull; +- +-/** +- * edit.listPostfixCompletionTemplates result +- * +- * { +- * "templates": List +- * } +- */ +-final Matcher isEditListPostfixCompletionTemplatesResult = new LazyMatcher(() => +- new MatchesJsonObject("edit.listPostfixCompletionTemplates result", +- {"templates": isListOf(isPostfixTemplateDescriptor)})); +- +-/** +- * edit.organizeDirectives params +- * +- * { +- * "file": FilePath +- * } +- */ +-final Matcher isEditOrganizeDirectivesParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.organizeDirectives params", {"file": isFilePath})); +- +-/** +- * edit.organizeDirectives result +- * +- * { +- * "edit": SourceFileEdit +- * } +- */ +-final Matcher isEditOrganizeDirectivesResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.organizeDirectives result", {"edit": isSourceFileEdit})); +- +-/** +- * edit.sortMembers params +- * +- * { +- * "file": FilePath +- * } +- */ +-final Matcher isEditSortMembersParams = new LazyMatcher(() => +- new MatchesJsonObject("edit.sortMembers params", {"file": isFilePath})); +- +-/** +- * edit.sortMembers result +- * +- * { +- * "edit": SourceFileEdit +- * } +- */ +-final Matcher isEditSortMembersResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "edit.sortMembers result", {"edit": isSourceFileEdit})); +- +-/** +- * execution.createContext params +- * +- * { +- * "contextRoot": FilePath +- * } +- */ +-final Matcher isExecutionCreateContextParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "execution.createContext params", {"contextRoot": isFilePath})); +- +-/** +- * execution.createContext result +- * +- * { +- * "id": ExecutionContextId +- * } +- */ +-final Matcher isExecutionCreateContextResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "execution.createContext result", {"id": isExecutionContextId})); +- +-/** +- * execution.deleteContext params +- * +- * { +- * "id": ExecutionContextId +- * } +- */ +-final Matcher isExecutionDeleteContextParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "execution.deleteContext params", {"id": isExecutionContextId})); +- +-/** +- * execution.deleteContext result +- */ +-final Matcher isExecutionDeleteContextResult = isNull; +- +-/** +- * execution.launchData params +- * +- * { +- * "file": FilePath +- * "kind": optional ExecutableKind +- * "referencedFiles": optional List +- * } +- */ +-final Matcher isExecutionLaunchDataParams = new LazyMatcher(() => +- new MatchesJsonObject("execution.launchData params", { +- "file": isFilePath +- }, optionalFields: { +- "kind": isExecutableKind, +- "referencedFiles": isListOf(isFilePath) +- })); +- +-/** +- * execution.mapUri params +- * +- * { +- * "id": ExecutionContextId +- * "file": optional FilePath +- * "uri": optional String +- * } +- */ +-final Matcher isExecutionMapUriParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "execution.mapUri params", {"id": isExecutionContextId}, +- optionalFields: {"file": isFilePath, "uri": isString})); +- +-/** +- * execution.mapUri result +- * +- * { +- * "file": optional FilePath +- * "uri": optional String +- * } +- */ +-final Matcher isExecutionMapUriResult = new LazyMatcher(() => +- new MatchesJsonObject("execution.mapUri result", null, +- optionalFields: {"file": isFilePath, "uri": isString})); +- +-/** +- * execution.setSubscriptions params +- * +- * { +- * "subscriptions": List +- * } +- */ +-final Matcher isExecutionSetSubscriptionsParams = new LazyMatcher(() => +- new MatchesJsonObject("execution.setSubscriptions params", +- {"subscriptions": isListOf(isExecutionService)})); +- +-/** +- * execution.setSubscriptions result +- */ +-final Matcher isExecutionSetSubscriptionsResult = isNull; +- +-/** +- * extractLocalVariable feedback +- * +- * { +- * "coveringExpressionOffsets": optional List +- * "coveringExpressionLengths": optional List +- * "names": List +- * "offsets": List +- * "lengths": List +- * } +- */ +-final Matcher isExtractLocalVariableFeedback = new LazyMatcher( +- () => new MatchesJsonObject("extractLocalVariable feedback", { +- "names": isListOf(isString), +- "offsets": isListOf(isInt), +- "lengths": isListOf(isInt) +- }, optionalFields: { +- "coveringExpressionOffsets": isListOf(isInt), +- "coveringExpressionLengths": isListOf(isInt) +- })); +- +-/** +- * extractLocalVariable options +- * +- * { +- * "name": String +- * "extractAll": bool +- * } +- */ +-final Matcher isExtractLocalVariableOptions = new LazyMatcher(() => +- new MatchesJsonObject("extractLocalVariable options", +- {"name": isString, "extractAll": isBool})); +- +-/** +- * extractMethod feedback +- * +- * { +- * "offset": int +- * "length": int +- * "returnType": String +- * "names": List +- * "canCreateGetter": bool +- * "parameters": List +- * "offsets": List +- * "lengths": List +- * } +- */ +-final Matcher isExtractMethodFeedback = +- new LazyMatcher(() => new MatchesJsonObject("extractMethod feedback", { +- "offset": isInt, +- "length": isInt, +- "returnType": isString, +- "names": isListOf(isString), +- "canCreateGetter": isBool, +- "parameters": isListOf(isRefactoringMethodParameter), +- "offsets": isListOf(isInt), +- "lengths": isListOf(isInt) +- })); +- +-/** +- * extractMethod options +- * +- * { +- * "returnType": String +- * "createGetter": bool +- * "name": String +- * "parameters": List +- * "extractAll": bool +- * } +- */ +-final Matcher isExtractMethodOptions = +- new LazyMatcher(() => new MatchesJsonObject("extractMethod options", { +- "returnType": isString, +- "createGetter": isBool, +- "name": isString, +- "parameters": isListOf(isRefactoringMethodParameter), +- "extractAll": isBool +- })); +- +-/** +- * inlineLocalVariable feedback +- * +- * { +- * "name": String +- * "occurrences": int +- * } +- */ +-final Matcher isInlineLocalVariableFeedback = new LazyMatcher(() => +- new MatchesJsonObject("inlineLocalVariable feedback", +- {"name": isString, "occurrences": isInt})); +- +-/** +- * inlineLocalVariable options +- */ +-final Matcher isInlineLocalVariableOptions = isNull; +- +-/** +- * inlineMethod feedback +- * +- * { +- * "className": optional String +- * "methodName": String +- * "isDeclaration": bool +- * } +- */ +-final Matcher isInlineMethodFeedback = new LazyMatcher(() => +- new MatchesJsonObject("inlineMethod feedback", +- {"methodName": isString, "isDeclaration": isBool}, +- optionalFields: {"className": isString})); +- +-/** +- * inlineMethod options +- * +- * { +- * "deleteSource": bool +- * "inlineAll": bool +- * } +- */ +-final Matcher isInlineMethodOptions = new LazyMatcher(() => +- new MatchesJsonObject( +- "inlineMethod options", {"deleteSource": isBool, "inlineAll": isBool})); +- +-/** +- * kythe.getKytheEntries params +- * +- * { +- * "file": FilePath +- * } +- */ +-final Matcher isKytheGetKytheEntriesParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "kythe.getKytheEntries params", {"file": isFilePath})); +- +-/** +- * kythe.getKytheEntries result +- * +- * { +- * "entries": List +- * "files": List +- * } +- */ +-final Matcher isKytheGetKytheEntriesResult = new LazyMatcher(() => +- new MatchesJsonObject("kythe.getKytheEntries result", +- {"entries": isListOf(isKytheEntry), "files": isListOf(isFilePath)})); +- +-/** +- * moveFile feedback +- */ +-final Matcher isMoveFileFeedback = isNull; +- +-/** +- * moveFile options +- * +- * { +- * "newFile": FilePath +- * } +- */ +-final Matcher isMoveFileOptions = new LazyMatcher( +- () => new MatchesJsonObject("moveFile options", {"newFile": isFilePath})); +- +-/** +- * rename feedback +- * +- * { +- * "offset": int +- * "length": int +- * "elementKindName": String +- * "oldName": String +- * } +- */ +-final Matcher isRenameFeedback = +- new LazyMatcher(() => new MatchesJsonObject("rename feedback", { +- "offset": isInt, +- "length": isInt, +- "elementKindName": isString, +- "oldName": isString +- })); +- +-/** +- * rename options +- * +- * { +- * "newName": String +- * } +- */ +-final Matcher isRenameOptions = new LazyMatcher( +- () => new MatchesJsonObject("rename options", {"newName": isString})); +- +-/** +- * search.findElementReferences params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "includePotential": bool +- * } +- */ +-final Matcher isSearchFindElementReferencesParams = new LazyMatcher(() => +- new MatchesJsonObject("search.findElementReferences params", +- {"file": isFilePath, "offset": isInt, "includePotential": isBool})); +- +-/** +- * search.findElementReferences result +- * +- * { +- * "id": optional SearchId +- * "element": optional Element +- * } +- */ +-final Matcher isSearchFindElementReferencesResult = new LazyMatcher(() => +- new MatchesJsonObject("search.findElementReferences result", null, +- optionalFields: {"id": isSearchId, "element": isElement})); +- +-/** +- * search.findMemberDeclarations params +- * +- * { +- * "name": String +- * } +- */ +-final Matcher isSearchFindMemberDeclarationsParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.findMemberDeclarations params", {"name": isString})); +- +-/** +- * search.findMemberDeclarations result +- * +- * { +- * "id": SearchId +- * } +- */ +-final Matcher isSearchFindMemberDeclarationsResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.findMemberDeclarations result", {"id": isSearchId})); +- +-/** +- * search.findMemberReferences params +- * +- * { +- * "name": String +- * } +- */ +-final Matcher isSearchFindMemberReferencesParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.findMemberReferences params", {"name": isString})); +- +-/** +- * search.findMemberReferences result +- * +- * { +- * "id": SearchId +- * } +- */ +-final Matcher isSearchFindMemberReferencesResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.findMemberReferences result", {"id": isSearchId})); +- +-/** +- * search.findTopLevelDeclarations params +- * +- * { +- * "pattern": String +- * } +- */ +-final Matcher isSearchFindTopLevelDeclarationsParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.findTopLevelDeclarations params", {"pattern": isString})); +- +-/** +- * search.findTopLevelDeclarations result +- * +- * { +- * "id": SearchId +- * } +- */ +-final Matcher isSearchFindTopLevelDeclarationsResult = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.findTopLevelDeclarations result", {"id": isSearchId})); +- +-/** +- * search.getTypeHierarchy params +- * +- * { +- * "file": FilePath +- * "offset": int +- * "superOnly": optional bool +- * } +- */ +-final Matcher isSearchGetTypeHierarchyParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "search.getTypeHierarchy params", {"file": isFilePath, "offset": isInt}, +- optionalFields: {"superOnly": isBool})); +- +-/** +- * search.getTypeHierarchy result +- * +- * { +- * "hierarchyItems": optional List +- * } +- */ +-final Matcher isSearchGetTypeHierarchyResult = new LazyMatcher(() => +- new MatchesJsonObject("search.getTypeHierarchy result", null, +- optionalFields: {"hierarchyItems": isListOf(isTypeHierarchyItem)})); +- +-/** +- * search.results params +- * +- * { +- * "id": SearchId +- * "results": List +- * "isLast": bool +- * } +- */ +-final Matcher isSearchResultsParams = new LazyMatcher(() => +- new MatchesJsonObject("search.results params", { +- "id": isSearchId, +- "results": isListOf(isSearchResult), +- "isLast": isBool +- })); +- +-/** +- * server.connected params +- * +- * { +- * "version": String +- * "pid": int +- * "sessionId": optional String +- * } +- */ +-final Matcher isServerConnectedParams = new LazyMatcher(() => +- new MatchesJsonObject( +- "server.connected params", {"version": isString, "pid": isInt}, +- optionalFields: {"sessionId": isString})); +- +-/** +- * server.error params +- * +- * { +- * "isFatal": bool +- * "message": String +- * "stackTrace": String +- * } +- */ +-final Matcher isServerErrorParams = new LazyMatcher(() => new MatchesJsonObject( +- "server.error params", +- {"isFatal": isBool, "message": isString, "stackTrace": isString})); +- +-/** +- * server.getVersion params +- */ +-final Matcher isServerGetVersionParams = isNull; +- +-/** +- * server.getVersion result +- * +- * { +- * "version": String +- * } +- */ +-final Matcher isServerGetVersionResult = new LazyMatcher(() => +- new MatchesJsonObject("server.getVersion result", {"version": isString})); +- +-/** +- * server.setSubscriptions params +- * +- * { +- * "subscriptions": List +- * } +- */ +-final Matcher isServerSetSubscriptionsParams = new LazyMatcher(() => +- new MatchesJsonObject("server.setSubscriptions params", +- {"subscriptions": isListOf(isServerService)})); +- +-/** +- * server.setSubscriptions result +- */ +-final Matcher isServerSetSubscriptionsResult = isNull; +- +-/** +- * server.shutdown params +- */ +-final Matcher isServerShutdownParams = isNull; +- +-/** +- * server.shutdown result +- */ +-final Matcher isServerShutdownResult = isNull; +- +-/** +- * server.status params +- * +- * { +- * "analysis": optional AnalysisStatus +- * "pub": optional PubStatus +- * } +- */ +-final Matcher isServerStatusParams = new LazyMatcher(() => +- new MatchesJsonObject("server.status params", null, +- optionalFields: {"analysis": isAnalysisStatus, "pub": isPubStatus})); +diff --git a/pkg/analysis_server/test/integration/test_all.dart b/pkg/analysis_server/test/integration/test_all.dart +deleted file mode 100644 +index c69d15b695b..00000000000 +--- a/pkg/analysis_server/test/integration/test_all.dart ++++ /dev/null +@@ -1,35 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'analysis/test_all.dart' as analysis_test_all; +-import 'analytics/test_all.dart' as analytics_test_all; +-import 'completion/test_all.dart' as completion_test_all; +-import 'coverage_test.dart' as coverage_test; +-import 'diagnostic/test_all.dart' as diagnostic_test_all; +-import 'edit/test_all.dart' as edit_test_all; +-import 'execution/test_all.dart' as execution_test_all; +-import 'kythe/test_all.dart' as kythe_test_all; +-import 'search/test_all.dart' as search_test_all; +-import 'server/test_all.dart' as server_test_all; +- +-/** +- * Utility for manually running all integration tests. +- */ +-main() { +- defineReflectiveSuite(() { +- analysis_test_all.main(); +- analytics_test_all.main(); +- completion_test_all.main(); +- diagnostic_test_all.main(); +- edit_test_all.main(); +- execution_test_all.main(); +- kythe_test_all.main(); +- search_test_all.main(); +- server_test_all.main(); +- +- coverage_test.main(); +- }, name: 'analysis_server_integration'); +-} +diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart +deleted file mode 100644 +index a0719874ff6..00000000000 +--- a/pkg/analysis_server/test/mock_sdk.dart ++++ /dev/null +@@ -1,438 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library testing.mock_sdk; +- +-import 'package:analyzer/file_system/file_system.dart' as resource; +-import 'package:analyzer/file_system/memory_file_system.dart' as resource; +-import 'package:analyzer/src/context/context.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/summary/idl.dart' show PackageBundle; +-import 'package:analyzer/src/summary/summary_file_builder.dart'; +- +-class MockSdk implements DartSdk { +- static const MockSdkLibrary LIB_CORE = +- const MockSdkLibrary('dart:core', '/lib/core/core.dart', ''' +-library dart.core; +- +-import 'dart:async'; +-import 'dart:_internal'; +- +-class Object { +- const Object() {} +- bool operator ==(other) => identical(this, other); +- String toString() => 'a string'; +- int get hashCode => 0; +- Type get runtimeType => null; +- dynamic noSuchMethod(Invocation invocation) => null; +-} +- +-class Function {} +-class StackTrace {} +-class Symbol {} +-class Type {} +- +-abstract class Comparable { +- int compareTo(T other); +-} +- +-abstract class String implements Comparable { +- external factory String.fromCharCodes(Iterable charCodes, +- [int start = 0, int end]); +- bool get isEmpty => false; +- bool get isNotEmpty => false; +- int get length => 0; +- String toUpperCase(); +- List get codeUnits; +-} +- +-class bool extends Object {} +- +-abstract class num implements Comparable { +- bool operator <(num other); +- bool operator <=(num other); +- bool operator >(num other); +- bool operator >=(num other); +- num operator +(num other); +- num operator -(num other); +- num operator *(num other); +- num operator /(num other); +- int operator ^(int other); +- int operator &(int other); +- int operator |(int other); +- int operator <<(int other); +- int operator >>(int other); +- int operator ~/(num other); +- num operator %(num other); +- int operator ~(); +- int toInt(); +- double toDouble(); +- num abs(); +- int round(); +-} +- +-abstract class int extends num { +- bool get isEven => false; +- int operator -(); +- external static int parse(String source, +- { int radix, +- int onError(String source) }); +-} +- +-abstract class double extends num { +- static const double NAN = 0.0 / 0.0; +- static const double INFINITY = 1.0 / 0.0; +- static const double NEGATIVE_INFINITY = -INFINITY; +- static const double MIN_POSITIVE = 5e-324; +- static const double MAX_FINITE = 1.7976931348623157e+308; +- +- double remainder(num other); +- double operator +(num other); +- double operator -(num other); +- double operator *(num other); +- double operator %(num other); +- double operator /(num other); +- int operator ~/(num other); +- double operator -(); +- double abs(); +- double get sign; +- int round(); +- int floor(); +- int ceil(); +- int truncate(); +- double roundToDouble(); +- double floorToDouble(); +- double ceilToDouble(); +- double truncateToDouble(); +- external static double parse(String source, +- [double onError(String source)]); +-} +- +-class DateTime extends Object {} +-class Null extends Object {} +- +-class Deprecated extends Object { +- final String expires; +- const Deprecated(this.expires); +-} +-const Object deprecated = const Deprecated("next release"); +- +-class Iterator { +- bool moveNext(); +- E get current; +-} +- +-abstract class Iterable { +- Iterator get iterator; +- bool get isEmpty; +- Iterable map(T f(E e)) => null; +- T fold(T initialValue, T combine(T previousValue, E element)); +-} +- +-class List implements Iterable { +- List(); +- void add(E value) {} +- void addAll(Iterable iterable) {} +- E operator [](int index) => null; +- void operator []=(int index, E value) {} +- Iterator get iterator => null; +- void clear() {} +- +- bool get isEmpty => false; +- E get first => null; +- E get last => null; +-} +- +-abstract class Map extends Object { +- bool containsKey(Object key); +- Iterable get keys; +-} +- +-external bool identical(Object a, Object b); +- +-void print(Object object) {} +- +-class Uri { +- static List parseIPv6Address(String host, [int start = 0, int end]) { +- int parseHex(int start, int end) { +- return 0; +- } +- return null; +- } +-} +-'''); +- +- static const MockSdkLibrary LIB_ASYNC = +- const MockSdkLibrary('dart:async', '/lib/async/async.dart', ''' +-library dart.async; +- +-import 'dart:math'; +- +-class Future { +- factory Future(computation()) => null; +- factory Future.delayed(Duration duration, [T computation()]) => null; +- factory Future.value([value]) => null; +- static Future wait(List futures) => null; +-} +- +-class FutureOr {} +- +-class Stream {} +-abstract class StreamTransformer {} +-'''); +- +- static const MockSdkLibrary LIB_COLLECTION = const MockSdkLibrary( +- 'dart:collection', '/lib/collection/collection.dart', ''' +-library dart.collection; +- +-abstract class HashMap implements Map {} +-abstract class LinkedHashMap implements Map {} +-'''); +- +- static const MockSdkLibrary LIB_CONVERT = +- const MockSdkLibrary('dart:convert', '/lib/convert/convert.dart', ''' +-library dart.convert; +- +-import 'dart:async'; +- +-abstract class Converter implements StreamTransformer {} +-class JsonDecoder extends Converter {} +-'''); +- +- static const MockSdkLibrary LIB_MATH = +- const MockSdkLibrary('dart:math', '/lib/math/math.dart', ''' +-library dart.math; +-const double E = 2.718281828459045; +-const double PI = 3.1415926535897932; +-const double LN10 = 2.302585092994046; +-T min(T a, T b) => null; +-T max(T a, T b) => null; +-external double cos(num radians); +-external num pow(num x, num exponent); +-external double sin(num radians); +-external double sqrt(num x); +-class Random { +- bool nextBool() => true; +- double nextDouble() => 2.0; +- int nextInt() => 1; +-} +-'''); +- +- static const MockSdkLibrary LIB_HTML = const MockSdkLibrary( +- 'dart:html', '/lib/html/dartium/html_dartium.dart', ''' +-library dart.html; +-class HtmlElement {} +-'''); +- +- static const MockSdkLibrary LIB_INTERNAL = +- const MockSdkLibrary('dart:_internal', '/lib/internal/internal.dart', ''' +-library dart._internal; +-external void printToConsole(String line); +-'''); +- +- static const List LIBRARIES = const [ +- LIB_CORE, +- LIB_ASYNC, +- LIB_COLLECTION, +- LIB_CONVERT, +- LIB_MATH, +- LIB_HTML, +- LIB_INTERNAL, +- ]; +- +- static const String librariesContent = r''' +-const Map libraries = const { +- "async": const LibraryInfo("async/async.dart"), +- "collection": const LibraryInfo("collection/collection.dart"), +- "convert": const LibraryInfo("convert/convert.dart"), +- "core": const LibraryInfo("core/core.dart"), +- "html": const LibraryInfo("html/dartium/html_dartium.dart"), +- "math": const LibraryInfo("math/math.dart"), +- "_internal": const LibraryInfo("internal/internal.dart"), +-}; +-'''; +- +- final resource.MemoryResourceProvider provider; +- +- /** +- * The [AnalysisContext] which is used for all of the sources. +- */ +- InternalAnalysisContext _analysisContext; +- +- /** +- * The cached linked bundle of the SDK. +- */ +- PackageBundle _bundle; +- +- MockSdk( +- {bool generateSummaryFiles: false, +- resource.ResourceProvider resourceProvider}) +- : provider = resourceProvider ?? new resource.MemoryResourceProvider() { +- LIBRARIES.forEach((SdkLibrary library) { +- provider.newFile(library.path, (library as MockSdkLibrary).content); +- }); +- provider.newFile( +- provider.convertPath( +- '/lib/_internal/sdk_library_metadata/lib/libraries.dart'), +- librariesContent); +- if (generateSummaryFiles) { +- List bytes = _computeLinkedBundleBytes(); +- provider.newFileWithBytes( +- provider.convertPath('/lib/_internal/spec.sum'), bytes); +- provider.newFileWithBytes( +- provider.convertPath('/lib/_internal/strong.sum'), bytes); +- } +- } +- +- @override +- AnalysisContext get context { +- if (_analysisContext == null) { +- _analysisContext = new SdkAnalysisContext(null); +- SourceFactory factory = new SourceFactory([new DartUriResolver(this)]); +- _analysisContext.sourceFactory = factory; +- } +- return _analysisContext; +- } +- +- @override +- List get sdkLibraries => LIBRARIES; +- +- @override +- String get sdkVersion => throw unimplemented; +- +- UnimplementedError get unimplemented => new UnimplementedError(); +- +- @override +- List get uris { +- List uris = []; +- for (SdkLibrary library in LIBRARIES) { +- uris.add(library.shortName); +- } +- return uris; +- } +- +- @override +- Source fromFileUri(Uri uri) { +- String filePath = provider.pathContext.fromUri(uri); +- for (SdkLibrary library in sdkLibraries) { +- String libraryPath = provider.convertPath(library.path); +- if (filePath == libraryPath) { +- try { +- resource.File file = provider.getResource(filePath); +- Uri dartUri = Uri.parse(library.shortName); +- return file.createSource(dartUri); +- } catch (exception) { +- return null; +- } +- } +- String libraryRootPath = provider.pathContext.dirname(libraryPath) + +- provider.pathContext.separator; +- if (filePath.startsWith(libraryRootPath)) { +- String pathInLibrary = filePath.substring(libraryRootPath.length); +- String uriStr = '${library.shortName}/$pathInLibrary'; +- try { +- resource.File file = provider.getResource(filePath); +- Uri dartUri = Uri.parse(uriStr); +- return file.createSource(dartUri); +- } catch (exception) { +- return null; +- } +- } +- } +- return null; +- } +- +- @override +- PackageBundle getLinkedBundle() { +- if (_bundle == null) { +- resource.File summaryFile = +- provider.getFile(provider.convertPath('/lib/_internal/spec.sum')); +- List bytes; +- if (summaryFile.exists) { +- bytes = summaryFile.readAsBytesSync(); +- } else { +- bytes = _computeLinkedBundleBytes(); +- } +- _bundle = new PackageBundle.fromBuffer(bytes); +- } +- return _bundle; +- } +- +- @override +- SdkLibrary getSdkLibrary(String dartUri) { +- // getSdkLibrary() is only used to determine whether a library is internal +- // to the SDK. The mock SDK doesn't have any internals, so it's safe to +- // return null. +- return null; +- } +- +- @override +- Source mapDartUri(String dartUri) { +- const Map uriToPath = const { +- "dart:core": "/lib/core/core.dart", +- "dart:html": "/lib/html/dartium/html_dartium.dart", +- "dart:async": "/lib/async/async.dart", +- "dart:collection": "/lib/collection/collection.dart", +- "dart:convert": "/lib/convert/convert.dart", +- "dart:math": "/lib/math/math.dart", +- "dart:_internal": "/lib/internal/internal.dart", +- }; +- +- String path = uriToPath[dartUri]; +- if (path != null) { +- resource.File file = provider.getResource(path); +- Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5)); +- return file.createSource(uri); +- } +- +- // If we reach here then we tried to use a dartUri that's not in the +- // table above. +- return null; +- } +- +- /** +- * Compute the bytes of the linked bundle associated with this SDK. +- */ +- List _computeLinkedBundleBytes() { +- List librarySources = sdkLibraries +- .map((SdkLibrary library) => mapDartUri(library.shortName)) +- .toList(); +- return new SummaryBuilder( +- librarySources, context, context.analysisOptions.strongMode) +- .build(); +- } +-} +- +-class MockSdkLibrary implements SdkLibrary { +- final String shortName; +- final String path; +- final String content; +- +- const MockSdkLibrary(this.shortName, this.path, this.content); +- +- @override +- String get category => throw unimplemented; +- +- @override +- bool get isDart2JsLibrary => throw unimplemented; +- +- @override +- bool get isDocumented => throw unimplemented; +- +- @override +- bool get isImplementation => false; +- +- @override +- bool get isInternal => shortName.startsWith('dart:_'); +- +- @override +- bool get isShared => throw unimplemented; +- +- @override +- bool get isVmLibrary => throw unimplemented; +- +- UnimplementedError get unimplemented => new UnimplementedError(); +-} +diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart +deleted file mode 100644 +index 20a5fcd6a4a..00000000000 +--- a/pkg/analysis_server/test/mocks.dart ++++ /dev/null +@@ -1,320 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/channel/channel.dart'; +-import 'package:analyzer/file_system/file_system.dart' as resource; +-import 'package:analyzer/file_system/memory_file_system.dart' as resource; +-import 'package:analyzer/source/package_map_provider.dart'; +-import 'package:analyzer/source/pub_package_map_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:mockito/mockito.dart'; +-import 'package:test/test.dart'; +- +-/** +- * Answer the absolute path the SDK relative to the currently running +- * script or throw an exception if it cannot be found. +- */ +-String get sdkPath { +- Uri sdkUri = Platform.script.resolve('../../../sdk/'); +- +- // Verify the directory exists +- Directory sdkDir = new Directory.fromUri(sdkUri); +- if (!sdkDir.existsSync()) { +- throw 'Specified Dart SDK does not exist: $sdkDir'; +- } +- +- return sdkDir.path; +-} +- +-/** +- * A [Matcher] that check that the given [Response] has an expected identifier +- * and has an error. The error code may optionally be checked. +- */ +-Matcher isResponseFailure(String id, [RequestErrorCode code]) => +- new _IsResponseFailure(id, code); +- +-/** +- * A [Matcher] that check that the given [Response] has an expected identifier +- * and no error. +- */ +-Matcher isResponseSuccess(String id) => new _IsResponseSuccess(id); +- +-/** +- * Returns a [Future] that completes after pumping the event queue [times] +- * times. By default, this should pump the event queue enough times to allow +- * any code to run, as long as it's not waiting on some external event. +- */ +-Future pumpEventQueue([int times = 5000]) { +- if (times == 0) return new Future.value(); +- // We use a delayed future to allow microtask events to finish. The +- // Future.value or Future() constructors use scheduleMicrotask themselves and +- // would therefore not wait for microtask callbacks that are scheduled after +- // invoking this method. +- return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); +-} +- +-/** +- * A mock [PackageMapProvider]. +- */ +-class MockPackageMapProvider implements PubPackageMapProvider { +- /** +- * Package map that will be returned by the next call to [computePackageMap]. +- */ +- Map> packageMap = +- >{}; +- +- /** +- * Package maps that will be returned by the next call to [computePackageMap]. +- */ +- Map>> packageMaps = null; +- +- /** +- * Dependency list that will be returned by the next call to [computePackageMap]. +- */ +- Set dependencies = new Set(); +- +- /** +- * Number of times [computePackageMap] has been called. +- */ +- int computeCount = 0; +- +- @override +- PackageMapInfo computePackageMap(resource.Folder folder) { +- ++computeCount; +- if (packageMaps != null) { +- return new PackageMapInfo(packageMaps[folder.path], dependencies); +- } +- return new PackageMapInfo(packageMap, dependencies); +- } +- +- noSuchMethod(Invocation invocation) { +- // No other methods should be called. +- return super.noSuchMethod(invocation); +- } +-} +- +-/** +- * A mock [ServerCommunicationChannel] for testing [AnalysisServer]. +- */ +-class MockServerChannel implements ServerCommunicationChannel { +- StreamController requestController = new StreamController(); +- StreamController responseController = +- new StreamController.broadcast(); +- StreamController notificationController = +- new StreamController(sync: true); +- +- List responsesReceived = []; +- List notificationsReceived = []; +- bool _closed = false; +- +- MockServerChannel(); +- @override +- void close() { +- _closed = true; +- } +- +- void expectMsgCount({responseCount: 0, notificationCount: 0}) { +- expect(responsesReceived, hasLength(responseCount)); +- expect(notificationsReceived, hasLength(notificationCount)); +- } +- +- @override +- void listen(void onRequest(Request request), +- {Function onError, void onDone()}) { +- requestController.stream +- .listen(onRequest, onError: onError, onDone: onDone); +- } +- +- @override +- void sendNotification(Notification notification) { +- // Don't deliver notifications after the connection is closed. +- if (_closed) { +- return; +- } +- notificationsReceived.add(notification); +- // Wrap send notification in future to simulate websocket +- // TODO(scheglov) ask Dan why and decide what to do +-// new Future(() => notificationController.add(notification)); +- notificationController.add(notification); +- } +- +- /** +- * Simulate request/response pair. +- */ +- Future sendRequest(Request request) { +- // No further requests should be sent after the connection is closed. +- if (_closed) { +- throw new Exception('sendRequest after connection closed'); +- } +- // Wrap send request in future to simulate WebSocket. +- new Future(() => requestController.add(request)); +- return waitForResponse(request); +- } +- +- @override +- void sendResponse(Response response) { +- // Don't deliver responses after the connection is closed. +- if (_closed) { +- return; +- } +- responsesReceived.add(response); +- // Wrap send response in future to simulate WebSocket. +- new Future(() => responseController.add(response)); +- } +- +- Future waitForResponse(Request request) { +- String id = request.id; +- return new Future(() => responseController.stream +- .firstWhere((response) => response.id == id) as Future); +- } +-} +- +-/** +- * A mock [WebSocket] for testing. +- */ +-class MockSocket implements WebSocket { +- StreamController controller = new StreamController(); +- MockSocket twin; +- Stream stream; +- +- MockSocket(); +- +- factory MockSocket.pair() { +- MockSocket socket1 = new MockSocket(); +- MockSocket socket2 = new MockSocket(); +- socket1.twin = socket2; +- socket2.twin = socket1; +- socket1.stream = socket2.controller.stream; +- socket2.stream = socket1.controller.stream; +- return socket1; +- } +- +- void add(dynamic text) => controller.add(text as T); +- +- void allowMultipleListeners() { +- stream = stream.asBroadcastStream(); +- } +- +- Future close([int code, String reason]) => +- controller.close().then((_) => twin.controller.close()); +- +- StreamSubscription listen(void onData(dynamic event), +- {Function onError, void onDone(), bool cancelOnError}) => +- stream.listen((T data) => onData(data), +- onError: onError, onDone: onDone, cancelOnError: cancelOnError); +- +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +- +- Stream where(bool test(dynamic t)) => stream.where((T data) => test(data)); +-} +- +-class MockSource extends StringTypedMock implements Source { +- MockSource([String name = 'mocked.dart']) : super(name); +-} +- +-class StringTypedMock extends Mock { +- String _toString; +- +- StringTypedMock(this._toString); +- +- @override +- String toString() { +- if (_toString != null) { +- return _toString; +- } +- return super.toString(); +- } +-} +- +-/** +- * A [Matcher] that check that there are no `error` in a given [Response]. +- */ +-class _IsResponseFailure extends Matcher { +- final String _id; +- final RequestErrorCode _code; +- +- _IsResponseFailure(this._id, this._code); +- +- @override +- Description describe(Description description) { +- description = +- description.add('response with identifier "$_id" and an error'); +- if (_code != null) { +- description = description.add(' with code ${this._code.name}'); +- } +- return description; +- } +- +- @override +- Description describeMismatch( +- item, Description mismatchDescription, Map matchState, bool verbose) { +- Response response = item; +- var id = response.id; +- RequestError error = response.error; +- mismatchDescription.add('has identifier "$id"'); +- if (error == null) { +- mismatchDescription.add(' and has no error'); +- } else { +- mismatchDescription +- .add(' and has error code ${response.error.code.name}'); +- } +- return mismatchDescription; +- } +- +- @override +- bool matches(item, Map matchState) { +- Response response = item; +- if (response.id != _id || response.error == null) { +- return false; +- } +- if (_code != null && response.error.code != _code) { +- return false; +- } +- return true; +- } +-} +- +-/** +- * A [Matcher] that check that there are no `error` in a given [Response]. +- */ +-class _IsResponseSuccess extends Matcher { +- final String _id; +- +- _IsResponseSuccess(this._id); +- +- @override +- Description describe(Description description) { +- return description +- .addDescriptionOf('response with identifier "$_id" and without error'); +- } +- +- @override +- Description describeMismatch( +- item, Description mismatchDescription, Map matchState, bool verbose) { +- Response response = item; +- if (response == null) { +- mismatchDescription.add('is null response'); +- } else { +- var id = response.id; +- RequestError error = response.error; +- mismatchDescription.add('has identifier "$id"'); +- if (error != null) { +- mismatchDescription.add(' and has error $error'); +- } +- } +- return mismatchDescription; +- } +- +- @override +- bool matches(item, Map matchState) { +- Response response = item; +- return response != null && response.id == _id && response.error == null; +- } +-} +diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart +deleted file mode 100644 +index 9a1717a9b03..00000000000 +--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart ++++ /dev/null +@@ -1,461 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/plugin/protocol/protocol_dart.dart'; +-import 'package:analyzer/dart/ast/ast.dart' as engine; +-import 'package:analyzer/dart/ast/visitor.dart' as engine; +-import 'package:analyzer/dart/element/element.dart' as engine; +-import 'package:analyzer/dart/element/type.dart' as engine; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/src/dart/ast/utilities.dart' as engine; +-import 'package:analyzer/src/dart/element/element.dart' as engine; +-import 'package:analyzer/src/error/codes.dart' as engine; +-import 'package:analyzer/src/generated/source.dart' as engine; +-import 'package:analyzer/src/generated/testing/element_search.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../abstract_context.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ElementTest); +- defineReflectiveTests(ElementKindTest); +- }); +-} +- +-@reflectiveTest +-class ElementKindTest { +- void test_fromEngine() { +- expect(convertElementKind(engine.ElementKind.CLASS), ElementKind.CLASS); +- expect(convertElementKind(engine.ElementKind.COMPILATION_UNIT), +- ElementKind.COMPILATION_UNIT); +- expect(convertElementKind(engine.ElementKind.CONSTRUCTOR), +- ElementKind.CONSTRUCTOR); +- expect(convertElementKind(engine.ElementKind.FIELD), ElementKind.FIELD); +- expect( +- convertElementKind(engine.ElementKind.FUNCTION), ElementKind.FUNCTION); +- expect(convertElementKind(engine.ElementKind.FUNCTION_TYPE_ALIAS), +- ElementKind.FUNCTION_TYPE_ALIAS); +- expect(convertElementKind(engine.ElementKind.GETTER), ElementKind.GETTER); +- expect(convertElementKind(engine.ElementKind.LABEL), ElementKind.LABEL); +- expect(convertElementKind(engine.ElementKind.LIBRARY), ElementKind.LIBRARY); +- expect(convertElementKind(engine.ElementKind.LOCAL_VARIABLE), +- ElementKind.LOCAL_VARIABLE); +- expect(convertElementKind(engine.ElementKind.METHOD), ElementKind.METHOD); +- expect(convertElementKind(engine.ElementKind.PARAMETER), +- ElementKind.PARAMETER); +- expect(convertElementKind(engine.ElementKind.SETTER), ElementKind.SETTER); +- expect(convertElementKind(engine.ElementKind.TOP_LEVEL_VARIABLE), +- ElementKind.TOP_LEVEL_VARIABLE); +- expect(convertElementKind(engine.ElementKind.TYPE_PARAMETER), +- ElementKind.TYPE_PARAMETER); +- } +- +- void test_string_constructor() { +- expect(new ElementKind(ElementKind.CLASS.name), ElementKind.CLASS); +- expect(new ElementKind(ElementKind.CLASS_TYPE_ALIAS.name), +- ElementKind.CLASS_TYPE_ALIAS); +- expect(new ElementKind(ElementKind.COMPILATION_UNIT.name), +- ElementKind.COMPILATION_UNIT); +- expect( +- new ElementKind(ElementKind.CONSTRUCTOR.name), ElementKind.CONSTRUCTOR); +- expect(new ElementKind(ElementKind.FIELD.name), ElementKind.FIELD); +- expect(new ElementKind(ElementKind.FUNCTION.name), ElementKind.FUNCTION); +- expect(new ElementKind(ElementKind.FUNCTION_TYPE_ALIAS.name), +- ElementKind.FUNCTION_TYPE_ALIAS); +- expect(new ElementKind(ElementKind.GETTER.name), ElementKind.GETTER); +- expect(new ElementKind(ElementKind.LIBRARY.name), ElementKind.LIBRARY); +- expect(new ElementKind(ElementKind.LOCAL_VARIABLE.name), +- ElementKind.LOCAL_VARIABLE); +- expect(new ElementKind(ElementKind.METHOD.name), ElementKind.METHOD); +- expect(new ElementKind(ElementKind.PARAMETER.name), ElementKind.PARAMETER); +- expect(new ElementKind(ElementKind.SETTER.name), ElementKind.SETTER); +- expect(new ElementKind(ElementKind.TOP_LEVEL_VARIABLE.name), +- ElementKind.TOP_LEVEL_VARIABLE); +- expect(new ElementKind(ElementKind.TYPE_PARAMETER.name), +- ElementKind.TYPE_PARAMETER); +- expect(new ElementKind(ElementKind.UNIT_TEST_TEST.name), +- ElementKind.UNIT_TEST_TEST); +- expect(new ElementKind(ElementKind.UNIT_TEST_GROUP.name), +- ElementKind.UNIT_TEST_GROUP); +- expect(new ElementKind(ElementKind.UNKNOWN.name), ElementKind.UNKNOWN); +- expect(() { +- new ElementKind('no-such-kind'); +- }, throwsException); +- } +- +- void test_toString() { +- expect(ElementKind.CLASS.toString(), 'ElementKind.CLASS'); +- expect(ElementKind.COMPILATION_UNIT.toString(), +- 'ElementKind.COMPILATION_UNIT'); +- } +-} +- +-@reflectiveTest +-class ElementTest extends AbstractContextTest { +- engine.Element findElementInUnit(engine.CompilationUnit unit, String name, +- [engine.ElementKind kind]) { +- return findElementsByName(unit, name) +- .where((e) => kind == null || e.kind == kind) +- .single; +- } +- +- test_fromElement_CLASS() async { +- engine.Source source = addSource('/test.dart', ''' +-@deprecated +-abstract class _A {} +-class B {}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- { +- engine.ClassElement engineElement = findElementInUnit(unit, '_A'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.CLASS); +- expect(element.name, '_A'); +- expect(element.typeParameters, isNull); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 27); +- expect(location.length, '_A'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 16); +- } +- expect(element.parameters, isNull); +- expect( +- element.flags, +- Element.FLAG_ABSTRACT | +- Element.FLAG_DEPRECATED | +- Element.FLAG_PRIVATE); +- } +- { +- engine.ClassElement engineElement = findElementInUnit(unit, 'B'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.CLASS); +- expect(element.name, 'B'); +- expect(element.typeParameters, ''); +- expect(element.flags, 0); +- } +- } +- +- test_fromElement_CONSTRUCTOR() async { +- engine.Source source = addSource('/test.dart', ''' +-class A { +- const A.myConstructor(int a, [String b]); +-}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.ConstructorElement engineElement = +- findElementInUnit(unit, 'myConstructor'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.CONSTRUCTOR); +- expect(element.name, 'myConstructor'); +- expect(element.typeParameters, isNull); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 20); +- expect(location.length, 'myConstructor'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 11); +- } +- expect(element.parameters, '(int a, [String b])'); +- expect(element.returnType, 'A'); +- expect(element.flags, Element.FLAG_CONST); +- } +- +- void test_fromElement_dynamic() { +- var engineElement = engine.DynamicElementImpl.instance; +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.UNKNOWN); +- expect(element.name, 'dynamic'); +- expect(element.location, isNull); +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- expect(element.flags, 0); +- } +- +- test_fromElement_ENUM() async { +- engine.Source source = addSource('/test.dart', ''' +-@deprecated +-enum _E1 { one, two } +-enum E2 { three, four }'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- { +- engine.ClassElement engineElement = findElementInUnit(unit, '_E1'); +- expect(engineElement.isDeprecated, isTrue); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.ENUM); +- expect(element.name, '_E1'); +- expect(element.typeParameters, isNull); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 17); +- expect(location.length, '_E1'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 6); +- } +- expect(element.parameters, isNull); +- expect( +- element.flags, +- (engineElement.isDeprecated ? Element.FLAG_DEPRECATED : 0) | +- Element.FLAG_PRIVATE); +- } +- { +- engine.ClassElement engineElement = findElementInUnit(unit, 'E2'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.ENUM); +- expect(element.name, 'E2'); +- expect(element.typeParameters, isNull); +- expect(element.flags, 0); +- } +- } +- +- test_fromElement_ENUM_CONSTANT() async { +- engine.Source source = addSource('/test.dart', ''' +-@deprecated +-enum _E1 { one, two } +-enum E2 { three, four }'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- { +- engine.FieldElement engineElement = findElementInUnit(unit, 'one'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.ENUM_CONSTANT); +- expect(element.name, 'one'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 23); +- expect(location.length, 'one'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 12); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, '_E1'); +- // TODO(danrubel) determine why enum constant is not marked as deprecated +- //engine.ClassElement classElement = engineElement.enclosingElement; +- //expect(classElement.isDeprecated, isTrue); +- expect( +- element.flags, +- // Element.FLAG_DEPRECATED | +- Element.FLAG_CONST | Element.FLAG_STATIC); +- } +- { +- engine.FieldElement engineElement = findElementInUnit(unit, 'three'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.ENUM_CONSTANT); +- expect(element.name, 'three'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 44); +- expect(location.length, 'three'.length); +- expect(location.startLine, 3); +- expect(location.startColumn, 11); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, 'E2'); +- expect(element.flags, Element.FLAG_CONST | Element.FLAG_STATIC); +- } +- { +- engine.FieldElement engineElement = +- unit.element.enums[1].getField('index'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, 'index'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, -1); +- expect(location.length, 'index'.length); +- expect(location.startLine, 1); +- expect(location.startColumn, 0); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, 'int'); +- expect(element.flags, Element.FLAG_FINAL); +- } +- { +- engine.FieldElement engineElement = +- unit.element.enums[1].getField('values'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, 'values'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, -1); +- expect(location.length, 'values'.length); +- expect(location.startLine, 1); +- expect(location.startColumn, 0); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, 'List'); +- expect(element.flags, Element.FLAG_CONST | Element.FLAG_STATIC); +- } +- } +- +- test_fromElement_FIELD() async { +- engine.Source source = addSource('/test.dart', ''' +-class A { +- static const myField = 42; +-}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.FieldElement engineElement = findElementInUnit(unit, 'myField'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, 'myField'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 25); +- expect(location.length, 'myField'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 16); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, 'int'); +- expect(element.flags, Element.FLAG_CONST | Element.FLAG_STATIC); +- } +- +- test_fromElement_FUNCTION_TYPE_ALIAS() async { +- engine.Source source = addSource('/test.dart', ''' +-typedef int F(String x); +-'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.FunctionTypeAliasElement engineElement = +- findElementInUnit(unit, 'F'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS); +- expect(element.name, 'F'); +- expect(element.typeParameters, ''); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 12); +- expect(location.length, 'F'.length); +- expect(location.startLine, 1); +- expect(location.startColumn, 13); +- } +- expect(element.parameters, '(String x)'); +- expect(element.returnType, 'int'); +- expect(element.flags, 0); +- } +- +- test_fromElement_GETTER() async { +- engine.Source source = addSource('/test.dart', ''' +-class A { +- String get myGetter => 42; +-}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.PropertyAccessorElement engineElement = +- findElementInUnit(unit, 'myGetter', engine.ElementKind.GETTER); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.GETTER); +- expect(element.name, 'myGetter'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 23); +- expect(location.length, 'myGetter'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 14); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, 'String'); +- expect(element.flags, 0); +- } +- +- test_fromElement_LABEL() async { +- engine.Source source = addSource('/test.dart', ''' +-main() { +-myLabel: +- while (true) { +- break myLabel; +- } +-}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.LabelElement engineElement = findElementInUnit(unit, 'myLabel'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.LABEL); +- expect(element.name, 'myLabel'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 9); +- expect(location.length, 'myLabel'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 1); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- expect(element.flags, 0); +- } +- +- test_fromElement_METHOD() async { +- engine.Source source = addSource('/test.dart', ''' +-class A { +- static List myMethod(int a, {String b, int c}) { +- return null; +- } +-}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.MethodElement engineElement = findElementInUnit(unit, 'myMethod'); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.METHOD); +- expect(element.name, 'myMethod'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 32); +- expect(location.length, 'myGetter'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 23); +- } +- expect(element.parameters, '(int a, {String b, int c})'); +- expect(element.returnType, 'List'); +- expect(element.flags, Element.FLAG_STATIC); +- } +- +- test_fromElement_SETTER() async { +- engine.Source source = addSource('/test.dart', ''' +-class A { +- set mySetter(String x) {} +-}'''); +- engine.CompilationUnit unit = await resolveLibraryUnit(source); +- engine.PropertyAccessorElement engineElement = +- findElementInUnit(unit, 'mySetter', engine.ElementKind.SETTER); +- // create notification Element +- Element element = convertElement(engineElement); +- expect(element.kind, ElementKind.SETTER); +- expect(element.name, 'mySetter'); +- { +- Location location = element.location; +- expect(location.file, '/test.dart'); +- expect(location.offset, 16); +- expect(location.length, 'mySetter'.length); +- expect(location.startLine, 2); +- expect(location.startColumn, 7); +- } +- expect(element.parameters, '(String x)'); +- expect(element.returnType, isNull); +- expect(element.flags, 0); +- } +-} +diff --git a/pkg/analysis_server/test/plugin/test_all.dart b/pkg/analysis_server/test/plugin/test_all.dart +deleted file mode 100644 +index 8390a16e680..00000000000 +--- a/pkg/analysis_server/test/plugin/test_all.dart ++++ /dev/null +@@ -1,16 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'protocol_dart_test.dart' as protocol_dart_test; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- defineReflectiveSuite(() { +- protocol_dart_test.main(); +- }, name: 'plugin'); +-} +diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart +deleted file mode 100644 +index df05a2ba66b..00000000000 +--- a/pkg/analysis_server/test/protocol_server_test.dart ++++ /dev/null +@@ -1,196 +0,0 @@ +-// Copyright (c) 2014, 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:mirrors'; +- +-import 'package:analysis_server/src/constants.dart'; +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analyzer/dart/ast/ast.dart' as engine; +-import 'package:analyzer/dart/element/element.dart' as engine; +-import 'package:analyzer/dart/element/type.dart' as engine; +-import 'package:analyzer/error/error.dart' as engine; +-import 'package:analyzer/src/error/codes.dart' as engine; +-import 'package:analyzer/src/generated/source.dart' as engine; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:mockito/mockito.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AnalysisErrorTest); +- defineReflectiveTests(EnumTest); +- }); +-} +- +-class AnalysisErrorMock extends Mock implements engine.AnalysisError {} +- +-@reflectiveTest +-class AnalysisErrorTest { +- engine.Source source = new MockSource(); +- engine.LineInfo lineInfo; +- engine.AnalysisError engineError = new AnalysisErrorMock(); +- +- void setUp() { +- // prepare Source +- when(source.fullName).thenReturn('foo.dart'); +- // prepare LineInfo +- lineInfo = new engine.LineInfo([0, 5, 9, 20]); +- // prepare AnalysisError +- when(engineError.source).thenReturn(source); +- when(engineError.errorCode) +- .thenReturn(engine.CompileTimeErrorCode.AMBIGUOUS_EXPORT); +- when(engineError.message).thenReturn('my message'); +- when(engineError.offset).thenReturn(10); +- when(engineError.length).thenReturn(20); +- } +- +- void tearDown() { +- source = null; +- engineError = null; +- } +- +- void test_fromEngine_hasCorrection() { +- when(engineError.correction).thenReturn('my correction'); +- AnalysisError error = newAnalysisError_fromEngine(lineInfo, engineError); +- expect(error.toJson(), { +- SEVERITY: 'ERROR', +- TYPE: 'COMPILE_TIME_ERROR', +- LOCATION: { +- FILE: 'foo.dart', +- OFFSET: 10, +- LENGTH: 20, +- START_LINE: 3, +- START_COLUMN: 2 +- }, +- MESSAGE: 'my message', +- CORRECTION: 'my correction', +- CODE: 'ambiguous_export', +- HAS_FIX: false +- }); +- } +- +- void test_fromEngine_noCorrection() { +- when(engineError.correction).thenReturn(null); +- AnalysisError error = newAnalysisError_fromEngine(lineInfo, engineError); +- expect(error.toJson(), { +- SEVERITY: 'ERROR', +- TYPE: 'COMPILE_TIME_ERROR', +- LOCATION: { +- FILE: 'foo.dart', +- OFFSET: 10, +- LENGTH: 20, +- START_LINE: 3, +- START_COLUMN: 2 +- }, +- MESSAGE: 'my message', +- CODE: 'ambiguous_export', +- HAS_FIX: false +- }); +- } +- +- void test_fromEngine_noLineInfo() { +- when(engineError.correction).thenReturn(null); +- AnalysisError error = newAnalysisError_fromEngine(null, engineError); +- expect(error.toJson(), { +- SEVERITY: 'ERROR', +- TYPE: 'COMPILE_TIME_ERROR', +- LOCATION: { +- FILE: 'foo.dart', +- OFFSET: 10, +- LENGTH: 20, +- START_LINE: -1, +- START_COLUMN: -1 +- }, +- MESSAGE: 'my message', +- CODE: 'ambiguous_export', +- HAS_FIX: false +- }); +- } +-} +- +-@reflectiveTest +-class EnumTest { +- void test_AnalysisErrorSeverity() { +- new EnumTester().run( +- (engine.ErrorSeverity engineErrorSeverity) => +- new AnalysisErrorSeverity(engineErrorSeverity.name), +- exceptions: {engine.ErrorSeverity.NONE: null}); +- } +- +- void test_AnalysisErrorType() { +- new EnumTester().run( +- (engine.ErrorType engineErrorType) => +- new AnalysisErrorType(engineErrorType.name)); +- } +- +- void test_ElementKind() { +- new EnumTester() +- .run(convertElementKind, exceptions: { +- // TODO(paulberry): do any of the exceptions below constitute bugs? +- engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN, +- engine.ElementKind.ERROR: ElementKind.UNKNOWN, +- engine.ElementKind.EXPORT: ElementKind.UNKNOWN, +- engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.UNKNOWN, +- engine.ElementKind.IMPORT: ElementKind.UNKNOWN, +- engine.ElementKind.NAME: ElementKind.UNKNOWN, +- engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN +- }); +- } +- +- void test_SearchResultKind() { +- // TODO(paulberry): why does the MatchKind class exist at all? Can't we +- // use SearchResultKind inside the analysis server? +- new EnumTester() +- .run(newSearchResultKind_fromEngine); +- } +-} +- +-/** +- * Helper class for testing the correspondence between an analysis engine enum +- * and an analysis server API enum. +- */ +-class EnumTester { +- /** +- * Test that the function [convert] properly converts all possible values of +- * [EngineEnum] to an [ApiEnum] with the same name, with the exceptions noted +- * in [exceptions]. For each key in [exceptions], if the corresponding value +- * is null, then we check that converting the given key results in an error. +- * If the corresponding value is an [ApiEnum], then we check that converting +- * the given key results in the given value. +- */ +- void run(ApiEnum convert(EngineEnum value), +- {Map exceptions: const {}}) { +- ClassMirror engineClass = reflectClass(EngineEnum); +- engineClass.staticMembers.forEach((Symbol symbol, MethodMirror method) { +- if (symbol == #values) { +- return; +- } +- if (!method.isGetter) { +- return; +- } +- String enumName = MirrorSystem.getName(symbol); +- EngineEnum engineValue = +- engineClass.getField(symbol).reflectee as EngineEnum; +- expect(engineValue, new isInstanceOf()); +- if (exceptions.containsKey(engineValue)) { +- ApiEnum expectedResult = exceptions[engineValue]; +- if (expectedResult == null) { +- expect(() { +- convert(engineValue); +- }, throwsException); +- } else { +- ApiEnum apiValue = convert(engineValue); +- expect(apiValue, equals(expectedResult)); +- } +- } else { +- ApiEnum apiValue = convert(engineValue); +- expect((apiValue as dynamic).name, equals(enumName)); +- } +- }); +- } +-} +diff --git a/pkg/analysis_server/test/protocol_test.dart b/pkg/analysis_server/test/protocol_test.dart +deleted file mode 100644 +index ff48b1e8065..00000000000 +--- a/pkg/analysis_server/test/protocol_test.dart ++++ /dev/null +@@ -1,270 +0,0 @@ +-// Copyright (c) 2014, 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:convert'; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/constants.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(NotificationTest); +- defineReflectiveTests(RequestTest); +- defineReflectiveTests(RequestErrorTest); +- defineReflectiveTests(ResponseTest); +- }); +-} +- +-@reflectiveTest +-class InvalidParameterResponseMatcher extends Matcher { +- static const String ERROR_CODE = 'INVALID_PARAMETER'; +- +- @override +- Description describe(Description description) => +- description.add("an 'invalid parameter' response (code $ERROR_CODE)"); +- +- @override +- bool matches(item, Map matchState) { +- if (item is! RequestFailure) { +- return false; +- } +- var response = item.response; +- if (response is! Response) { +- return false; +- } +- if (response.error is! RequestError) { +- return false; +- } +- RequestError requestError = response.error; +- if (requestError.code != ERROR_CODE) { +- return false; +- } +- return true; +- } +-} +- +-@reflectiveTest +-class NotificationTest { +- void test_fromJson() { +- Notification original = new Notification('foo'); +- Notification notification = new Notification.fromJson(original.toJson()); +- expect(notification.event, equals('foo')); +- expect(notification.toJson().keys, isNot(contains('params'))); +- } +- +- void test_fromJson_withParams() { +- Notification original = new Notification('foo', {'x': 'y'}); +- Notification notification = new Notification.fromJson(original.toJson()); +- expect(notification.event, equals('foo')); +- expect(notification.toJson()['params'], equals({'x': 'y'})); +- } +- +- void test_toJson_noParams() { +- Notification notification = new Notification('foo'); +- expect(notification.event, equals('foo')); +- expect(notification.toJson().keys, isNot(contains('params'))); +- expect(notification.toJson(), equals({'event': 'foo'})); +- } +- +- void test_toJson_withParams() { +- Notification notification = new Notification('foo', {'x': 'y'}); +- expect(notification.event, equals('foo')); +- expect(notification.toJson()['params'], equals({'x': 'y'})); +- expect( +- notification.toJson(), +- equals({ +- 'event': 'foo', +- 'params': {'x': 'y'} +- })); +- } +-} +- +-@reflectiveTest +-class RequestErrorTest { +- void test_create() { +- RequestError error = +- new RequestError(RequestErrorCode.INVALID_REQUEST, 'msg'); +- expect(error.code, RequestErrorCode.INVALID_REQUEST); +- expect(error.message, "msg"); +- expect(error.toJson(), equals({CODE: 'INVALID_REQUEST', MESSAGE: "msg"})); +- } +- +- void test_fromJson() { +- var trace = 'a stack trace\r\nfoo'; +- var json = { +- CODE: RequestErrorCode.INVALID_PARAMETER.name, +- MESSAGE: 'foo', +- STACK_TRACE: trace +- }; +- RequestError error = +- new RequestError.fromJson(new ResponseDecoder(null), '', json); +- expect(error.code, RequestErrorCode.INVALID_PARAMETER); +- expect(error.message, "foo"); +- expect(error.stackTrace, trace); +- } +- +- void test_toJson() { +- var trace = 'a stack trace\r\nbar'; +- RequestError error = new RequestError( +- RequestErrorCode.UNKNOWN_REQUEST, 'msg', +- stackTrace: trace); +- expect(error.toJson(), +- {CODE: 'UNKNOWN_REQUEST', MESSAGE: 'msg', STACK_TRACE: trace}); +- } +-} +- +-@reflectiveTest +-class RequestTest { +- void test_fromJson() { +- Request original = new Request('one', 'aMethod'); +- String json = JSON.encode(original.toJson()); +- Request request = new Request.fromString(json); +- expect(request.id, equals('one')); +- expect(request.method, equals('aMethod')); +- expect(request.clientRequestTime, isNull); +- } +- +- void test_fromJson_invalidId() { +- String json = +- '{"id":{"one":"two"},"method":"aMethod","params":{"foo":"bar"}}'; +- Request request = new Request.fromString(json); +- expect(request, isNull); +- } +- +- void test_fromJson_invalidMethod() { +- String json = +- '{"id":"one","method":{"boo":"aMethod"},"params":{"foo":"bar"}}'; +- Request request = new Request.fromString(json); +- expect(request, isNull); +- } +- +- void test_fromJson_invalidParams() { +- String json = '{"id":"one","method":"aMethod","params":"foobar"}'; +- Request request = new Request.fromString(json); +- expect(request, isNull); +- } +- +- void test_fromJson_withBadClientTime() { +- Request original = new Request('one', 'aMethod', null, 347); +- Map map = original.toJson(); +- // Insert bad value - should be int but client sent string instead +- map[Request.CLIENT_REQUEST_TIME] = '347'; +- String json = JSON.encode(map); +- Request request = new Request.fromString(json); +- expect(request, isNull); +- } +- +- void test_fromJson_withClientTime() { +- Request original = new Request('one', 'aMethod', null, 347); +- String json = JSON.encode(original.toJson()); +- Request request = new Request.fromString(json); +- expect(request.id, equals('one')); +- expect(request.method, equals('aMethod')); +- expect(request.clientRequestTime, 347); +- } +- +- void test_fromJson_withParams() { +- Request original = new Request('one', 'aMethod', {'foo': 'bar'}); +- String json = JSON.encode(original.toJson()); +- Request request = new Request.fromString(json); +- expect(request.id, equals('one')); +- expect(request.method, equals('aMethod')); +- expect(request.toJson()['params'], equals({'foo': 'bar'})); +- } +- +- void test_toJson() { +- Request request = new Request('one', 'aMethod'); +- expect(request.toJson(), +- equals({Request.ID: 'one', Request.METHOD: 'aMethod'})); +- } +- +- void test_toJson_withParams() { +- Request request = new Request('one', 'aMethod', {'foo': 'bar'}); +- expect( +- request.toJson(), +- equals({ +- Request.ID: 'one', +- Request.METHOD: 'aMethod', +- Request.PARAMS: {'foo': 'bar'} +- })); +- } +-} +- +-@reflectiveTest +-class ResponseTest { +- void test_create_invalidRequestFormat() { +- Response response = new Response.invalidRequestFormat(); +- expect(response.id, equals('')); +- expect(response.error, isNotNull); +- expect( +- response.toJson(), +- equals({ +- Response.ID: '', +- Response.ERROR: { +- 'code': 'INVALID_REQUEST', +- 'message': 'Invalid request' +- } +- })); +- } +- +- void test_create_unanalyzedPriorityFiles() { +- Response response = new Response.unanalyzedPriorityFiles('0', 'file list'); +- expect(response.id, equals('0')); +- expect(response.error, isNotNull); +- expect( +- response.toJson(), +- equals({ +- Response.ID: '0', +- Response.ERROR: { +- 'code': 'UNANALYZED_PRIORITY_FILES', +- 'message': "Unanalyzed files cannot be a priority: 'file list'" +- } +- })); +- } +- +- void test_create_unknownRequest() { +- Response response = new Response.unknownRequest(new Request('0', '')); +- expect(response.id, equals('0')); +- expect(response.error, isNotNull); +- expect( +- response.toJson(), +- equals({ +- Response.ID: '0', +- Response.ERROR: { +- 'code': 'UNKNOWN_REQUEST', +- 'message': 'Unknown request' +- } +- })); +- } +- +- void test_fromJson() { +- Response original = new Response('myId'); +- Response response = new Response.fromJson(original.toJson()); +- expect(response.id, equals('myId')); +- } +- +- void test_fromJson_withError() { +- Response original = new Response.invalidRequestFormat(); +- Response response = new Response.fromJson(original.toJson()); +- expect(response.id, equals('')); +- expect(response.error, isNotNull); +- RequestError error = response.error; +- expect(error.code, equals(RequestErrorCode.INVALID_REQUEST)); +- expect(error.message, equals('Invalid request')); +- } +- +- void test_fromJson_withResult() { +- Response original = new Response('myId', result: {'foo': 'bar'}); +- Response response = new Response.fromJson(original.toJson()); +- expect(response.id, equals('myId')); +- Map result = +- response.toJson()['result'] as Map; +- expect(result.length, equals(1)); +- expect(result['foo'], equals('bar')); +- } +-} +diff --git a/pkg/analysis_server/test/search/abstract_search_domain.dart b/pkg/analysis_server/test/search/abstract_search_domain.dart +deleted file mode 100644 +index dc83c5a96cd..00000000000 +--- a/pkg/analysis_server/test/search/abstract_search_domain.dart ++++ /dev/null +@@ -1,113 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/search/search_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +- +-import '../analysis_abstract.dart'; +- +-class AbstractSearchDomainTest extends AbstractAnalysisTest { +- final Map resultSets = {}; +- String searchId; +- List results = []; +- SearchResult result; +- +- void assertHasResult(SearchResultKind kind, String search, [int length]) { +- int offset = findOffset(search); +- if (length == null) { +- length = findIdentifierLength(search); +- } +- findResult(kind, testFile, offset, length, true); +- } +- +- void assertNoResult(SearchResultKind kind, String search, [int length]) { +- int offset = findOffset(search); +- if (length == null) { +- length = findIdentifierLength(search); +- } +- findResult(kind, testFile, offset, length, false); +- } +- +- void findResult(SearchResultKind kind, String file, int offset, int length, +- bool expected) { +- for (SearchResult result in results) { +- Location location = result.location; +- if (result.kind == kind && +- location.file == file && +- location.offset == offset && +- location.length == length) { +- if (!expected) { +- fail('Unexpected result $result in\n' + results.join('\n')); +- } +- this.result = result; +- return; +- } +- } +- if (expected) { +- fail( +- 'Not found: "search" kind=$kind offset=$offset length=$length\nin\n' + +- results.join('\n')); +- } +- } +- +- String getPathString(List path) { +- return path.map((Element element) { +- String kindName = element.kind.name; +- String name = element.name; +- if (name.isEmpty) { +- return kindName; +- } else { +- return '$kindName $name'; +- } +- }).join('\n'); +- } +- +- @override +- void processNotification(Notification notification) { +- super.processNotification(notification); +- if (notification.event == SEARCH_NOTIFICATION_RESULTS) { +- var params = new SearchResultsParams.fromNotification(notification); +- String id = params.id; +- _ResultSet resultSet = resultSets[id]; +- if (resultSet == null) { +- resultSet = new _ResultSet(id); +- resultSets[id] = resultSet; +- } +- resultSet.results.addAll(params.results); +- resultSet.done = params.isLast; +- } +- } +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- server.handlers = [ +- new SearchDomainHandler(server), +- ]; +- } +- +- Future waitForSearchResults() { +- _ResultSet resultSet = resultSets[searchId]; +- if (resultSet != null && resultSet.done) { +- results = resultSet.results; +- return new Future.value(); +- } +- return new Future.delayed(Duration.ZERO, waitForSearchResults); +- } +-} +- +-class _ResultSet { +- final String id; +- final List results = []; +- bool done = false; +- +- _ResultSet(this.id); +-} +diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart +deleted file mode 100644 +index 3e411f4496c..00000000000 +--- a/pkg/analysis_server/test/search/element_references_test.dart ++++ /dev/null +@@ -1,674 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_search_domain.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ElementReferencesTest); +- }); +-} +- +-@reflectiveTest +-class ElementReferencesTest extends AbstractSearchDomainTest { +- Element searchElement; +- +- void assertHasRef(SearchResultKind kind, String search, bool isPotential) { +- assertHasResult(kind, search); +- expect(result.isPotential, isPotential); +- } +- +- Future findElementReferences( +- String search, bool includePotential) async { +- int offset = findOffset(search); +- await waitForTasksFinished(); +- Request request = new SearchFindElementReferencesParams( +- testFile, offset, includePotential) +- .toRequest('0'); +- Response response = await waitResponse(request); +- var result = new SearchFindElementReferencesResult.fromResponse(response); +- searchId = result.id; +- searchElement = result.element; +- if (searchId != null) { +- await waitForSearchResults(); +- } +- expect(serverErrors, isEmpty); +- } +- +- test_constructor_named() async { +- addTestFile(''' +-class A { +- A.named(p); +-} +-main() { +- new A.named(1); +- new A.named(2); +-} +-'''); +- await findElementReferences('named(p)', false); +- expect(searchElement.kind, ElementKind.CONSTRUCTOR); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.REFERENCE, '.named(1)', 6); +- assertHasResult(SearchResultKind.REFERENCE, '.named(2)', 6); +- } +- +- test_constructor_named_potential() async { +- // Constructors in other classes shouldn't be considered potential matches, +- // nor should unresolved method calls, since constructor call sites are +- // statically bound to their targets). +- addTestFile(''' +-class A { +- A.named(p); // A +-} +-class B { +- B.named(p); +-} +-f(x) { +- new A.named(1); +- new B.named(2); +- x.named(3); +-} +-'''); +- await findElementReferences('named(p); // A', true); +- expect(searchElement.kind, ElementKind.CONSTRUCTOR); +- expect(results, hasLength(1)); +- assertHasResult(SearchResultKind.REFERENCE, '.named(1)', 6); +- } +- +- test_constructor_unnamed() async { +- addTestFile(''' +-class A { +- A(p); +-} +-main() { +- new A(1); +- new A(2); +-} +-'''); +- await findElementReferences('A(p)', false); +- expect(searchElement.kind, ElementKind.CONSTRUCTOR); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.REFERENCE, '(1)', 0); +- assertHasResult(SearchResultKind.REFERENCE, '(2)', 0); +- } +- +- test_constructor_unnamed_potential() async { +- // Constructors in other classes shouldn't be considered potential matches, +- // even if they are also unnamed (since constructor call sites are +- // statically bound to their targets). +- // Also, assignments to local variables shouldn't be considered potential +- // matches. +- addTestFile(''' +-class A { +- A(p); // A +-} +-class B { +- B(p); +- foo() { +- int k; +- k = 3; +- } +-} +-main() { +- new A(1); +- new B(2); +-} +-'''); +- await findElementReferences('A(p)', true); +- expect(searchElement.kind, ElementKind.CONSTRUCTOR); +- expect(results, hasLength(1)); +- assertHasResult(SearchResultKind.REFERENCE, '(1)', 0); +- } +- +- test_field_explicit() async { +- addTestFile(''' +-class A { +- var fff; // declaration +- A(this.fff); // in constructor +- A.named() : fff = 1; +- m() { +- fff = 2; +- fff += 3; +- print(fff); // in m() +- fff(); // in m() +- } +-} +-main(A a) { +- a.fff = 20; +- a.fff += 30; +- print(a.fff); // in main() +- a.fff(); // in main() +-} +-'''); +- await findElementReferences('fff; // declaration', false); +- expect(searchElement.kind, ElementKind.FIELD); +- expect(results, hasLength(10)); +- assertHasResult(SearchResultKind.WRITE, 'fff); // in constructor'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 1;'); +- // m() +- assertHasResult(SearchResultKind.WRITE, 'fff = 2;'); +- assertHasResult(SearchResultKind.WRITE, 'fff += 3;'); +- assertHasResult(SearchResultKind.READ, 'fff); // in m()'); +- assertHasResult(SearchResultKind.INVOCATION, 'fff(); // in m()'); +- // main() +- assertHasResult(SearchResultKind.WRITE, 'fff = 20;'); +- assertHasResult(SearchResultKind.WRITE, 'fff += 30;'); +- assertHasResult(SearchResultKind.READ, 'fff); // in main()'); +- assertHasResult(SearchResultKind.INVOCATION, 'fff(); // in main()'); +- } +- +- test_field_implicit() async { +- addTestFile(''' +-class A { +- var get fff => null; +- void set fff(x) {} +- m() { +- print(fff); // in m() +- fff = 1; +- } +-} +-main(A a) { +- print(a.fff); // in main() +- a.fff = 10; +-} +-'''); +- { +- await findElementReferences('fff =>', false); +- expect(searchElement.kind, ElementKind.FIELD); +- expect(results, hasLength(4)); +- assertHasResult(SearchResultKind.READ, 'fff); // in m()'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 1;'); +- assertHasResult(SearchResultKind.READ, 'fff); // in main()'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 10;'); +- } +- { +- await findElementReferences('fff(x) {}', false); +- expect(results, hasLength(4)); +- assertHasResult(SearchResultKind.READ, 'fff); // in m()'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 1;'); +- assertHasResult(SearchResultKind.READ, 'fff); // in main()'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 10;'); +- } +- } +- +- test_field_inFormalParameter() async { +- addTestFile(''' +-class A { +- var fff; // declaration +- A(this.fff); // in constructor +- m() { +- fff = 2; +- print(fff); // in m() +- } +-} +-'''); +- await findElementReferences('fff); // in constructor', false); +- expect(searchElement.kind, ElementKind.FIELD); +- expect(results, hasLength(3)); +- assertHasResult(SearchResultKind.WRITE, 'fff); // in constructor'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 2;'); +- assertHasResult(SearchResultKind.READ, 'fff); // in m()'); +- } +- +- test_function() async { +- addTestFile(''' +-fff(p) {} +-main() { +- fff(1); +- print(fff); +-} +-'''); +- await findElementReferences('fff(p) {}', false); +- expect(searchElement.kind, ElementKind.FUNCTION); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.INVOCATION, 'fff(1)'); +- assertHasResult(SearchResultKind.REFERENCE, 'fff);'); +- } +- +- test_hierarchy_field_explicit() async { +- addTestFile(''' +- class A { +- int fff; // in A +- } +- class B extends A { +- int fff; // in B +- } +- class C extends B { +- int fff; // in C +- } +- main(A a, B b, C c) { +- a.fff = 10; +- b.fff = 20; +- c.fff = 30; +- } +- '''); +- await findElementReferences('fff; // in B', false); +- expect(searchElement.kind, ElementKind.FIELD); +- assertHasResult(SearchResultKind.WRITE, 'fff = 10;'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 20;'); +- assertHasResult(SearchResultKind.WRITE, 'fff = 30;'); +- } +- +- test_hierarchy_method() async { +- addTestFile(''' +-class A { +- mmm(_) {} // in A +-} +-class B extends A { +- mmm(_) {} // in B +-} +-class C extends B { +- mmm(_) {} // in C +-} +-main(A a, B b, C c) { +- a.mmm(10); +- b.mmm(20); +- c.mmm(30); +-} +-'''); +- await findElementReferences('mmm(_) {} // in B', false); +- expect(searchElement.kind, ElementKind.METHOD); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(10)'); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(20)'); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(30)'); +- } +- +- test_hierarchy_method_static() async { +- addTestFile(''' +-class A { +- static void mmm(_) {} // in A +-} +-class B extends A { +- static void mmm(_) {} // in B +-} +-class C extends B { +- static void mmm(_) {} // in C +-} +-main() { +- A.mmm(10); +- B.mmm(20); +- C.mmm(30); +-} +-'''); +- await findElementReferences('mmm(_) {} // in B', false); +- expect(searchElement.kind, ElementKind.METHOD); +- expect(results, hasLength(1)); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(20)'); +- } +- +- test_label() async { +- addTestFile(''' +-main() { +-myLabel: +- for (int i = 0; i < 10; i++) { +- if (i == 2) { +- continue myLabel; // continue +- } +- break myLabel; // break +- } +-} +-'''); +- await findElementReferences('myLabel; // break', false); +- expect(searchElement.kind, ElementKind.LABEL); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.REFERENCE, 'myLabel; // continue'); +- assertHasResult(SearchResultKind.REFERENCE, 'myLabel; // break'); +- } +- +- test_localVariable() async { +- addTestFile(''' +-main() { +- var vvv = 1; +- print(vvv); +- vvv += 3; +- vvv = 2; +- vvv(); +-} +-'''); +- await findElementReferences('vvv = 1', false); +- expect(searchElement.kind, ElementKind.LOCAL_VARIABLE); +- expect(results, hasLength(4)); +- assertHasResult(SearchResultKind.READ, 'vvv);'); +- assertHasResult(SearchResultKind.READ_WRITE, 'vvv += 3'); +- assertHasResult(SearchResultKind.WRITE, 'vvv = 2'); +- assertHasResult(SearchResultKind.INVOCATION, 'vvv();'); +- } +- +- test_method() async { +- addTestFile(''' +-class A { +- mmm(p) {} +- m() { +- mmm(1); +- print(mmm); // in m() +- } +-} +-main(A a) { +- a.mmm(10); +- print(a.mmm); // in main() +-} +-'''); +- await findElementReferences('mmm(p) {}', false); +- expect(searchElement.kind, ElementKind.METHOD); +- expect(results, hasLength(4)); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(1);'); +- assertHasResult(SearchResultKind.REFERENCE, 'mmm); // in m()'); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(10);'); +- assertHasResult(SearchResultKind.REFERENCE, 'mmm); // in main()'); +- } +- +- test_method_propagatedType() async { +- addTestFile(''' +-class A { +- mmm(p) {} +-} +-main() { +- var a = new A(); +- a.mmm(10); +- print(a.mmm); +-} +-'''); +- await findElementReferences('mmm(p) {}', false); +- expect(searchElement.kind, ElementKind.METHOD); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.INVOCATION, 'mmm(10);'); +- assertHasResult(SearchResultKind.REFERENCE, 'mmm);'); +- } +- +- test_noElement() async { +- addTestFile(''' +-main() { +- print(noElement); +-} +-'''); +- await findElementReferences('noElement', false); +- expect(searchId, isNull); +- } +- +- test_oneUnit_zeroLibraries() async { +- addTestFile(''' +-part of lib; +-fff(p) {} +-main() { +- fff(10); +-} +-'''); +- await findElementReferences('fff(p) {}', false); +- expect(results, hasLength(1)); +- assertHasResult(SearchResultKind.INVOCATION, 'fff(10);'); +- } +- +- test_parameter() async { +- addTestFile(''' +-main(ppp) { +- print(ppp); +- ppp += 3; +- ppp = 2; +- ppp(); +-} +-'''); +- await findElementReferences('ppp) {', false); +- expect(searchElement.kind, ElementKind.PARAMETER); +- expect(results, hasLength(4)); +- assertHasResult(SearchResultKind.READ, 'ppp);'); +- assertHasResult(SearchResultKind.READ_WRITE, 'ppp += 3'); +- assertHasResult(SearchResultKind.WRITE, 'ppp = 2'); +- assertHasResult(SearchResultKind.INVOCATION, 'ppp();'); +- } +- +- @failingTest +- test_path_inConstructor_named() async { +- // The path does not contain the first expected element. +- addTestFile(''' +-library my_lib; +-class A {} +-class B { +- B.named() { +- A a = null; +- } +-} +-'''); +- await findElementReferences('A {}', false); +- assertHasResult(SearchResultKind.REFERENCE, 'A a = null;'); +- expect(getPathString(result.path), ''' +-LOCAL_VARIABLE a +-CONSTRUCTOR named +-CLASS B +-COMPILATION_UNIT test.dart +-LIBRARY my_lib'''); +- } +- +- @failingTest +- test_path_inConstructor_unnamed() async { +- // The path does not contain the first expected element. +- addTestFile(''' +-library my_lib; +-class A {} +-class B { +- B() { +- A a = null; +- } +-} +-'''); +- await findElementReferences('A {}', false); +- assertHasResult(SearchResultKind.REFERENCE, 'A a = null;'); +- expect(getPathString(result.path), ''' +-LOCAL_VARIABLE a +-CONSTRUCTOR +-CLASS B +-COMPILATION_UNIT test.dart +-LIBRARY my_lib'''); +- } +- +- @failingTest +- test_path_inFunction() async { +- // The path does not contain the first expected element. +- addTestFile(''' +-library my_lib; +-class A {} +-main() { +- A a = null; +-} +-'''); +- await findElementReferences('A {}', false); +- assertHasResult(SearchResultKind.REFERENCE, 'A a = null;'); +- expect(getPathString(result.path), ''' +-LOCAL_VARIABLE a +-FUNCTION main +-COMPILATION_UNIT test.dart +-LIBRARY my_lib'''); +- } +- +- test_potential_disabled() async { +- addTestFile(''' +-class A { +- test(p) {} +-} +-main(A a, p) { +- a.test(1); +- p.test(2); +-} +-'''); +- await findElementReferences('test(p) {}', false); +- assertHasResult(SearchResultKind.INVOCATION, 'test(1);'); +- assertNoResult(SearchResultKind.INVOCATION, 'test(2);'); +- } +- +- test_potential_field() async { +- addTestFile(''' +-class A { +- var test; // declaration +-} +-main(A a, p) { +- a.test = 1; +- p.test = 2; +- print(p.test); // p +-} +-'''); +- await findElementReferences('test; // declaration', true); +- { +- assertHasResult(SearchResultKind.WRITE, 'test = 1;'); +- expect(result.isPotential, isFalse); +- } +- { +- assertHasResult(SearchResultKind.WRITE, 'test = 2;'); +- expect(result.isPotential, isTrue); +- } +- { +- assertHasResult(SearchResultKind.READ, 'test); // p'); +- expect(result.isPotential, isTrue); +- } +- } +- +- test_potential_method() async { +- addTestFile(''' +-class A { +- test(p) {} +-} +-main(A a, p) { +- a.test(1); +- p.test(2); +-} +-'''); +- await findElementReferences('test(p) {}', true); +- { +- assertHasResult(SearchResultKind.INVOCATION, 'test(1);'); +- expect(result.isPotential, isFalse); +- } +- { +- assertHasResult(SearchResultKind.INVOCATION, 'test(2);'); +- expect(result.isPotential, isTrue); +- } +- } +- +- test_potential_method_definedInSubclass() async { +- addTestFile(''' +-class Base { +- methodInBase() { +- test(1); +- } +-} +-class Derived extends Base { +- test(_) {} // of Derived +- methodInDerived() { +- test(2); +- } +-} +-globalFunction(Base b) { +- b.test(3); +-} +-'''); +- await findElementReferences('test(_) {} // of Derived', true); +- assertHasRef(SearchResultKind.INVOCATION, 'test(1);', true); +- assertHasRef(SearchResultKind.INVOCATION, 'test(2);', false); +- assertHasRef(SearchResultKind.INVOCATION, 'test(3);', true); +- } +- +- test_prefix() async { +- addTestFile(''' +-import 'dart:async' as ppp; +-main() { +- ppp.Future a; +- ppp.Stream b; +-} +-'''); +- await findElementReferences("ppp;", false); +- expect(searchElement.kind, ElementKind.PREFIX); +- expect(searchElement.name, 'ppp'); +- expect(searchElement.location.startLine, 1); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.REFERENCE, 'ppp.Future'); +- assertHasResult(SearchResultKind.REFERENCE, 'ppp.Stream'); +- } +- +- test_topLevelVariable_explicit() async { +- addTestFile(''' +-var vvv = 1; +-main() { +- print(vvv); +- vvv += 3; +- vvv = 2; +- vvv(); +-} +-'''); +- await findElementReferences('vvv = 1', false); +- expect(searchElement.kind, ElementKind.TOP_LEVEL_VARIABLE); +- expect(results, hasLength(4)); +- assertHasResult(SearchResultKind.READ, 'vvv);'); +- assertHasResult(SearchResultKind.WRITE, 'vvv += 3'); +- assertHasResult(SearchResultKind.WRITE, 'vvv = 2'); +- assertHasResult(SearchResultKind.INVOCATION, 'vvv();'); +- } +- +- test_topLevelVariable_implicit() async { +- addTestFile(''' +-get vvv => null; +-set vvv(x) {} +-main() { +- print(vvv); +- vvv = 1; +-} +-'''); +- { +- await findElementReferences('vvv =>', false); +- expect(searchElement.kind, ElementKind.TOP_LEVEL_VARIABLE); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.READ, 'vvv);'); +- assertHasResult(SearchResultKind.WRITE, 'vvv = 1;'); +- } +- { +- await findElementReferences('vvv(x) {}', false); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.READ, 'vvv);'); +- assertHasResult(SearchResultKind.WRITE, 'vvv = 1;'); +- } +- } +- +- test_typeReference_class() async { +- addTestFile(''' +-main() { +- int a = 1; +- int b = 2; +-} +-'''); +- await findElementReferences('int a', false); +- expect(searchElement.kind, ElementKind.CLASS); +- assertHasResult(SearchResultKind.REFERENCE, 'int a'); +- assertHasResult(SearchResultKind.REFERENCE, 'int b'); +- } +- +- test_typeReference_functionType() async { +- addTestFile(''' +-typedef F(); +-main(F f) { +-} +-'''); +- await findElementReferences('F()', false); +- expect(searchElement.kind, ElementKind.FUNCTION_TYPE_ALIAS); +- expect(results, hasLength(1)); +- assertHasResult(SearchResultKind.REFERENCE, 'F f'); +- } +- +- test_typeReference_typeVariable() async { +- addTestFile(''' +-class A { +- T f; +- T m() => null; +-} +-'''); +- await findElementReferences('T> {', false); +- expect(searchElement.kind, ElementKind.TYPE_PARAMETER); +- expect(results, hasLength(2)); +- assertHasResult(SearchResultKind.REFERENCE, 'T f;'); +- assertHasResult(SearchResultKind.REFERENCE, 'T m()'); +- } +-} +diff --git a/pkg/analysis_server/test/search/member_declarations_test.dart b/pkg/analysis_server/test/search/member_declarations_test.dart +deleted file mode 100644 +index 644912e7b43..00000000000 +--- a/pkg/analysis_server/test/search/member_declarations_test.dart ++++ /dev/null +@@ -1,157 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_search_domain.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(MemberDeclarationsTest); +- }); +-} +- +-@reflectiveTest +-class MemberDeclarationsTest extends AbstractSearchDomainTest { +- void assertHasDeclaration(ElementKind kind, String className) { +- result = findTopLevelResult(kind, className); +- if (result == null) { +- fail('Not found: kind=$kind in="$className"\nin\n' + results.join('\n')); +- } +- } +- +- Future findMemberDeclarations(String name) async { +- await waitForTasksFinished(); +- Request request = +- new SearchFindMemberDeclarationsParams(name).toRequest('0'); +- Response response = await waitResponse(request); +- var result = new SearchFindMemberDeclarationsResult.fromResponse(response); +- searchId = result.id; +- return waitForSearchResults(); +- } +- +- SearchResult findTopLevelResult(ElementKind kind, String enclosingClass) { +- for (SearchResult result in results) { +- Element element = result.path[0]; +- Element clazz = result.path[1]; +- if (element.kind == kind && clazz.name == enclosingClass) { +- return result; +- } +- } +- return null; +- } +- +- test_localVariable() async { +- addTestFile(''' +-class A { +- main() { +- var foo = 42; +- } +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, isEmpty); +- } +- +- test_localVariable_forIn() async { +- addTestFile(''' +-class A { +- main() { +- for (int foo in []) { +- } +- } +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, isEmpty); +- } +- +- test_methodField() async { +- addTestFile(''' +-class A { +- foo() {} +- bar() {} +-} +-class B { +- int foo; +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, hasLength(2)); +- assertHasDeclaration(ElementKind.METHOD, 'A'); +- assertHasDeclaration(ElementKind.FIELD, 'B'); +- } +- +- test_methodGetter() async { +- addTestFile(''' +-class A { +- foo() {} +- bar() {} +-} +-class B { +- get foo => null; +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, hasLength(2)); +- assertHasDeclaration(ElementKind.METHOD, 'A'); +- assertHasDeclaration(ElementKind.GETTER, 'B'); +- } +- +- test_methodGetterSetter() async { +- addTestFile(''' +-class A { +- foo() {} +- bar() {} +-} +-class B { +- get foo => null; +- set foo(x) {} +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, hasLength(3)); +- assertHasDeclaration(ElementKind.METHOD, 'A'); +- assertHasDeclaration(ElementKind.GETTER, 'B'); +- assertHasDeclaration(ElementKind.SETTER, 'B'); +- } +- +- test_methodMethod() async { +- addTestFile(''' +-class A { +- foo() {} +- bar() {} +-} +-class B { +- foo() {} +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, hasLength(2)); +- assertHasDeclaration(ElementKind.METHOD, 'A'); +- assertHasDeclaration(ElementKind.METHOD, 'B'); +- } +- +- test_methodSetter() async { +- addTestFile(''' +-class A { +- foo() {} +- bar() {} +-} +-class B { +- set foo(x) {} +-} +-'''); +- await findMemberDeclarations('foo'); +- expect(results, hasLength(2)); +- assertHasDeclaration(ElementKind.METHOD, 'A'); +- assertHasDeclaration(ElementKind.SETTER, 'B'); +- } +-} +diff --git a/pkg/analysis_server/test/search/member_references_test.dart b/pkg/analysis_server/test/search/member_references_test.dart +deleted file mode 100644 +index 33be7f20920..00000000000 +--- a/pkg/analysis_server/test/search/member_references_test.dart ++++ /dev/null +@@ -1,114 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_search_domain.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(MemberReferencesTest); +- }); +-} +- +-@reflectiveTest +-class MemberReferencesTest extends AbstractSearchDomainTest { +- void assertHasRef(SearchResultKind kind, String search, bool isPotential) { +- assertHasResult(kind, search); +- expect(result.isPotential, isPotential); +- } +- +- Future findMemberReferences(String name) async { +- await waitForTasksFinished(); +- Request request = new SearchFindMemberReferencesParams(name).toRequest('0'); +- Response response = await waitResponse(request); +- searchId = new SearchFindMemberReferencesResult.fromResponse(response).id; +- return waitForSearchResults(); +- } +- +- test_fields_explicit() async { +- addTestFile(''' +-class A { +- var foo; +-} +-class B { +- var foo; +-} +-mainResolved(A a, B b) { +- a.foo = 1; +- b.foo = 2; +- print(a.foo); // resolved A +- print(b.foo); // resolved B +-} +-mainUnresolved(a, b) { +- a.foo = 10; +- b.foo = 20; +- print(a.foo); // unresolved A +- print(b.foo); // unresolved B +-} +-'''); +- await findMemberReferences('foo'); +- assertNoResult(SearchResultKind.WRITE, 'foo = 1;'); +- assertNoResult(SearchResultKind.WRITE, 'foo = 2;'); +- assertNoResult(SearchResultKind.READ, 'foo); // resolved A'); +- assertNoResult(SearchResultKind.READ, 'foo); // resolved B'); +- assertHasRef(SearchResultKind.WRITE, 'foo = 10;', true); +- assertHasRef(SearchResultKind.WRITE, 'foo = 20;', true); +- assertHasRef(SearchResultKind.READ, 'foo); // unresolved A', true); +- assertHasRef(SearchResultKind.READ, 'foo); // unresolved B', true); +- } +- +- test_fields_implicit() async { +- addTestFile(''' +-class A { +- get foo => null; +-} +-class B { +- get foo => null; +-} +-mainResolved(A a, B b) { +- print(a.foo); // resolved A +- print(b.foo); // resolved B +-} +-mainUnresolved(a, b) { +- print(a.foo); // unresolved A +- print(b.foo); // unresolved B +-} +-'''); +- await findMemberReferences('foo'); +- assertNoResult(SearchResultKind.READ, 'foo); // resolved A'); +- assertNoResult(SearchResultKind.READ, 'foo); // resolved B'); +- assertHasRef(SearchResultKind.READ, 'foo); // unresolved A', true); +- assertHasRef(SearchResultKind.READ, 'foo); // unresolved B', true); +- } +- +- test_methods() async { +- addTestFile(''' +-class A { +- foo() {} +-} +-class B { +- foo() {} +-} +-mainResolved(A a, B b) { +- a.foo(1); +- b.foo(2); +-} +-mainUnresolved(a, b) { +- a.foo(10); +- b.foo(20); +-} +-'''); +- await findMemberReferences('foo'); +- assertNoResult(SearchResultKind.INVOCATION, 'foo(1)'); +- assertNoResult(SearchResultKind.INVOCATION, 'foo(2)'); +- assertHasRef(SearchResultKind.INVOCATION, 'foo(10)', true); +- assertHasRef(SearchResultKind.INVOCATION, 'foo(20)', true); +- } +-} +diff --git a/pkg/analysis_server/test/search/search_result_test.dart b/pkg/analysis_server/test/search/search_result_test.dart +deleted file mode 100644 +index 47a8560e003..00000000000 +--- a/pkg/analysis_server/test/search/search_result_test.dart ++++ /dev/null +@@ -1,55 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SearchResultKindTest); +- }); +-} +- +-@reflectiveTest +-class SearchResultKindTest { +- void test_fromEngine() { +- expect(newSearchResultKind_fromEngine(MatchKind.DECLARATION), +- SearchResultKind.DECLARATION); +- expect( +- newSearchResultKind_fromEngine(MatchKind.READ), SearchResultKind.READ); +- expect(newSearchResultKind_fromEngine(MatchKind.READ_WRITE), +- SearchResultKind.READ_WRITE); +- expect(newSearchResultKind_fromEngine(MatchKind.WRITE), +- SearchResultKind.WRITE); +- expect(newSearchResultKind_fromEngine(MatchKind.REFERENCE), +- SearchResultKind.REFERENCE); +- expect(newSearchResultKind_fromEngine(MatchKind.INVOCATION), +- SearchResultKind.INVOCATION); +- expect(newSearchResultKind_fromEngine(null), SearchResultKind.UNKNOWN); +- } +- +- void test_fromName() { +- expect(new SearchResultKind(SearchResultKind.DECLARATION.name), +- SearchResultKind.DECLARATION); +- expect(new SearchResultKind(SearchResultKind.READ.name), +- SearchResultKind.READ); +- expect(new SearchResultKind(SearchResultKind.READ_WRITE.name), +- SearchResultKind.READ_WRITE); +- expect(new SearchResultKind(SearchResultKind.WRITE.name), +- SearchResultKind.WRITE); +- expect(new SearchResultKind(SearchResultKind.REFERENCE.name), +- SearchResultKind.REFERENCE); +- expect(new SearchResultKind(SearchResultKind.INVOCATION.name), +- SearchResultKind.INVOCATION); +- expect(new SearchResultKind(SearchResultKind.UNKNOWN.name), +- SearchResultKind.UNKNOWN); +- } +- +- void test_toString() { +- expect(SearchResultKind.DECLARATION.toString(), +- 'SearchResultKind.DECLARATION'); +- } +-} +diff --git a/pkg/analysis_server/test/search/test_all.dart b/pkg/analysis_server/test/search/test_all.dart +deleted file mode 100644 +index a2ccb2bd80f..00000000000 +--- a/pkg/analysis_server/test/search/test_all.dart ++++ /dev/null +@@ -1,26 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'element_references_test.dart' as element_references_test; +-import 'member_declarations_test.dart' as member_declarations; +-import 'member_references_test.dart' as member_references_test; +-import 'search_result_test.dart' as search_result_test; +-import 'top_level_declarations_test.dart' as top_level_declarations_test; +-import 'type_hierarchy_test.dart' as type_hierarchy_test; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- defineReflectiveSuite(() { +- element_references_test.main(); +- member_declarations.main(); +- member_references_test.main(); +- search_result_test.main(); +- top_level_declarations_test.main(); +- type_hierarchy_test.main(); +- }, name: 'search'); +-} +diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart +deleted file mode 100644 +index e383ca644fe..00000000000 +--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart ++++ /dev/null +@@ -1,82 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_search_domain.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(TopLevelDeclarationsTest); +- }); +-} +- +-@reflectiveTest +-class TopLevelDeclarationsTest extends AbstractSearchDomainTest { +- void assertHasDeclaration(ElementKind kind, String name) { +- result = findTopLevelResult(kind, name); +- if (result == null) { +- fail('Not found: kind=$kind name="$name"\nin\n' + results.join('\n')); +- } +- } +- +- void assertNoDeclaration(ElementKind kind, String name) { +- result = findTopLevelResult(kind, name); +- if (result != null) { +- fail('Unexpected: kind=$kind name="$name"\nin\n' + results.join('\n')); +- } +- } +- +- Future findTopLevelDeclarations(String pattern) async { +- await waitForTasksFinished(); +- Request request = +- new SearchFindTopLevelDeclarationsParams(pattern).toRequest('0'); +- Response response = await waitResponse(request); +- if (response.error != null) { +- return response.error; +- } +- searchId = +- new SearchFindTopLevelDeclarationsResult.fromResponse(response).id; +- return waitForSearchResults(); +- } +- +- SearchResult findTopLevelResult(ElementKind kind, String name) { +- for (SearchResult result in results) { +- Element element = result.path[0]; +- if (element.kind == kind && element.name == name) { +- return result; +- } +- } +- return null; +- } +- +- test_invalidRegex() async { +- var result = await findTopLevelDeclarations('[A'); +- expect(result, new isInstanceOf()); +- } +- +- test_startEndPattern() async { +- addTestFile(''' +-class A {} // A +-class B = Object with A; +-typedef C(); +-D() {} +-var E = null; +-class ABC {} +-'''); +- await findTopLevelDeclarations('^[A-E]\$'); +- assertHasDeclaration(ElementKind.CLASS, 'A'); +- assertHasDeclaration(ElementKind.CLASS, 'B'); +- assertHasDeclaration(ElementKind.FUNCTION_TYPE_ALIAS, 'C'); +- assertHasDeclaration(ElementKind.FUNCTION, 'D'); +- assertHasDeclaration(ElementKind.TOP_LEVEL_VARIABLE, 'E'); +- assertNoDeclaration(ElementKind.CLASS, 'ABC'); +- } +-} +diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart +deleted file mode 100644 +index c2d15474a23..00000000000 +--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart ++++ /dev/null +@@ -1,1055 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/search/search_domain.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(GetTypeHierarchyTest); +- }); +-} +- +-@reflectiveTest +-class GetTypeHierarchyTest extends AbstractAnalysisTest { +- static const String requestId = 'test-getTypeHierarchy'; +- +- @override +- void setUp() { +- super.setUp(); +- createProject(); +- server.handlers = [ +- new SearchDomainHandler(server), +- ]; +- } +- +- test_bad_function() async { +- addTestFile(''' +-main() { +-} +-'''); +- List items = await _getTypeHierarchy('main() {'); +- expect(items, isNull); +- } +- +- test_bad_noElement() async { +- addTestFile(''' +-main() { +- /* target */ +-} +-'''); +- List items = await _getTypeHierarchy('/* target */'); +- expect(items, isNull); +- } +- +- test_bad_recursion() async { +- addTestFile(''' +-class A extends B { +-} +-class B extends A { +-} +-'''); +- List items = await _getTypeHierarchy('B extends A'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'B', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [1] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'A', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 0, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_class_displayName() async { +- addTestFile(''' +-class A { +-} +-class B extends A { +-} +-'''); +- List items = await _getTypeHierarchy('B extends'); +- var itemB = items[0]; +- var itemA = items[itemB.superclass]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemA.displayName, 'A'); +- } +- +- test_class_double_subclass() async { +- addTestFile(''' +-class AAA {} // A +- +-class BBB extends AAA {} +- +-class CCC extends BBB implements AAA {} +-'''); +- List items = await _getTypeHierarchy('AAA {} // A'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'AAA', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [2, 3] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'BBB', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 0, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [3] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'CCC', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 0, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- ]); +- } +- +- test_class_extends_fileAndPackageUris() async { +- // prepare packages +- String pkgFile = '/packages/pkgA/lib/libA.dart'; +- resourceProvider.newFile(pkgFile, ''' +-library lib_a; +-class A {} +-class B extends A {} +-'''); +- resourceProvider.newFile( +- '/packages/pkgA/.packages', 'pkgA:file:///packages/pkgA/lib'); +- // reference the package from a project +- resourceProvider.newFile( +- '$projectPath/.packages', 'pkgA:file:///packages/pkgA/lib'); +- addTestFile(''' +-import 'package:pkgA/libA.dart'; +-class C extends A {} +-'''); +- await waitForTasksFinished(); +- // configure roots +- Request request = +- new AnalysisSetAnalysisRootsParams([projectPath, '/packages/pkgA'], []) +- .toRequest('0'); +- handleSuccessfulRequest(request); +- // test A type hierarchy +- List items = await _getTypeHierarchy('A {}'); +- Set names = _toClassNames(items); +- expect(names, contains('A')); +- expect(names, contains('B')); +- expect(names, contains('C')); +- } +- +- test_class_extendsTypeA() async { +- addTestFile(''' +-class A {} +-class B extends A { +-} +-class C extends B { +-} +-'''); +- List items = await _getTypeHierarchy('A {}'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'A', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [2] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'B', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 0, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [3] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'C', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 2, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_class_extendsTypeB() async { +- addTestFile(''' +-class A { +-} +-class B extends A { +-} +-class C extends B { +-} +-'''); +- List items = await _getTypeHierarchy('B extends'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'B', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [3] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'A', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 2, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'C', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 0, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_class_extendsTypeC() async { +- addTestFile(''' +-class A { +-} +-class B extends A { +-} +-class C extends B { +-} +-'''); +- List items = await _getTypeHierarchy('C extends'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'C', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'B', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 2, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'A', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 3, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_class_implementsTypes() async { +- addTestFile(''' +-class MA {} +-class MB {} +-class B extends A { +-} +-class T implements MA, MB { +-} +-'''); +- List items = await _getTypeHierarchy('T implements'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'T', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [2, 3], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'MA', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'MB', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_class_withTypes() async { +- addTestFile(''' +-class MA {} +-class MB {} +-class B extends A { +-} +-class T extends Object with MA, MB { +-} +-'''); +- List items = await _getTypeHierarchy('T extends Object'); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'T', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [2, 3], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'MA', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'MB', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_fromField_toMixinGetter() async { +- addTestFile(''' +-abstract class A { +- var test = 1; +-} +-class Mixin { +- get test => 2; +-} +-class B extends A with Mixin {} +-'''); +- List items = await _getTypeHierarchy('test = 1;'); +- var itemA = items.firstWhere((e) => e.classElement.name == 'A'); +- var itemB = items.firstWhere((e) => e.classElement.name == 'B'); +- Element memberA = itemA.memberElement; +- Element memberB = itemB.memberElement; +- expect(memberA, isNotNull); +- expect(memberB, isNotNull); +- expect(memberA.location.offset, findOffset('test = 1;')); +- expect(memberB.location.offset, findOffset('test => 2;')); +- } +- +- test_fromField_toMixinSetter() async { +- addTestFile(''' +-abstract class A { +- var test = 1; +-} +-class Mixin { +- set test(m) {} +-} +-class B extends A with Mixin {} +-'''); +- List items = await _getTypeHierarchy('test = 1;'); +- var itemA = items.firstWhere((e) => e.classElement.name == 'A'); +- var itemB = items.firstWhere((e) => e.classElement.name == 'B'); +- Element memberA = itemA.memberElement; +- Element memberB = itemB.memberElement; +- expect(memberA, isNotNull); +- expect(memberB, isNotNull); +- expect(memberA.location.offset, findOffset('test = 1;')); +- expect(memberB.location.offset, findOffset('test(m) {}')); +- } +- +- test_member_fromField_toField() async { +- addTestFile(''' +-class A { +- var test = 1; +-} +-class B extends A { +- var test = 2; +-} +-'''); +- List items = await _getTypeHierarchy('test = 2;'); +- TypeHierarchyItem itemB = items[0]; +- TypeHierarchyItem itemA = items[itemB.superclass]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemA.memberElement.location.offset, findOffset('test = 1;')); +- expect(itemB.memberElement.location.offset, findOffset('test = 2;')); +- } +- +- test_member_fromField_toGetter() async { +- addTestFile(''' +-class A { +- get test => 1; +-} +-class B extends A { +- var test = 2; +-} +-'''); +- List items = await _getTypeHierarchy('test = 2;'); +- TypeHierarchyItem itemB = items[0]; +- TypeHierarchyItem itemA = items[itemB.superclass]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemA.memberElement.location.offset, findOffset('test => 1')); +- expect(itemB.memberElement.location.offset, findOffset('test = 2;')); +- } +- +- test_member_fromField_toSetter() async { +- addTestFile(''' +-class A { +- set test(a) {} +-} +-class B extends A { +- var test = 2; +-} +-'''); +- List items = await _getTypeHierarchy('test = 2;'); +- TypeHierarchyItem itemB = items[0]; +- TypeHierarchyItem itemA = items[itemB.superclass]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemA.memberElement.location.offset, findOffset('test(a) {}')); +- expect(itemB.memberElement.location.offset, findOffset('test = 2;')); +- } +- +- test_member_fromFinalField_toGetter() async { +- addTestFile(''' +-class A { +- get test => 1; +-} +-class B extends A { +- final test = 2; +-} +-'''); +- List items = await _getTypeHierarchy('test = 2;'); +- TypeHierarchyItem itemB = items[0]; +- TypeHierarchyItem itemA = items[itemB.superclass]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemA.memberElement.location.offset, findOffset('test => 1;')); +- expect(itemB.memberElement.location.offset, findOffset('test = 2;')); +- } +- +- test_member_fromFinalField_toSetter() async { +- addTestFile(''' +-class A { +- set test(x) {} +-} +-class B extends A { +- final test = 2; +-} +-'''); +- List items = await _getTypeHierarchy('test = 2;'); +- TypeHierarchyItem itemB = items[0]; +- TypeHierarchyItem itemA = items[itemB.superclass]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemA.memberElement, isNull); +- expect(itemB.memberElement.location.offset, findOffset('test = 2;')); +- } +- +- test_member_getter() async { +- addTestFile(''' +-class A { +- get test => null; // in A +-} +-class B extends A { +- get test => null; // in B +-} +-class C extends B { +-} +-class D extends C { +- get test => null; // in D +-} +-'''); +- List items = +- await _getTypeHierarchy('test => null; // in B'); +- TypeHierarchyItem itemB = items[0]; +- TypeHierarchyItem itemA = items[itemB.superclass]; +- TypeHierarchyItem itemC = items[itemB.subclasses[0]]; +- TypeHierarchyItem itemD = items[itemC.subclasses[0]]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemC.classElement.name, 'C'); +- expect(itemD.classElement.name, 'D'); +- expect(itemA.memberElement.location.offset, +- findOffset('test => null; // in A')); +- expect(itemB.memberElement.location.offset, +- findOffset('test => null; // in B')); +- expect(itemC.memberElement, isNull); +- expect(itemD.memberElement.location.offset, +- findOffset('test => null; // in D')); +- } +- +- test_member_method() async { +- addTestFile(''' +-class A { +- test() {} // in A +-} +-class B extends A { +- test() {} // in B +-} +-class C extends B { +-} +-class D extends C { +- test() {} // in D +-} +-'''); +- List items = +- await _getTypeHierarchy('test() {} // in B'); +- var itemB = items[0]; +- var itemA = items[itemB.superclass]; +- var itemC = items[itemB.subclasses[0]]; +- var itemD = items[itemC.subclasses[0]]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemC.classElement.name, 'C'); +- expect(itemD.classElement.name, 'D'); +- expect( +- itemA.memberElement.location.offset, findOffset('test() {} // in A')); +- expect( +- itemB.memberElement.location.offset, findOffset('test() {} // in B')); +- expect(itemC.memberElement, isNull); +- expect( +- itemD.memberElement.location.offset, findOffset('test() {} // in D')); +- } +- +- test_member_method_private_differentLib() async { +- addFile('$testFolder/lib.dart', r''' +-import 'test.dart'; +-class A { +- void _m() {} +-} +-class C extends B { +- void _m() {} +-} +-'''); +- addTestFile(''' +-import 'lib.dart'; +-class B extends A { +- _m() {} // in B +-} +-class D extends C { +- _m() {} // in D +-} +-'''); +- List items = await _getTypeHierarchy('_m() {} // in B'); +- var itemB = items[0]; +- var itemA = items[itemB.superclass]; +- var itemC = items[itemB.subclasses[0]]; +- var itemD = items[itemC.subclasses[0]]; +- expect(itemB.classElement.name, 'B'); +- expect(itemA.classElement.name, 'A'); +- expect(itemC.classElement.name, 'C'); +- expect(itemD.classElement.name, 'D'); +- expect(itemA.memberElement, isNull); +- expect(itemC.memberElement, isNull); +- expect(itemB.memberElement, isNotNull); +- expect(itemD.memberElement, isNotNull); +- } +- +- test_member_method_private_sameLib() async { +- addTestFile(''' +-class A { +- _m() {} // in A +-} +-class B extends A { +- _m() {} // in B +-} +-class C extends B { +- _m() {} // in C +-} +-'''); +- List items = await _getTypeHierarchy('_m() {} // in B'); +- var itemB = items[0]; +- var itemA = items[itemB.superclass]; +- var itemC = items[itemB.subclasses[0]]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemC.classElement.name, 'C'); +- expect(itemA.memberElement.location.offset, findOffset('_m() {} // in A')); +- expect(itemB.memberElement.location.offset, findOffset('_m() {} // in B')); +- expect(itemC.memberElement.location.offset, findOffset('_m() {} // in C')); +- } +- +- test_member_ofMixin2_method() async { +- addTestFile(''' +-class M1 { +- void test() {} // in M1 +-} +-class M2 { +- void test() {} // in M2 +-} +-class D1 extends Object with M1 {} +-class D2 extends Object with M1, M2 {} +-class D3 extends Object with M2, M1 {} +-class D4 extends Object with M2, M1 { +- void test() {} // in D4 +-} +-'''); +- List items = +- await _getTypeHierarchy('test() {} // in M1'); +- var itemM1 = items.firstWhere((e) => e.classElement.name == 'M1'); +- var item1 = items.firstWhere((e) => e.classElement.name == 'D1'); +- var item2 = items.firstWhere((e) => e.classElement.name == 'D2'); +- var item3 = items.firstWhere((e) => e.classElement.name == 'D3'); +- var item4 = items.firstWhere((e) => e.classElement.name == 'D4'); +- expect(itemM1, isNotNull); +- expect(item1, isNotNull); +- expect(item2, isNotNull); +- expect(item3, isNotNull); +- expect(item4, isNotNull); +- // D1 does not override +- { +- Element member1 = item1.memberElement; +- expect(member1, isNull); +- } +- // D2 mixes-in M2 last, which overrides +- { +- Element member2 = item2.memberElement; +- expect(member2, isNotNull); +- expect(member2.location.offset, findOffset('test() {} // in M2')); +- } +- // D3 mixes-in M1 last and does not override itself +- { +- Element member3 = item3.memberElement; +- expect(member3, isNull); +- } +- // D4 mixes-in M1 last, but it also overrides +- { +- Element member4 = item4.memberElement; +- expect(member4.location.offset, findOffset('test() {} // in D4')); +- } +- } +- +- test_member_ofMixin_getter() async { +- addTestFile(''' +-abstract class Base { +- get test; // in Base +-} +-class Mixin { +- get test => null; // in Mixin +-} +-class Derived1 extends Base with Mixin {} +-class Derived2 extends Base { +- get test => null; // in Derived2 +-} +-'''); +- List items = await _getTypeHierarchy('test; // in Base'); +- var itemBase = items.firstWhere((e) => e.classElement.name == 'Base'); +- var item1 = items.firstWhere((e) => e.classElement.name == 'Derived1'); +- var item2 = items.firstWhere((e) => e.classElement.name == 'Derived2'); +- Element memberBase = itemBase.memberElement; +- Element member1 = item1.memberElement; +- Element member2 = item2.memberElement; +- expect(memberBase, isNotNull); +- expect(member1, isNotNull); +- expect(member2, isNotNull); +- expect(memberBase.location.offset, findOffset('test; // in Base')); +- expect(member1.location.offset, findOffset('test => null; // in Mixin')); +- expect(member2.location.offset, findOffset('test => null; // in Derived2')); +- } +- +- test_member_ofMixin_method() async { +- addTestFile(''' +-abstract class Base { +- void test(); // in Base +-} +-class Mixin { +- void test() {} // in Mixin +-} +-class Derived1 extends Base with Mixin {} +-class Derived2 extends Base { +- void test() {} // in Derived2 +-} +-'''); +- List items = +- await _getTypeHierarchy('test(); // in Base'); +- var itemBase = items.firstWhere((e) => e.classElement.name == 'Base'); +- var item1 = items.firstWhere((e) => e.classElement.name == 'Derived1'); +- var item2 = items.firstWhere((e) => e.classElement.name == 'Derived2'); +- Element memberBase = itemBase.memberElement; +- Element member1 = item1.memberElement; +- Element member2 = item2.memberElement; +- expect(memberBase, isNotNull); +- expect(member1, isNotNull); +- expect(member2, isNotNull); +- expect(memberBase.location.offset, findOffset('test(); // in Base')); +- expect(member1.location.offset, findOffset('test() {} // in Mixin')); +- expect(member2.location.offset, findOffset('test() {} // in Derived2')); +- } +- +- test_member_ofMixin_setter() async { +- addTestFile(''' +-abstract class Base { +- set test(x); // in Base +-} +-class Mixin { +- set test(x) {} // in Mixin +-} +-class Derived1 extends Base with Mixin {} +-class Derived2 extends Base { +- set test(x) {} // in Derived2 +-} +-'''); +- List items = +- await _getTypeHierarchy('test(x); // in Base'); +- var itemBase = items.firstWhere((e) => e.classElement.name == 'Base'); +- var item1 = items.firstWhere((e) => e.classElement.name == 'Derived1'); +- var item2 = items.firstWhere((e) => e.classElement.name == 'Derived2'); +- Element memberBase = itemBase.memberElement; +- Element member1 = item1.memberElement; +- Element member2 = item2.memberElement; +- expect(memberBase, isNotNull); +- expect(member1, isNotNull); +- expect(member2, isNotNull); +- expect(memberBase.location.offset, findOffset('test(x); // in Base')); +- expect(member1.location.offset, findOffset('test(x) {} // in Mixin')); +- expect(member2.location.offset, findOffset('test(x) {} // in Derived2')); +- } +- +- test_member_operator() async { +- addTestFile(''' +-class A { +- operator ==(x) => null; // in A +-} +-class B extends A { +- operator ==(x) => null; // in B +-} +-class C extends B { +-} +-class D extends C { +- operator ==(x) => null; // in D +-} +-'''); +- List items = +- await _getTypeHierarchy('==(x) => null; // in B'); +- var itemB = items[0]; +- var itemA = items[itemB.superclass]; +- var itemC = items[itemB.subclasses[0]]; +- var itemD = items[itemC.subclasses[0]]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemC.classElement.name, 'C'); +- expect(itemD.classElement.name, 'D'); +- expect(itemA.memberElement.location.offset, +- findOffset('==(x) => null; // in A')); +- expect(itemB.memberElement.location.offset, +- findOffset('==(x) => null; // in B')); +- expect(itemC.memberElement, isNull); +- expect(itemD.memberElement.location.offset, +- findOffset('==(x) => null; // in D')); +- } +- +- test_member_setter() async { +- addTestFile(''' +-class A { +- set test(x) {} // in A +-} +-class B extends A { +- set test(x) {} // in B +-} +-class C extends B { +-} +-class D extends C { +- set test(x) {} // in D +-} +-'''); +- List items = +- await _getTypeHierarchy('test(x) {} // in B'); +- var itemB = items[0]; +- var itemA = items[itemB.superclass]; +- var itemC = items[itemB.subclasses[0]]; +- var itemD = items[itemC.subclasses[0]]; +- expect(itemA.classElement.name, 'A'); +- expect(itemB.classElement.name, 'B'); +- expect(itemC.classElement.name, 'C'); +- expect(itemD.classElement.name, 'D'); +- expect( +- itemA.memberElement.location.offset, findOffset('test(x) {} // in A')); +- expect( +- itemB.memberElement.location.offset, findOffset('test(x) {} // in B')); +- expect(itemC.memberElement, isNull); +- expect( +- itemD.memberElement.location.offset, findOffset('test(x) {} // in D')); +- } +- +- test_superOnly() async { +- addTestFile(''' +-class A {} +-class B {} +-class C extends A implements B {} +-class D extends C {} +-'''); +- List items = +- await _getTypeHierarchy('C extends', superOnly: true); +- expect(_toJson(items), [ +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'C', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 1, +- 'interfaces': [3], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'A', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 2, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'Object', +- 'location': anything, +- 'flags': 0 +- }, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- }, +- { +- 'classElement': { +- 'kind': 'CLASS', +- 'name': 'B', +- 'location': anything, +- 'flags': 0 +- }, +- 'superclass': 2, +- 'interfaces': [], +- 'mixins': [], +- 'subclasses': [] +- } +- ]); +- } +- +- test_superOnly_fileDoesNotExist() async { +- Request request = new SearchGetTypeHierarchyParams( +- '/does/not/exist.dart', 0, +- superOnly: true) +- .toRequest(requestId); +- Response response = await serverChannel.sendRequest(request); +- List items = +- new SearchGetTypeHierarchyResult.fromResponse(response).hierarchyItems; +- expect(items, isNull); +- } +- +- Request _createGetTypeHierarchyRequest(String search, {bool superOnly}) { +- return new SearchGetTypeHierarchyParams(testFile, findOffset(search), +- superOnly: superOnly) +- .toRequest(requestId); +- } +- +- Future> _getTypeHierarchy(String search, +- {bool superOnly}) async { +- await waitForTasksFinished(); +- Request request = +- _createGetTypeHierarchyRequest(search, superOnly: superOnly); +- Response response = await serverChannel.sendRequest(request); +- expect(serverErrors, isEmpty); +- return new SearchGetTypeHierarchyResult.fromResponse(response) +- .hierarchyItems; +- } +- +- List _toJson(List items) { +- return items.map((item) => item.toJson()).toList(); +- } +- +- static Set _toClassNames(List items) { +- return items.map((TypeHierarchyItem item) { +- return item.classElement.name; +- }).toSet(); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart +deleted file mode 100644 +index 6ab74304758..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart ++++ /dev/null +@@ -1,1019 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../../src/utilities/flutter_util.dart'; +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ArgListContributorTest); +- }); +-} +- +-@reflectiveTest +-class ArgListContributorTest extends DartCompletionContributorTest { +- void assertNoOtherSuggestions(Iterable expected) { +- for (CompletionSuggestion suggestion in suggestions) { +- if (!expected.contains(suggestion)) { +- failedCompletion('did not expect completion: ' +- '${suggestion.completion}\n $suggestion'); +- } +- } +- } +- +- /** +- * Assert that there is a suggestion with the given parameter [name] that has +- * the given [completion], [selectionOffset] and [selectionLength]. +- */ +- void assertSuggestArgumentAndCompletion(String name, +- {String completion, int selectionOffset, int selectionLength: 0}) { +- CompletionSuggestion suggestion = +- suggestions.firstWhere((s) => s.parameterName == name); +- expect(suggestion, isNotNull); +- expect(suggestion.completion, completion); +- expect(suggestion.selectionOffset, selectionOffset); +- expect(suggestion.selectionLength, selectionLength); +- } +- +- void assertSuggestArgumentList( +- List paramNames, List paramTypes) { +- // DEPRECATED... argument lists are no longer suggested. +- // See https://github.com/dart-lang/sdk/issues/25197 +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- +- // CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST; +- // CompletionSuggestion cs = getSuggest(csKind: csKind); +- // if (cs == null) { +- // failedCompletion('expected completion $csKind', suggestions); +- // } +- // assertSuggestArgumentList_params( +- // paramNames, paramTypes, cs.parameterNames, cs.parameterTypes); +- // expect(cs.relevance, DART_RELEVANCE_HIGH); +- // assertNoOtherSuggestions([cs]); +- } +- +- void assertSuggestArgumentList_params( +- List expectedNames, +- List expectedTypes, +- List actualNames, +- List actualTypes) { +- if (actualNames != null && +- actualNames.length == expectedNames.length && +- actualTypes != null && +- actualTypes.length == expectedTypes.length) { +- int index = 0; +- while (index < expectedNames.length) { +- if (actualNames[index] != expectedNames[index] || +- actualTypes[index] != expectedTypes[index]) { +- break; +- } +- ++index; +- } +- if (index == expectedNames.length) { +- return; +- } +- } +- StringBuffer msg = new StringBuffer(); +- msg.writeln('Argument list not the same'); +- msg.writeln(' Expected names: $expectedNames'); +- msg.writeln(' found: $actualNames'); +- msg.writeln(' Expected types: $expectedTypes'); +- msg.writeln(' found: $actualTypes'); +- fail(msg.toString()); +- } +- +- /** +- * Assert that the specified named argument suggestions with their types are +- * the only suggestions. +- */ +- void assertSuggestArgumentsAndTypes( +- {Map namedArgumentsWithTypes, +- List requiredParamIndices: const [], +- bool includeColon: true, +- bool includeComma: false}) { +- List expected = new List(); +- int paramIndex = 0; +- namedArgumentsWithTypes.forEach((String name, String type) { +- String completion = includeColon ? '$name: ' : name; +- // Selection should be before any trailing commas. +- int selectionOffset = completion.length; +- if (includeComma) { +- completion = '$completion,'; +- } +- int relevance = requiredParamIndices.contains(paramIndex++) +- ? DART_RELEVANCE_NAMED_PARAMETER_REQUIRED +- : DART_RELEVANCE_NAMED_PARAMETER; +- expected.add(assertSuggest(completion, +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: relevance, +- paramName: name, +- paramType: type, +- selectionOffset: selectionOffset)); +- }); +- assertNoOtherSuggestions(expected); +- } +- +- /** +- * Assert that the specified suggestions are the only suggestions. +- */ +- void assertSuggestions(List suggestions) { +- List expected = new List(); +- for (String suggestion in suggestions) { +- // Selection offset should be before any trailing commas. +- int selectionOffset = +- suggestion.endsWith(',') ? suggestion.length - 1 : suggestion.length; +- expected.add(assertSuggest('$suggestion', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- selectionOffset: selectionOffset)); +- } +- assertNoOtherSuggestions(expected); +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new ArgListContributor(); +- } +- +- fail_test_Annotation_local_constructor_named_param_10() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(two: '2' ^) main() { }'''); +- await computeSuggestions(); +- assertSuggestions([', one: ']); +- } +- +- fail_test_Annotation_local_constructor_named_param_9() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(two: '2'^) main() { }'''); +- await computeSuggestions(); +- assertSuggestions([', one: ']); +- } +- +- test_Annotation_imported_constructor_named_param() async { +- addSource('/libA.dart', ''' +-library libA; class A { const A({int one, String two: 'defaultValue'}); }'''); +- addTestSource('import "/libA.dart"; @A(^) main() { }'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}); +- } +- +- test_Annotation_local_constructor_named_param() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(^) main() { }'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}); +- } +- +- test_Annotation_local_constructor_named_param_11() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(two: '2', ^) main() { }'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_Annotation_local_constructor_named_param_2() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(^ two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestions(['one: ,']); +- } +- +- test_Annotation_local_constructor_named_param_3() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(^two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestions(['one: ,']); +- } +- +- test_Annotation_local_constructor_named_param_4() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(^, two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_Annotation_local_constructor_named_param_5() async { +- addTestSource(''' +-class A { const A({int one, String two: 'defaultValue'}); } +-@A(^ , two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_Annotation_local_constructor_named_param_6() async { +- addTestSource(''' +-class A { const A(int zero, {int one, String two: 'defaultValue'}); } +-@A(0, ^, two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_Annotation_local_constructor_named_param_7() async { +- addTestSource(''' +-class A { const A(int zero, {int one, String two: 'defaultValue'}); } +-@A(0, ^ two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestions(['one: ,']); +- } +- +- test_Annotation_local_constructor_named_param_8() async { +- addTestSource(''' +-class A { const A(int zero, {int one, String two: 'defaultValue'}); } +-@A(0, ^two: '2') main() { }'''); +- await computeSuggestions(); +- assertSuggestions(['one: ,']); +- } +- +- test_Annotation_local_constructor_named_param_negative() async { +- addTestSource(''' +-class A { const A(int one, int two, int three, {int four, String five: +- 'defaultValue'}); } +-@A(1, ^, 3) main() { }'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_Flutter_InstanceCreationExpression_0() async { +- configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +-build() => new Row( +- ^ +- ); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('children: [],', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- defaultArgListString: null, +- selectionOffset: 19, +- defaultArgumentListTextRanges: null); +- } +- +- test_ArgumentList_Flutter_InstanceCreationExpression_01() async { +- configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +- build() => new Scaffold( +- appBar: new AppBar( +- ^ +- ), +- ); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('color: ,', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- defaultArgListString: null, // No default values. +- selectionOffset: 7); +- } +- +- test_ArgumentList_Flutter_InstanceCreationExpression_1() async { +- configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +-build() => new Row( +- key: null, +- ^ +- ); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('children: [],', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- defaultArgListString: null, +- selectionOffset: 19, +- defaultArgumentListTextRanges: null); +- } +- +- test_ArgumentList_Flutter_InstanceCreationExpression_2() async { +- configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +-build() => new Row( +- ^ +- key: null, +- ); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('children: [],', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- defaultArgListString: null, +- selectionOffset: 19, +- defaultArgumentListTextRanges: null); +- } +- +- test_ArgumentList_Flutter_InstanceCreationExpression_children_dynamic() async { +- // Ensure we don't generate unneeded param if a future API doesn't +- // type it's children. +- configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code + +- '\nclass DynamicRow extends Widget { DynamicRow({List children: null}){}}' +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +-build() => new Container( +- child: new DynamicRow(^); +- ); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('children: [],', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- defaultArgListString: null, +- selectionOffset: 11, +- defaultArgumentListTextRanges: null); +- } +- +- test_ArgumentList_Flutter_InstanceCreationExpression_children_Map() async { +- // Ensure we don't generate Map params for a future API +- configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code + +- '\nclass MapRow extends Widget { MapRow({Map children: null}){}}' +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +-build() => new Container( +- child: new MapRow(^); +- ); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('children: ,', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- selectionOffset: 10, +- defaultArgListString: null); +- } +- +- test_ArgumentList_Flutter_MethodExpression_children() async { +- // Ensure we don't generate params for a method call +- configureFlutterPkg({ +- 'src/widgets/framework.dart': +- flutter_framework_code + '\nfoo({String children})' +- }); +- +- addTestSource(''' +-import 'package:flutter/src/widgets/framework.dart'; +- +-main() { +-foo(^); +-'''); +- +- await computeSuggestions(); +- +- assertSuggest('children: ', +- csKind: CompletionSuggestionKind.NAMED_ARGUMENT, +- relevance: DART_RELEVANCE_NAMED_PARAMETER, +- defaultArgListString: null); +- } +- +- test_ArgumentList_getter() async { +- addTestSource('class A {int get foo => 7; main() {foo(^)}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_constructor_named_param() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement +- addSource('/libA.dart', 'library libA; class A{A({int one}); }'); +- addTestSource('import "/libA.dart"; main() { new A(^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_ArgumentList_imported_constructor_named_param2() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement +- addSource('/libA.dart', 'library libA; class A{A.foo({int one}); }'); +- addTestSource('import "/libA.dart"; main() { new A.foo(^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_ArgumentList_imported_constructor_named_typed_param() async { +- // ArgumentList InstanceCreationExpression VariableDeclaration +- addSource( +- '/libA.dart', 'library libA; class A { A({int i, String s, d}) {} }}'); +- addTestSource('import "/libA.dart"; main() { var a = new A(^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'i': 'int', 's': 'String', 'd': 'dynamic'}); +- } +- +- test_ArgumentList_imported_factory_named_param() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement +- addSource( +- '/libA.dart', 'library libA; class A{factory A({int one}) => null;}'); +- addTestSource('import "/libA.dart"; main() { new A(^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_ArgumentList_imported_factory_named_param2() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement +- addSource('/libA.dart', +- 'library libA; abstract class A{factory A.foo({int one});}'); +- addTestSource('import "/libA.dart"; main() { new A.foo(^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- } +- +- test_ArgumentList_imported_factory_named_typed_param() async { +- // ArgumentList InstanceCreationExpression VariableDeclaration +- addSource('/libA.dart', +- 'library libA; class A {factory A({int i, String s, d}) {} }}'); +- addTestSource('import "/libA.dart"; main() { var a = new A(^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'i': 'int', 's': 'String', 'd': 'dynamic'}); +- } +- +- test_ArgumentList_imported_function_0() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect() { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect(a^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_function_1() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg'], ['String']); +- } +- +- test_ArgumentList_imported_function_2() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg1, int arg2) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']); +- } +- +- test_ArgumentList_imported_function_3() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg1, int arg2, {bool arg3}) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']); +- } +- +- test_ArgumentList_imported_function_3a() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg1, int arg2, {bool arg3}) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect('hello', ^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_function_3b() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg1, int arg2, {bool arg3}) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect('hello', ^x)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_function_3c() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg1, int arg2, {bool arg3}) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect('hello', x^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_function_3d() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(String arg1, int arg2, {bool arg3}) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect('hello', x ^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_function_named_param() async { +- // +- addTestSource('main() { int.parse("16", ^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'}); +- } +- +- test_ArgumentList_imported_function_named_param1() async { +- // +- addTestSource('main() { int.parse("16", r^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'}); +- } +- +- test_ArgumentList_imported_function_named_param2() async { +- // +- addTestSource('main() { int.parse("16", radix: 7, ^);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'onError': '(String) → int'}); +- } +- +- test_ArgumentList_imported_function_named_param2a() async { +- // +- addTestSource('main() { int.parse("16", radix: ^);}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_imported_function_named_param_label1() async { +- // +- addTestSource('main() { int.parse("16", r^: 16);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'}, +- includeColon: false); +- } +- +- test_ArgumentList_imported_function_named_param_label2() async { +- // +- addTestSource('main() { int.parse("16", ^r: 16);}'); +- await computeSuggestions(); +- assertSuggestions(['radix: ,', 'onError: ,']); +- } +- +- test_ArgumentList_imported_function_named_param_label3() async { +- // +- addTestSource('main() { int.parse("16", ^: 16);}'); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'}); +- } +- +- test_ArgumentList_local_constructor_named_fieldFormal_documentation() async { +- String content = ''' +-class A { +- /// aaa +- /// +- /// bbb +- /// ccc +- int fff; +- A({this.fff}); +-} +-main() { +- new A(^); +-} +-'''; +- addTestSource(content); +- await computeSuggestions(); +- expect(suggestions, hasLength(1)); +- +- CompletionSuggestion suggestion = suggestions[0]; +- expect(suggestion.docSummary, 'aaa'); +- expect(suggestion.docComplete, 'aaa\n\nbbb\nccc'); +- +- Element element = suggestion.element; +- expect(element, isNotNull); +- expect(element.kind, ElementKind.PARAMETER); +- expect(element.name, 'fff'); +- expect(element.location.offset, content.indexOf('fff})')); +- } +- +- test_ArgumentList_local_constructor_named_fieldFormal_noDocumentation() async { +- String content = ''' +-class A { +- int fff; +- A({this.fff}); +-} +-main() { +- new A(^); +-} +-'''; +- addTestSource(content); +- await computeSuggestions(); +- expect(suggestions, hasLength(1)); +- +- CompletionSuggestion suggestion = suggestions[0]; +- expect(suggestion.docSummary, isNull); +- expect(suggestion.docComplete, isNull); +- +- Element element = suggestion.element; +- expect(element, isNotNull); +- expect(element.kind, ElementKind.PARAMETER); +- expect(element.name, 'fff'); +- expect(element.location.offset, content.indexOf('fff})')); +- } +- +- test_ArgumentList_local_constructor_named_param() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(^);}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_1() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(o^);}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_2() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(^o,);}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_3() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(two: 'foo', ^);}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_4() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(two: 'foo', o^);}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_5() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(two: 'foo', o^,);}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'}); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_6() async { +- // +- addTestSource(''' +-class A { A.foo({int one, String two: 'defaultValue'}) { } } +-main() { new A.foo(^);}'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}); +- } +- +- test_ArgumentList_local_constructor_named_param_prefixed_prepend() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(o^ two: 'foo');}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int'}, includeComma: true); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ,', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_prepend() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(^ two: 'foo');}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int'}, includeComma: true); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ,', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_prepend_1() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(o^, two: 'foo');}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int'}, includeComma: false); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_named_param_prepend_2() async { +- // +- addTestSource(''' +-class A { A({int one, String two: 'defaultValue'}) { } } +-main() { new A(^, two: 'foo');}'''); +- await computeSuggestions(); +- +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int'}, includeComma: false); +- assertSuggestArgumentAndCompletion('one', +- completion: 'one: ', selectionOffset: 5); +- } +- +- test_ArgumentList_local_constructor_required_param_0() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +-class A { A({int one, @required String two: 'defaultValue'}) { } } +-main() { new A(^);}'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'one': 'int', 'two': 'String'}, +- requiredParamIndices: [1]); +- } +- +- test_ArgumentList_local_function_1() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg) { } +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg'], ['dynamic']); +- } +- +- test_ArgumentList_local_function_2() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg1, int arg2) { } +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']); +- } +- +- test_ArgumentList_local_function_3() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg1, int arg2) { } +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']); +- } +- +- test_ArgumentList_local_function_3a() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg1, int arg2, {bool arg3}) { } +- class B { } +- String bar() => true; +- void main() {expect('hello', ^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_local_function_3b() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg1, int arg2, {bool arg3}) { } +- class B { } +- String bar() => true; +- void main() {expect('hello', ^x)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_local_function_3c() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg1, int arg2, {bool arg3}) { } +- class B { } +- String bar() => true; +- void main() {expect('hello', x^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_local_function_3d() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addTestSource(''' +- import '/libA.dart' +- expect(arg1, int arg2, {bool arg3}) { } +- class B { } +- String bar() => true; +- void main() {expect('hello', x ^)}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_local_function_named_param() async { +- // +- addTestSource(''' +-f(v,{int radix, int onError(String s)}){} +-main() { f("16", ^);}'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'}); +- } +- +- test_ArgumentList_local_function_named_param1() async { +- // +- addTestSource(''' +-f(v,{int radix, int onError(String s)}){} +-main() { f("16", r^);}'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'}); +- } +- +- test_ArgumentList_local_function_named_param2() async { +- // +- addTestSource(''' +-f(v,{int radix, int onError(String s)}){} +-main() { f("16", radix: 7, ^);}'''); +- await computeSuggestions(); +- assertSuggestArgumentsAndTypes( +- namedArgumentsWithTypes: {'onError': '(String) → int'}); +- } +- +- test_ArgumentList_local_function_named_param2a() async { +- // +- addTestSource(''' +-f(v,{int radix, int onError(String s)}){} +-main() { f("16", radix: ^);}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_local_method_0() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { +- expect() { } +- void foo() {expect(^)}} +- String bar() => true;'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ArgumentList_local_method_2() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { +- expect(arg, int blat) { } +- void foo() {expect(^)}} +- String bar() => true;'''); +- await computeSuggestions(); +- assertSuggestArgumentList(['arg', 'blat'], ['dynamic', 'int']); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart +deleted file mode 100644 +index 0bc60b753b1..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart ++++ /dev/null +@@ -1,153 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(CombinatorContributorTest); +- }); +-} +- +-@reflectiveTest +-class CombinatorContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new CombinatorContributor(); +- } +- +- test_Block_inherited_local() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addTestSource(''' +- class F { var f1; f2() { } } +- class E extends F { var e1; e2() { } } +- class I { int i1; i2() { } } +- class M { var m1; int m2() { } } +- class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_Combinator_hide() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +- library libAB; +- part '/partAB.dart'; +- class A { } +- class B { }'''); +- addSource('/partAB.dart', ''' +- part of libAB; +- var T1; +- PB F1() => new PB(); +- class PB { }'''); +- addSource('/testCD.dart', ''' +- class C { } +- class D { }'''); +- addTestSource(''' +- import "/testAB.dart" hide ^; +- import "/testCD.dart"; +- class X {}'''); +- +- await computeSuggestions(); +- assertSuggestClass('A', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('B', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('PB', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestTopLevelVar('T1', null, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunction('F1', 'PB', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('C'); +- assertNotSuggested('D'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- } +- +- test_Combinator_show() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +- library libAB; +- part '/partAB.dart'; +- class A { } +- class B { } +- class _AB'''); +- addSource('/partAB.dart', ''' +- part of libAB; +- var T1; +- PB F1() => new PB(); +- typedef PB2 F2(int blat); +- class Clz = Object with Object; +- class PB { }'''); +- addSource('/testCD.dart', ''' +- class C { } +- class D { }'''); +- addTestSource(''' +- import "/testAB.dart" show ^; +- import "/testCD.dart"; +- class X {}'''); +- +- await computeSuggestions(); +- assertSuggestClass('A', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('B', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('_AB'); +- assertSuggestClass('PB', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestTopLevelVar('T1', null, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunction('F1', 'PB', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('Clz', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunctionTypeAlias('F2', null, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('C'); +- assertNotSuggested('D'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- } +- +- test_Combinator_show_PI() async { +- addTestSource('import "dart:math" show ^;'); +- await computeSuggestions(); +- assertSuggestTopLevelVar('PI', 'double', +- kind: CompletionSuggestionKind.IDENTIFIER); +- } +- +- test_Combinator_show_recursive() async { +- addSource('/testA.dart', ''' +-class A {} +-'''); +- addSource('/testB.dart', ''' +-export 'testA.dart'; +-export 'testB.dart'; +-class B {} +-'''); +- addTestSource(''' +-import "/testB.dart" show ^; +-'''); +- await computeSuggestions(); +- assertSuggestClass('A', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('B', +- relevance: DART_RELEVANCE_DEFAULT, +- kind: CompletionSuggestionKind.IDENTIFIER); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart +deleted file mode 100644 +index 3aa6d41a222..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart ++++ /dev/null +@@ -1,148 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../../domain_completion_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(CommonUsageSorterTest); +- }); +-} +- +-@reflectiveTest +-class CommonUsageSorterTest extends AbstractCompletionDomainTest { +- Future getSuggestionsWith(Map> selectorRelevance) async { +- var originalSorter = DartCompletionManager.contributionSorter; +- DartCompletionManager.contributionSorter = +- new CommonUsageSorter(selectorRelevance); +- try { +- return await getSuggestions(); +- } finally { +- DartCompletionManager.contributionSorter = originalSorter; +- } +- } +- +- test_ConstructorName() async { +- // SimpleIdentifier ConstructorName InstanceCreationExpression +- addTestFile('import "dart:async"; class A {x() {new Future.^}}'); +- await getSuggestionsWith({ +- 'dart.async.Future': ['value', 'wait'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'delayed'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'value', +- relevance: DART_RELEVANCE_COMMON_USAGE); +- assertNoResult('Future'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +- +- test_PrefixedIdentifier_field() async { +- // SimpleIdentifier PrefixedIdentifeir ExpressionStatement +- addTestFile('class A {static int s1; static int s2; x() {A.^}}'); +- await getSuggestionsWith({ +- '.A': ['s2'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 's1'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 's2', +- relevance: DART_RELEVANCE_COMMON_USAGE); +- assertNoResult('Future'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +- +- test_PrefixedIdentifier_field_inPart() async { +- // SimpleIdentifier PrefixedIdentifeir ExpressionStatement +- addFile('/project/bin/myLib.dart', +- 'library L; part "$testFile"; class A {static int s2;}'); +- addTestFile('part of L; foo() {A.^}'); +- await getSuggestionsWith({ +- 'L.A': ['s2'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 's2', +- relevance: DART_RELEVANCE_COMMON_USAGE); +- assertNoResult('Future'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +- +- test_PrefixedIdentifier_getter() async { +- // SimpleIdentifier PrefixedIdentifeir ExpressionStatement +- addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}'); +- await getSuggestionsWith({ +- '.A': ['g2'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'g2', +- relevance: DART_RELEVANCE_COMMON_USAGE); +- assertNoResult('Future'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +- +- test_PrefixedIdentifier_setter() async { +- // SimpleIdentifier PrefixedIdentifeir ExpressionStatement +- addTestFile('class A {set s1(v) {}; set s2(v) {}; x() {new A().^}}'); +- await getSuggestionsWith({ +- '.A': ['s2'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 's1'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 's2', +- relevance: DART_RELEVANCE_COMMON_USAGE); +- assertNoResult('Future'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +- +- test_PrefixedIdentifier_static_method() async { +- // SimpleIdentifier PrefixedIdentifeir ExpressionStatement +- addTestFile('import "dart:async"; class A {x() {Future.^}}'); +- await getSuggestionsWith({ +- 'dart.async.Future': ['value', 'wait'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'wait', +- relevance: DART_RELEVANCE_COMMON_USAGE - 1); +- assertNoResult('Future'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +- +- test_PropertyAccess() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addTestFile('import "dart:math"; class A {x() {new Random().^}}'); +- await getSuggestionsWith({ +- 'dart.math.Random': ['nextInt', 'nextDouble'] +- }); +- expect(replacementOffset, equals(completionOffset)); +- expect(replacementLength, equals(0)); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextBool'); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextDouble', +- relevance: DART_RELEVANCE_COMMON_USAGE - 1); +- assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextInt', +- relevance: DART_RELEVANCE_COMMON_USAGE); +- assertNoResult('Random'); +- assertNoResult('Object'); +- assertNoResult('A'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart +deleted file mode 100644 +index 469bc3a938c..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart ++++ /dev/null +@@ -1,589 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/completion_core.dart'; +-import 'package:analysis_server/src/services/completion/completion_performance.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart' +- show DartCompletionRequestImpl; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +- +-import '../../../abstract_context.dart'; +-import '../../../src/utilities/flutter_util.dart'; +- +-int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) { +- String c1 = s1.completion.toLowerCase(); +- String c2 = s2.completion.toLowerCase(); +- return c1.compareTo(c2); +-} +- +-abstract class DartCompletionContributorTest extends AbstractContextTest { +- static const String _UNCHECKED = '__UNCHECKED__'; +- String testFile; +- Source testSource; +- int completionOffset; +- int replacementOffset; +- int replacementLength; +- DartCompletionContributor contributor; +- DartCompletionRequest request; +- List suggestions; +- +- /** +- * If `true` and `null` is specified as the suggestion's expected returnType +- * then the actual suggestion is expected to have a `dynamic` returnType. +- * Newer tests return `false` so that they can distinguish between +- * `dynamic` and `null`. +- * Eventually all tests should be converted and this getter removed. +- */ +- bool get isNullExpectedReturnTypeConsideredDynamic => true; +- +- void addTestSource(String content) { +- expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once'); +- completionOffset = content.indexOf('^'); +- expect(completionOffset, isNot(equals(-1)), reason: 'missing ^'); +- int nextOffset = content.indexOf('^', completionOffset + 1); +- expect(nextOffset, equals(-1), reason: 'too many ^'); +- content = content.substring(0, completionOffset) + +- content.substring(completionOffset + 1); +- testSource = addSource(testFile, content); +- } +- +- void assertHasNoParameterInfo(CompletionSuggestion suggestion) { +- expect(suggestion.parameterNames, isNull); +- expect(suggestion.parameterTypes, isNull); +- expect(suggestion.requiredParameterCount, isNull); +- expect(suggestion.hasNamedParameters, isNull); +- } +- +- void assertHasParameterInfo(CompletionSuggestion suggestion) { +- expect(suggestion.parameterNames, isNotNull); +- expect(suggestion.parameterTypes, isNotNull); +- expect(suggestion.parameterNames.length, suggestion.parameterTypes.length); +- expect(suggestion.requiredParameterCount, +- lessThanOrEqualTo(suggestion.parameterNames.length)); +- expect(suggestion.hasNamedParameters, isNotNull); +- } +- +- void assertNoSuggestions({CompletionSuggestionKind kind: null}) { +- if (kind == null) { +- if (suggestions.length > 0) { +- failedCompletion('Expected no suggestions', suggestions); +- } +- return; +- } +- CompletionSuggestion suggestion = suggestions.firstWhere( +- (CompletionSuggestion cs) => cs.kind == kind, +- orElse: () => null); +- if (suggestion != null) { +- failedCompletion('did not expect completion: $completion\n $suggestion'); +- } +- } +- +- void assertNotSuggested(String completion) { +- CompletionSuggestion suggestion = suggestions.firstWhere( +- (CompletionSuggestion cs) => cs.completion == completion, +- orElse: () => null); +- if (suggestion != null) { +- failedCompletion('did not expect completion: $completion\n $suggestion'); +- } +- } +- +- CompletionSuggestion assertSuggest(String completion, +- {CompletionSuggestionKind csKind: CompletionSuggestionKind.INVOCATION, +- int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- ElementKind elemKind: null, +- bool isDeprecated: false, +- bool isPotential: false, +- String elemFile, +- int elemOffset, +- int selectionOffset, +- String paramName, +- String paramType, +- String defaultArgListString: _UNCHECKED, +- List defaultArgumentListTextRanges}) { +- CompletionSuggestion cs = +- getSuggest(completion: completion, csKind: csKind, elemKind: elemKind); +- if (cs == null) { +- failedCompletion('expected $completion $csKind $elemKind', suggestions); +- } +- expect(cs.kind, equals(csKind)); +- if (isDeprecated) { +- expect(cs.relevance, equals(DART_RELEVANCE_LOW)); +- } else { +- expect(cs.relevance, equals(relevance), reason: completion); +- } +- expect(cs.importUri, importUri); +- expect(cs.selectionOffset, equals(selectionOffset ?? completion.length)); +- expect(cs.selectionLength, equals(0)); +- expect(cs.isDeprecated, equals(isDeprecated)); +- expect(cs.isPotential, equals(isPotential)); +- if (cs.element != null) { +- expect(cs.element.location, isNotNull); +- expect(cs.element.location.file, isNotNull); +- expect(cs.element.location.offset, isNotNull); +- expect(cs.element.location.length, isNotNull); +- expect(cs.element.location.startColumn, isNotNull); +- expect(cs.element.location.startLine, isNotNull); +- } +- if (elemFile != null) { +- expect(cs.element.location.file, elemFile); +- } +- if (elemOffset != null) { +- expect(cs.element.location.offset, elemOffset); +- } +- if (paramName != null) { +- expect(cs.parameterName, paramName); +- } +- if (paramType != null) { +- expect(cs.parameterType, paramType); +- } +- if (defaultArgListString != _UNCHECKED) { +- expect(cs.defaultArgumentListString, defaultArgListString); +- } +- if (defaultArgumentListTextRanges != null) { +- expect(cs.defaultArgumentListTextRanges, defaultArgumentListTextRanges); +- } +- return cs; +- } +- +- CompletionSuggestion assertSuggestClass(String name, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- bool isDeprecated: false, +- String elemFile, +- String elemName, +- int elemOffset}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- isDeprecated: isDeprecated, +- elemFile: elemFile, +- elemOffset: elemOffset); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.CLASS)); +- expect(element.name, equals(elemName ?? name)); +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestClassTypeAlias(String name, +- {int relevance: DART_RELEVANCE_DEFAULT, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) { +- CompletionSuggestion cs = +- assertSuggest(name, csKind: kind, relevance: relevance); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.CLASS_TYPE_ALIAS)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestConstructor(String name, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- int elemOffset, +- String defaultArgListString: _UNCHECKED, +- List defaultArgumentListTextRanges}) { +- CompletionSuggestion cs = assertSuggest(name, +- relevance: relevance, +- importUri: importUri, +- elemOffset: elemOffset, +- defaultArgListString: defaultArgListString, +- defaultArgumentListTextRanges: defaultArgumentListTextRanges); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.CONSTRUCTOR)); +- int index = name.indexOf('.'); +- expect(element.name, index >= 0 ? name.substring(index + 1) : ''); +- return cs; +- } +- +- CompletionSuggestion assertSuggestEnum(String completion, +- {bool isDeprecated: false}) { +- CompletionSuggestion suggestion = +- assertSuggest(completion, isDeprecated: isDeprecated); +- expect(suggestion.isDeprecated, isDeprecated); +- expect(suggestion.element.kind, ElementKind.ENUM); +- return suggestion; +- } +- +- CompletionSuggestion assertSuggestEnumConst(String completion, +- {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) { +- CompletionSuggestion suggestion = assertSuggest(completion, +- relevance: relevance, isDeprecated: isDeprecated); +- expect(suggestion.completion, completion); +- expect(suggestion.isDeprecated, isDeprecated); +- expect(suggestion.element.kind, ElementKind.ENUM_CONSTANT); +- return suggestion; +- } +- +- CompletionSuggestion assertSuggestField(String name, String type, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- bool isDeprecated: false}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- elemKind: ElementKind.FIELD, +- isDeprecated: isDeprecated); +- // The returnType represents the type of a field +- expect(cs.returnType, type != null ? type : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.FIELD)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- // The returnType represents the type of a field +- expect(element.returnType, type != null ? type : 'dynamic'); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestFunction(String name, String returnType, +- {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- bool isDeprecated: false, +- int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- String defaultArgListString: _UNCHECKED, +- List defaultArgumentListTextRanges}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- isDeprecated: isDeprecated, +- defaultArgListString: defaultArgListString, +- defaultArgumentListTextRanges: defaultArgumentListTextRanges); +- if (returnType != null) { +- expect(cs.returnType, returnType); +- } else if (isNullExpectedReturnTypeConsideredDynamic) { +- expect(cs.returnType, 'dynamic'); +- } +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.FUNCTION)); +- expect(element.name, equals(name)); +- expect(element.isDeprecated, equals(isDeprecated)); +- String param = element.parameters; +- expect(param, isNotNull); +- expect(param[0], equals('(')); +- expect(param[param.length - 1], equals(')')); +- if (returnType != null) { +- expect(element.returnType, returnType); +- } else if (isNullExpectedReturnTypeConsideredDynamic) { +- expect(element.returnType, 'dynamic'); +- } +- assertHasParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestFunctionTypeAlias( +- String name, String returnType, +- {bool isDeprecated: false, +- int relevance: DART_RELEVANCE_DEFAULT, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- String importUri}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- isDeprecated: isDeprecated); +- if (returnType != null) { +- expect(cs.returnType, returnType); +- } else if (isNullExpectedReturnTypeConsideredDynamic) { +- expect(cs.returnType, 'dynamic'); +- } else { +- expect(cs.returnType, isNull); +- } +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.FUNCTION_TYPE_ALIAS)); +- expect(element.name, equals(name)); +- expect(element.isDeprecated, equals(isDeprecated)); +- // TODO (danrubel) Determine why params are null +- // String param = element.parameters; +- // expect(param, isNotNull); +- // expect(param[0], equals('(')); +- // expect(param[param.length - 1], equals(')')); +- expect(element.returnType, +- equals(returnType != null ? returnType : 'dynamic')); +- // TODO (danrubel) Determine why param info is missing +- // assertHasParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestGetter(String name, String returnType, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- bool isDeprecated: false}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- elemKind: ElementKind.GETTER, +- isDeprecated: isDeprecated); +- expect(cs.returnType, returnType != null ? returnType : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.GETTER)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, +- equals(returnType != null ? returnType : 'dynamic')); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestMethod( +- String name, String declaringType, String returnType, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- bool isDeprecated: false, +- String defaultArgListString: _UNCHECKED, +- List defaultArgumentListTextRanges}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- isDeprecated: isDeprecated, +- defaultArgListString: defaultArgListString, +- defaultArgumentListTextRanges: defaultArgumentListTextRanges); +- expect(cs.declaringType, equals(declaringType)); +- expect(cs.returnType, returnType != null ? returnType : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.METHOD)); +- expect(element.name, equals(name)); +- String param = element.parameters; +- expect(param, isNotNull); +- expect(param[0], equals('(')); +- expect(param[param.length - 1], equals(')')); +- expect(element.returnType, returnType != null ? returnType : 'dynamic'); +- assertHasParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestName(String name, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- CompletionSuggestionKind kind: CompletionSuggestionKind.IDENTIFIER, +- bool isDeprecated: false}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- isDeprecated: isDeprecated); +- expect(cs.completion, equals(name)); +- expect(cs.element, isNull); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestSetter(String name, +- {int relevance: DART_RELEVANCE_DEFAULT, +- String importUri, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, +- relevance: relevance, +- importUri: importUri, +- elemKind: ElementKind.SETTER); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.SETTER)); +- expect(element.name, equals(name)); +- // TODO (danrubel) assert setter param +- //expect(element.parameters, isNull); +- // TODO (danrubel) it would be better if this was always null +- if (element.returnType != null) { +- expect(element.returnType, 'dynamic'); +- } +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType, +- {int relevance: DART_RELEVANCE_DEFAULT, +- CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, +- String importUri}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: kind, relevance: relevance, importUri: importUri); +- if (returnType != null) { +- expect(cs.returnType, returnType); +- } else if (isNullExpectedReturnTypeConsideredDynamic) { +- expect(cs.returnType, 'dynamic'); +- } +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.TOP_LEVEL_VARIABLE)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- if (returnType != null) { +- expect(element.returnType, returnType); +- } else if (isNullExpectedReturnTypeConsideredDynamic) { +- expect(element.returnType, 'dynamic'); +- } +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- /** +- * Return a [Future] that completes with the containing library information +- * after it is accessible via [context.getLibrariesContaining]. +- */ +- Future computeLibrariesContaining([int times = 200]) { +- return driver.getResult(testFile).then((result) => null); +- } +- +- Future computeSuggestions({int times = 200}) async { +- AnalysisResult analysisResult = await driver.getResult(testFile); +- testSource = analysisResult.unit.element.source; +- CompletionRequestImpl baseRequest = new CompletionRequestImpl( +- analysisResult, +- provider, +- testSource, +- completionOffset, +- new CompletionPerformance()); +- +- // Build the request +- Completer requestCompleter = +- new Completer(); +- DartCompletionRequestImpl +- .from(baseRequest) +- .then((DartCompletionRequest request) { +- requestCompleter.complete(request); +- }); +- request = await performAnalysis(times, requestCompleter); +- +- var range = request.target.computeReplacementRange(request.offset); +- replacementOffset = range.offset; +- replacementLength = range.length; +- Completer> suggestionCompleter = +- new Completer>(); +- +- // Request completions +- contributor +- .computeSuggestions(request) +- .then((List computedSuggestions) { +- suggestionCompleter.complete(computedSuggestions); +- }); +- +- // Perform analysis until the suggestions have been computed +- // or the max analysis cycles ([times]) has been reached +- suggestions = await performAnalysis(times, suggestionCompleter); +- expect(suggestions, isNotNull, reason: 'expected suggestions'); +- } +- +- /** +- * Configures the [SourceFactory] to have the `flutter` package in +- * `/packages/flutter/lib` folder. +- */ +- void configureFlutterPkg(Map pathToCode) { +- pathToCode.forEach((path, code) { +- provider.newFile('$flutterPkgLibPath/$path', code); +- }); +- // configure SourceFactory +- Folder myPkgFolder = provider.getResource(flutterPkgLibPath); +- UriResolver pkgResolver = new PackageMapUriResolver(provider, { +- 'flutter': [myPkgFolder] +- }); +- SourceFactory sourceFactory = new SourceFactory( +- [new DartUriResolver(sdk), pkgResolver, resourceResolver]); +- driver.configure(sourceFactory: sourceFactory); +- // force 'flutter' resolution +- addSource( +- '/tmp/other.dart', +- pathToCode.keys +- .map((path) => "import 'package:flutter/$path';") +- .join('\n')); +- } +- +- DartCompletionContributor createContributor(); +- +- void failedCompletion(String message, +- [Iterable completions]) { +- StringBuffer sb = new StringBuffer(message); +- if (completions != null) { +- sb.write('\n found'); +- completions.toList() +- ..sort(suggestionComparator) +- ..forEach((CompletionSuggestion suggestion) { +- sb.write('\n ${suggestion.completion} -> $suggestion'); +- }); +- } +- fail(sb.toString()); +- } +- +- CompletionSuggestion getSuggest( +- {String completion: null, +- CompletionSuggestionKind csKind: null, +- ElementKind elemKind: null}) { +- CompletionSuggestion cs; +- if (suggestions != null) { +- suggestions.forEach((CompletionSuggestion s) { +- if (completion != null && completion != s.completion) { +- return; +- } +- if (csKind != null && csKind != s.kind) { +- return; +- } +- if (elemKind != null) { +- Element element = s.element; +- if (element == null || elemKind != element.kind) { +- return; +- } +- } +- if (cs == null) { +- cs = s; +- } else { +- failedCompletion('expected exactly one $cs', +- suggestions.where((s) => s.completion == completion)); +- } +- }); +- } +- return cs; +- } +- +- Future performAnalysis(int times, Completer completer) async { +- if (completer.isCompleted) { +- return completer.future; +- } +- // We use a delayed future to allow microtask events to finish. The +- // Future.value or Future() constructors use scheduleMicrotask themselves and +- // would therefore not wait for microtask callbacks that are scheduled after +- // invoking this method. +- return new Future.delayed( +- Duration.ZERO, () => performAnalysis(times - 1, completer)); +- } +- +- void resolveSource(String path, String content) { +- addSource(path, content); +- } +- +- @override +- void setUp() { +- super.setUp(); +- testFile = provider.convertPath('/completionTest.dart'); +- contributor = createContributor(); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart +deleted file mode 100644 +index 462d7872ff6..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart ++++ /dev/null +@@ -1,91 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/completion_core.dart'; +-import 'package:analysis_server/src/services/completion/completion_performance.dart'; +-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'; +-import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/task/dart.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(CompletionManagerTest); +- }); +-} +- +-@reflectiveTest +-class CompletionManagerTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new ImportedReferenceContributor(); +- } +- +- test_resolveDirectives() async { +- addSource('/libA.dart', ''' +-library libA; +-/// My class. +-/// Short description. +-/// +-/// Longer description. +-class A {} +-'''); +- addSource('/libB.dart', ''' +-library libB; +-import "/libA.dart" as foo; +-part '$testFile'; +-'''); +- addTestSource('part of libB; main() {^}'); +- +- // Build the request +- CompletionRequestImpl baseRequest = new CompletionRequestImpl( +- await driver.getResult(testFile), +- provider, +- testSource, +- completionOffset, +- new CompletionPerformance()); +- Completer requestCompleter = +- new Completer(); +- DartCompletionRequestImpl +- .from(baseRequest, resultDescriptor: RESOLVED_UNIT1) +- .then((DartCompletionRequest request) { +- requestCompleter.complete(request); +- }); +- request = await performAnalysis(200, requestCompleter); +- +- var directives = request.target.unit.directives; +- +- List imports = request.libraryElement.imports; +- expect(imports, hasLength(directives.length + 1)); +- +- ImportElement importNamed(String expectedUri) { +- List uriList = []; +- for (ImportElement importElement in imports) { +- String uri = importElement.importedLibrary.source.uri.toString(); +- uriList.add(uri); +- if (uri.endsWith(expectedUri)) { +- return importElement; +- } +- } +- fail('Failed to find $expectedUri in $uriList'); +- return null; +- } +- +- void assertImportedLib(String expectedUri) { +- ImportElement importElem = importNamed(expectedUri); +- expect(importElem.importedLibrary.exportNamespace, isNotNull); +- } +- +- // Assert that the new imports each have an export namespace +- assertImportedLib('dart:core'); +- assertImportedLib('libA.dart'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart +deleted file mode 100644 +index 28fcdbec8c1..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart ++++ /dev/null +@@ -1,197 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FieldFormalContributorTest); +- }); +-} +- +-@reflectiveTest +-class FieldFormalContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new FieldFormalContributor(); +- } +- +- test_ThisExpression_constructor_param() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.^) {} +- A.z() {} +- var b; X _c; static sb; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('sb'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param2() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.b^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param3() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.^b) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param4() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.b, this.^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param_optional() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class Point { +- int x; +- int y; +- Point({this.x, this.^}) {} +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('y', 'int', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('x'); +- } +- +- test_ThisExpression_constructor_param_positional() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class Point { +- int x; +- int y; +- Point({this.x, this.^}) {} +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('y', 'int', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('x'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart +deleted file mode 100644 +index 11847a6ff5e..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart ++++ /dev/null +@@ -1,4294 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ImportedReferenceContributorTest); +- }); +-} +- +-@reflectiveTest +-class ImportedReferenceContributorTest extends DartCompletionContributorTest { +- @override +- bool get isNullExpectedReturnTypeConsideredDynamic => false; +- +- @override +- DartCompletionContributor createContributor() { +- return new ImportedReferenceContributor(); +- } +- +- /// Sanity check. Permutations tested in local_ref_contributor. +- test_ArgDefaults_function_with_required_named() async { +- addMetaPackageSource(); +- +- resolveSource('/testB.dart', ''' +-lib B; +-import 'package:meta/meta.dart'; +- +-bool foo(int bar, {bool boo, @required int baz}) => false; +-'''); +- +- addTestSource(''' +-import "/testB.dart"; +- +-void main() {f^}'''); +- await computeSuggestions(); +- +- assertSuggestFunction('foo', 'bool', +- defaultArgListString: 'bar, baz: null'); +- } +- +- test_ArgumentList() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- resolveSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart'; +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool'); +- assertSuggestFunction('identical', 'bool'); +- assertNotSuggested('B'); +- assertSuggestClass('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_imported_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- resolveSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(arg) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool'); +- assertSuggestFunction('identical', 'bool'); +- assertNotSuggested('B'); +- assertSuggestClass('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_functionalArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- class A { A(f()) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { } +- String bar() => true; +- void main() {new A(^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunction('identical', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('B'); +- assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_typedefArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- typedef Funct(); +- class A { A(Funct f) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { } +- String bar() => true; +- void main() {new A(^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunction('identical', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('B'); +- assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- resolveSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- expect(arg) { } +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool'); +- assertSuggestFunction('identical', 'bool'); +- assertNotSuggested('B'); +- assertSuggestClass('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_method() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- resolveSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { +- expect(arg) { } +- void foo() {expect(^)}} +- String bar() => true;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool'); +- assertSuggestFunction('identical', 'bool'); +- assertNotSuggested('B'); +- assertSuggestClass('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_functionalArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- class A { A(f()) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { } +- String bar(f()) => true; +- void main() {bar(^);}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertSuggestFunction('hasLength', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunction('identical', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('B'); +- assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_methodArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- class A { A(f()) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { String bar(f()) => true; } +- void main() {new B().bar(^);}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('hasLength', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestFunction('identical', 'bool', +- kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('B'); +- assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER); +- assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_namedParam() async { +- // SimpleIdentifier NamedExpression ArgumentList MethodInvocation +- // ExpressionStatement +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { }'''); +- addTestSource(''' +- import '/libA.dart' +- String bar() => true; +- void main() {expect(foo: ^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('bar'); +- // An unresolved imported library will produce suggestions +- // with a null returnType +- // The current DartCompletionRequest#resolveExpression resolves +- // the world (which it should not) and causes the imported library +- // to be resolved. +- assertSuggestFunction('hasLength', /* null */ 'bool'); +- assertNotSuggested('main'); +- } +- +- test_AsExpression() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +- class A {var b; X _c; foo() {var a; (a as ^).foo();}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertSuggestClass('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_AsExpression_type_subtype_extends_filter() async { +- // SimpleIdentifier TypeName AsExpression IfStatement +- addSource('/testB.dart', ''' +- foo() { } +- class A {} class B extends A {} class C extends B {} +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- main(){A a; if (a as ^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- } +- +- test_AsExpression_type_subtype_implements_filter() async { +- // SimpleIdentifier TypeName AsExpression IfStatement +- addSource('/testB.dart', ''' +- foo() { } +- class A {} class B implements A {} class C implements B {} +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- main(){A a; if (a as ^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- } +- +- test_AssignmentExpression_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int ^b = 1;}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_AssignmentExpression_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int b = ^}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_AssignmentExpression_type() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- ^ b = 1;}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertSuggestClass('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- ^ +- b = 1;}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertSuggestClass('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertSuggestFunction('identical', 'bool'); +- } +- +- test_AssignmentExpression_type_partial() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- int^ b = 1;}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('A'); +- assertSuggestClass('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- i^ +- b = 1;}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertSuggestClass('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertSuggestFunction('identical', 'bool'); +- } +- +- test_AwaitExpression() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- addTestSource(''' +- class A {int x; int y() => 0;} +- main() async {A a; await ^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_AwaitExpression_function() async { +- resolveSource('/libA.dart', ''' +-Future y() async {return 0;} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- int x; +- foo() async {await ^} +-} +-'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestFunction('y', 'dynamic'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_AwaitExpression_inherited() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- addSource('/testB.dart', ''' +-lib libB; +-class A { +- Future y() async { return 0; } +-}'''); +- addTestSource(''' +-import "/testB.dart"; +-class B extends A { +- foo() async {await ^} +-} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertSuggestClass('A'); +- assertSuggestClass('Object'); +- assertNotSuggested('y'); +- } +- +- test_BinaryExpression_LHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = ^ + 2;}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertSuggestClass('Object'); +- assertNotSuggested('b'); +- } +- +- test_BinaryExpression_RHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = 2 + ^;}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertSuggestClass('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('=='); +- } +- +- test_Block() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- ^ var r; +- } +- void b() { }} +- class Z { }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertSuggestClass('A', elemFile: '/testAB.dart'); +- assertNotSuggested('_B'); +- assertSuggestClass('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW); +- //assertSuggestFunction( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertSuggestClass('EE'); +- // hidden element suggested as low relevance +- //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertSuggestClass('g.G', elemName: 'G'); +- assertNotSuggested('G'); +- //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW); +- assertSuggestClass('Object'); +-// assertSuggestFunction('min', 'T'); +- //assertSuggestFunction( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertSuggestTopLevelVar('T1', null); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertSuggestClass('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- final ^ +- } +- void b() { }} +- class Z { }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertSuggestClass('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW); +- //assertSuggestFunction( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertSuggestClass('EE'); +- // hidden element suggested as low relevance +- //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertSuggestClass('g.G', elemName: 'G'); +- //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW); +- assertSuggestClass('Object'); +- assertNotSuggested('min'); +- //assertSuggestFunction( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertSuggestClass('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final2() async { +- addTestSource('main() {final S^ v;}'); +- +- await computeSuggestions(); +- assertSuggestClass('String'); +- } +- +- test_Block_final3() async { +- addTestSource('main() {final ^ v;}'); +- +- await computeSuggestions(); +- assertSuggestClass('String'); +- } +- +- test_Block_final_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g hide G; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- final var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +- class Z { }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertSuggestClass('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW); +- //assertSuggestFunction( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertSuggestClass('EE'); +- // hidden element suggested as low relevance +- //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- // Hidden elements not suggested +- assertNotSuggested('g.G'); +- //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW); +- assertSuggestClass('Object'); +- assertNotSuggested('min'); +- //assertSuggestFunction( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertSuggestClass('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final_var() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +- class Z { }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertSuggestClass('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW); +- //assertSuggestFunction( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertSuggestClass('EE'); +- // hidden element suggested as low relevance +- //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertSuggestClass('g.G', elemName: 'G'); +- //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW); +- assertSuggestClass('Object'); +- assertNotSuggested('min'); +- //assertSuggestFunction( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertSuggestClass('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_identifier_partial() async { +- resolveSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B { }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class DF { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- class D3 { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g; +- int T5; +- var _T6; +- Z D2() {int x;} +- class X {a() {var f; {var x;} D^ var r;} void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- +- // imported elements are portially filtered +- //assertSuggestClass('A'); +- assertNotSuggested('_B'); +- // hidden element not suggested +- assertNotSuggested('D'); +- assertSuggestFunction('D1', 'dynamic', +- isDeprecated: true, relevance: DART_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- // Not imported, so not suggested +- assertNotSuggested('D3'); +- //assertSuggestClass('EE'); +- // hidden element not suggested +- assertNotSuggested('DF'); +- //assertSuggestLibraryPrefix('g'); +- assertSuggestClass('g.G', elemName: 'G'); +- //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW); +- //assertSuggestClass('Object'); +- //assertSuggestFunction('min', 'num', false); +- //assertSuggestFunction( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- //assertSuggestTopLevelVarGetterSetter('T1', 'String'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- //assertNotSuggested('T5'); +- //assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- } +- +- test_Block_inherited_imported() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addSource('/testB.dart', ''' +- lib B; +- class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; } +- class E extends F { var e1; e2() { } } +- class I { int i1; i2() { } } +- class M { var m1; int m2() { } }'''); +- addTestSource(''' +- import "/testB.dart"; +- class A extends E implements I with M {a() {^}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // TODO (danrubel) prefer fields over getters +- // If add `get e1;` to interface I +- // then suggestions include getter e1 rather than field e1 +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- //assertNotSuggested('m2', null, null); +- assertNotSuggested('=='); +- } +- +- test_Block_inherited_local() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addTestSource(''' +- class F { var f1; f2() { } get f3 => 0; set f4(fx) { } } +- class E extends F { var e1; e2() { } } +- class I { int i1; i2() { } } +- class M { var m1; int m2() { } } +- class A extends E implements I with M {a() {^}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- assertNotSuggested('m2'); +- } +- +- test_Block_local_function() async { +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- p^ var r; +- } +- void b() { }} +- class Z { }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertNotSuggested('partT8'); +- assertNotSuggested('partBoo'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_partial_results() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B { }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "/testAB.dart"; +- import "/testCD.dart" hide D; +- import "/testEEF.dart" show EE; +- import "/testG.dart" as g; +- int T5; +- var _T6; +- Z D2() {int x;} +- class X {a() {var f; {var x;} ^ var r;} void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- assertSuggestClass('C'); +- assertNotSuggested('H'); +- } +- +- test_Block_unimported() async { +- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }'); +- addSource( +- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }'); +- testFile = '/proj/completionTest.dart'; +- addTestSource('class C {foo(){F^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Not imported, so not suggested +- assertNotSuggested('Foo'); +- assertNotSuggested('Foo2'); +- assertNotSuggested('Future'); +- } +- +- test_CascadeExpression_selector1() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "/testB.dart"; +- class A {var b; X _c;} +- class X{} +- // looks like a cascade to the parser +- // but the user is trying to get completions for a non-cascade +- main() {A a; a.^.z}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2() async { +- // SimpleIdentifier PropertyAccess CascadeExpression ExpressionStatement +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "/testB.dart"; +- class A {var b; X _c;} +- class X{} +- main() {A a; a..^z}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2_withTrailingReturn() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "/testB.dart"; +- class A {var b; X _c;} +- class X{} +- main() {A a; a..^ return}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_target() async { +- // SimpleIdentifier CascadeExpression ExpressionStatement +- addTestSource(''' +- class A {var b; X _c;} +- class X{} +- main() {A a; a^..b}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- // top level results are partially filtered +- //assertSuggestClass('Object'); +- assertNotSuggested('=='); +- } +- +- test_CatchClause_onType() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^ {}}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_onType_noBrackets() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_typed() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e'); +- assertNotSuggested('a'); +- assertSuggestClass('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_untyped() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e'); +- assertNotSuggested('s'); +- assertNotSuggested('a'); +- assertSuggestClass('Object'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- @deprecated class A {^} +- class _B {} +- A T;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- CompletionSuggestion suggestionO = assertSuggestClass('Object'); +- if (suggestionO != null) { +- expect(suggestionO.element.isDeprecated, isFalse); +- expect(suggestionO.element.isPrivate, isFalse); +- } +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^} +- class _B {} +- A T;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^ A(){}} +- class _B {} +- A T;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('String'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field2() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as Soo; +- class A {final S^ A();} +- class _B {} +- A Sew;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('String'); +- assertNotSuggested('Sew'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('Soo'); +- } +- +- test_ClassDeclaration_body_final_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^ final foo;} +- class _B {} +- A T;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_var() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^ var foo;} +- class _B {} +- A T;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertSuggestClass('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_Combinator_hide() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +- library libAB; +- part '/partAB.dart'; +- class A { } +- class B { }'''); +- addSource('/partAB.dart', ''' +- part of libAB; +- var T1; +- PB F1() => new PB(); +- class PB { }'''); +- addSource('/testCD.dart', ''' +- class C { } +- class D { }'''); +- addTestSource(''' +- import "/testAB.dart" hide ^; +- import "/testCD.dart"; +- class X {}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_Combinator_show() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +- library libAB; +- part '/partAB.dart'; +- class A { } +- class B { }'''); +- addSource('/partAB.dart', ''' +- part of libAB; +- var T1; +- PB F1() => new PB(); +- typedef PB2 F2(int blat); +- class Clz = Object with Object; +- class PB { }'''); +- addSource('/testCD.dart', ''' +- class C { } +- class D { }'''); +- addTestSource(''' +- import "/testAB.dart" show ^; +- import "/testCD.dart"; +- class X {}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ConditionalExpression_elseExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T1 : T^}}'''); +- +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_elseExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T1 : ^}}'''); +- +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertSuggestClass('A'); +- assertSuggestFunction('F1', 'dynamic'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_partial_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T^}}'''); +- +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_partial_thenExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? ^}}'''); +- +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertSuggestClass('A'); +- assertSuggestFunction('F1', 'dynamic'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T^ : c}}'''); +- +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConstructorName_importedClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- var m; +- main() {new X.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- var m; +- main() {new X.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- main() {new String.fr^omCharCodes([]);}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 13); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('fromCharCodes'); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('isNotEmpty'); +- assertNotSuggested('length'); +- assertNotSuggested('Object'); +- assertNotSuggested('String'); +- } +- +- test_ConstructorName_localClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}} +- main() {new X.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_localFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- int T1; +- F1() { } +- class X {factory X.c(); factory X._d(); z() {}} +- main() {new X.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_DefaultFormalParameter_named_expression() async { +- // DefaultFormalParameter FormalParameterList MethodDeclaration +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {a(blat: ^) { }}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertSuggestClass('String'); +- assertSuggestFunction('identical', 'bool'); +- assertNotSuggested('bar'); +- } +- +- test_doc_class() async { +- addSource('/libA.dart', r''' +-library A; +-/// My class. +-/// Short description. +-/// +-/// Longer description. +-class A {} +-'''); +- addTestSource('import "/libA.dart"; main() {^}'); +- +- await computeSuggestions(); +- +- CompletionSuggestion suggestion = assertSuggestClass('A'); +- expect(suggestion.docSummary, 'My class.\nShort description.'); +- expect(suggestion.docComplete, +- 'My class.\nShort description.\n\nLonger description.'); +- } +- +- test_doc_function() async { +- resolveSource('/libA.dart', r''' +-library A; +-/// My function. +-/// Short description. +-/// +-/// Longer description. +-int myFunc() {} +-'''); +- addTestSource('import "/libA.dart"; main() {^}'); +- +- await computeSuggestions(); +- +- CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int'); +- expect(suggestion.docSummary, 'My function.\nShort description.'); +- expect(suggestion.docComplete, +- 'My function.\nShort description.\n\nLonger description.'); +- } +- +- test_doc_function_c_style() async { +- resolveSource('/libA.dart', r''' +-library A; +-/** +- * My function. +- * Short description. +- * +- * Longer description. +- */ +-int myFunc() {} +-'''); +- addTestSource('import "/libA.dart"; main() {^}'); +- +- await computeSuggestions(); +- +- CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int'); +- expect(suggestion.docSummary, 'My function.\nShort description.'); +- expect(suggestion.docComplete, +- 'My function.\nShort description.\n\nLonger description.'); +- } +- +- test_enum() async { +- addSource('/libA.dart', 'library A; enum E { one, two }'); +- addTestSource('import "/libA.dart"; main() {^}'); +- await computeSuggestions(); +- assertSuggestEnum('E'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- } +- +- test_enum_deprecated() async { +- addSource('/libA.dart', 'library A; @deprecated enum E { one, two }'); +- addTestSource('import "/libA.dart"; main() {^}'); +- await computeSuggestions(); +- // TODO(danrube) investigate why suggestion/element is not deprecated +- // when AST node has correct @deprecated annotation +- assertSuggestEnum('E', isDeprecated: true); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- } +- +- test_ExpressionStatement_identifier() async { +- // SimpleIdentifier ExpressionStatement Block +- resolveSource('/testA.dart', ''' +- _B F1() { } +- class A {int x;} +- class _B { }'''); +- addTestSource(''' +- import "/testA.dart"; +- typedef int F2(int blat); +- class Clz = Object with Object; +- class C {foo(){^} void bar() {}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestFunction('F1', '_B'); +- assertNotSuggested('C'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('F2'); +- assertNotSuggested('Clz'); +- assertNotSuggested('C'); +- assertNotSuggested('x'); +- assertNotSuggested('_B'); +- } +- +- test_ExpressionStatement_name() async { +- // ExpressionStatement Block BlockFunctionBody MethodDeclaration +- addSource('/testA.dart', ''' +- B T1; +- class B{}'''); +- addTestSource(''' +- import "/testA.dart"; +- class C {a() {C ^}}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_typed() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "/testA.dart"; +- class C {A ^}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_var() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "/testA.dart"; +- class C {var ^}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_FieldFormalParameter_in_non_constructor() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource('class A {B(this.^foo) {}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 3); +- assertNoSuggestions(); +- } +- +- test_ForEachStatement_body_typed() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (int foo in bar) {^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertSuggestClass('Object'); +- } +- +- test_ForEachStatement_body_untyped() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (foo in bar) {^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertSuggestClass('Object'); +- } +- +- test_ForEachStatement_iterable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (int foo in ^) {}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertSuggestClass('Object'); +- } +- +- test_ForEachStatement_loopVariable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ in args) {}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertSuggestClass('String'); +- } +- +- test_ForEachStatement_loopVariable_type() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ foo in args) {}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertSuggestClass('String'); +- } +- +- test_ForEachStatement_loopVariable_type2() async { +- // DeclaredIdentifier ForEachStatement Block +- addTestSource('main(args) {for (S^ foo in args) {}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertSuggestClass('String'); +- } +- +- test_FormalParameterList() async { +- // FormalParameterList MethodDeclaration +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {a(^) { }}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertSuggestClass('String'); +- assertNotSuggested('identical'); +- assertNotSuggested('bar'); +- } +- +- test_ForStatement_body() async { +- // Block ForStatement +- addTestSource('main(args) {for (int i; i < 10; ++i) {^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('i'); +- assertSuggestClass('Object'); +- } +- +- test_ForStatement_condition() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; i^)}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- } +- +- test_ForStatement_initializer() async { +- addTestSource(''' +-import 'dart:math'; +-main() { +- List localVar; +- for (^) {} +-} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('localVar'); +- assertNotSuggested('PI'); +- assertSuggestClass('Object'); +- assertSuggestClass('int'); +- } +- +- test_ForStatement_initializer_variableName_afterType() async { +- addTestSource('main() { for (String ^) }'); +- await computeSuggestions(); +- assertNotSuggested('int'); +- } +- +- test_ForStatement_typing_inKeyword() async { +- addTestSource('main() { for (var v i^) }'); +- await computeSuggestions(); +- assertNotSuggested('int'); +- } +- +- test_ForStatement_updaters() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; index < 10; i^)}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- } +- +- test_ForStatement_updaters_prefix_expression() async { +- // SimpleIdentifier PrefixExpression ForStatement +- addTestSource(''' +- void bar() { } +- main() {for (int index = 0; index < 10; ++i^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- assertNotSuggested('main'); +- assertNotSuggested('bar'); +- } +- +- test_function_parameters_mixed_required_and_named() async { +- resolveSource('/libA.dart', ''' +-int m(x, {int y}) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'int'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_function_parameters_mixed_required_and_positional() async { +- resolveSource('/libA.dart', ''' +-void m(x, [int y]) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_function_parameters_named() async { +- resolveSource('/libA.dart', ''' +-void m({x, int y}) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_function_parameters_none() async { +- resolveSource('/libA.dart', ''' +-void m() {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, isEmpty); +- expect(suggestion.parameterTypes, isEmpty); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_function_parameters_positional() async { +- resolveSource('/libA.dart', ''' +-void m([x, int y]) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_function_parameters_required() async { +- resolveSource('/libA.dart', ''' +-void m(x, int y) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 2); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_FunctionDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- /* */ ^ zoo(z) { } String name;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment2() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- /** */ ^ zoo(z) { } String name;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment3() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- /// some dartdoc +- class C2 { } +- ^ zoo(z) { } String name;'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionExpression_body_function() async { +- // Block BlockFunctionBody FunctionExpression +- addTestSource(''' +- void bar() { } +- String foo(List args) {x.then((R b) {^});}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('args'); +- assertNotSuggested('b'); +- assertSuggestClass('Object'); +- } +- +- test_IfStatement() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (true) ^}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertSuggestClass('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_condition() async { +- // SimpleIdentifier IfStatement Block BlockFunctionBody +- addTestSource(''' +- class A {int x; int y() => 0;} +- main(){var a; if (^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_IfStatement_empty() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (^) something}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertSuggestClass('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_invocation() async { +- // SimpleIdentifier PrefixIdentifier IfStatement +- addTestSource(''' +- main() {var a; if (a.^) something}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('toString'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_typing_isKeyword() async { +- addTestSource('main() { if (v i^) }'); +- await computeSuggestions(); +- assertNotSuggested('int'); +- } +- +- test_ImportDirective_dart() async { +- // SimpleStringLiteral ImportDirective +- addTestSource(''' +- import "dart^"; +- main() {}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_IndexExpression() async { +- // ExpressionStatement Block +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} f[^]}}'''); +- +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertSuggestClass('A'); +- assertSuggestFunction('F1', 'dynamic'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_IndexExpression2() async { +- // SimpleIdentifier IndexExpression ExpressionStatement Block +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} f[T^]}}'''); +- +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_InstanceCreationExpression() async { +- resolveSource('/testA.dart', ''' +-class A {foo(){var f; {var x;}}} +-class B {B(this.x, [String boo]) { } int x;} +-class C {C.bar({boo: 'hoo', int z: 0}) { } }'''); +- addTestSource(''' +-import "/testA.dart"; +-import "dart:math" as math; +-main() {new ^ String x = "hello";}'''); +- +- await computeSuggestions(); +- CompletionSuggestion suggestion; +- +- suggestion = assertSuggestConstructor('Object'); +- expect(suggestion.element.parameters, '()'); +- expect(suggestion.parameterNames, hasLength(0)); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- +- suggestion = assertSuggestConstructor('A'); +- expect(suggestion.element.parameters, '()'); +- expect(suggestion.parameterNames, hasLength(0)); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- +- suggestion = assertSuggestConstructor('B'); +- expect(suggestion.element.parameters, '(int x, [String boo])'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'int'); +- expect(suggestion.parameterNames[1], 'boo'); +- expect(suggestion.parameterTypes[1], 'String'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- +- suggestion = assertSuggestConstructor('C.bar'); +- expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})"); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'boo'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'z'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('math'); +- } +- +- test_InstanceCreationExpression_imported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {A(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- import "dart:async"; +- int T2; +- F2() { } +- class B {B(this.x, [String boo]) { } int x;} +- class C {foo(){var f; {var x;} new ^}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestConstructor('Object'); +- assertSuggestConstructor('Future'); +- assertSuggestConstructor('A'); +- // Suggested by ConstructorContributor +- assertNotSuggested('B'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('foo'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- // An unresolved imported library will produce suggestions +- // with a null returnType +- // The current DartCompletionRequest#resolveExpression resolves +- // the world (which it should not) and causes the imported library +- // to be resolved. +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- } +- +- test_InstanceCreationExpression_unimported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){new F^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Not imported, so not suggested +- assertNotSuggested('Future'); +- assertNotSuggested('Foo'); +- } +- +- test_internal_sdk_libs() async { +- addTestSource('main() {p^}'); +- +- await computeSuggestions(); +- assertSuggest('print'); +- // Not imported, so not suggested +- assertNotSuggested('pow'); +- // Do not suggest completions from internal SDK library +- assertNotSuggested('printToConsole'); +- } +- +- test_InterpolationExpression() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- main() {String name; print("hello \$^");}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertSuggestTopLevelVar('T1', null); +- assertSuggestFunction('F1', null); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_InterpolationExpression_block() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- main() {String name; print("hello \${^}");}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- // Simulate unresolved imported library +- // in which case suggestions will have null (unresolved) returnType +- assertSuggestTopLevelVar('T1', null); +- assertSuggestFunction('F1', null); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_InterpolationExpression_block2() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addTestSource('main() {String name; print("hello \${n^}");}'); +- +- await computeSuggestions(); +- assertNotSuggested('name'); +- // top level results are partially filtered +- //assertSuggestClass('Object'); +- } +- +- test_InterpolationExpression_prefix_selector() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${name.^}");}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('length'); +- assertNotSuggested('name'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_InterpolationExpression_prefix_selector2() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \$name.^");}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_InterpolationExpression_prefix_target() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${nam^e.length}");}'); +- +- await computeSuggestions(); +- assertNotSuggested('name'); +- // top level results are partially filtered +- //assertSuggestClass('Object'); +- assertNotSuggested('length'); +- } +- +- test_IsExpression() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addSource('/testB.dart', ''' +- lib B; +- foo() { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- class Y {Y.c(); Y._d(); z() {}} +- main() {var x; if (x is ^) { }}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('x'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- } +- +- test_IsExpression_target() async { +- // IfStatement Block BlockFunctionBody +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {int x; int y() => 0;} +- main(){var a; if (^ is A)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_IsExpression_type() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +- class A {int x; int y() => 0;} +- main(){var a; if (a is ^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_IsExpression_type_partial() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +- class A {int x; int y() => 0;} +- main(){var a; if (a is Obj^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertSuggestClass('Object'); +- } +- +- test_IsExpression_type_subtype_extends_filter() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addSource('/testB.dart', ''' +- foo() { } +- class A {} class B extends A {} class C extends B {} +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- main(){A a; if (a is ^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- } +- +- test_IsExpression_type_subtype_implements_filter() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addSource('/testB.dart', ''' +- foo() { } +- class A {} class B implements A {} class C implements B {} +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- main(){A a; if (a is ^)}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- } +- +- test_keyword() async { +- resolveSource('/testB.dart', ''' +- lib B; +- int newT1; +- int T1; +- nowIsIt() { } +- class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- String newer() {} +- var m; +- main() {new^ X.c();}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- // Imported suggestion are filtered by 1st character +- assertSuggestFunction('nowIsIt', 'dynamic'); +- assertSuggestTopLevelVar('T1', 'int'); +- assertSuggestTopLevelVar('newT1', 'int'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- assertNotSuggested('newer'); +- } +- +- test_Literal_list() async { +- // ']' ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([^]);}'); +- +- await computeSuggestions(); +- assertNotSuggested('Some'); +- assertSuggestClass('String'); +- } +- +- test_Literal_list2() async { +- // SimpleIdentifier ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([S^]);}'); +- +- await computeSuggestions(); +- assertNotSuggested('Some'); +- assertSuggestClass('String'); +- } +- +- test_Literal_string() async { +- // SimpleStringLiteral ExpressionStatement Block +- addTestSource('class A {a() {"hel^lo"}}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_localVariableDeclarationName() async { +- addTestSource('main() {String m^}'); +- await computeSuggestions(); +- assertNotSuggested('main'); +- assertNotSuggested('min'); +- } +- +- test_MapLiteralEntry() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- foo = {^'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- // Simulate unresolved imported library, +- // in which case suggestions will have null return types (unresolved) +- // The current DartCompletionRequest#resolveExpression resolves +- // the world (which it should not) and causes the imported library +- // to be resolved. +- assertSuggestTopLevelVar('T1', /* null */ 'int'); +- assertSuggestFunction('F1', /* null */ 'dynamic'); +- assertSuggestFunctionTypeAlias('D1', /* null */ 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- } +- +- test_MapLiteralEntry1() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- foo = {T^'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Simulate unresolved imported library, +- // in which case suggestions will have null return types (unresolved) +- // The current DartCompletionRequest#resolveExpression resolves +- // the world (which it should not) and causes the imported library +- // to be resolved. +- assertSuggestTopLevelVar('T1', /* null */ 'int'); +- assertNotSuggested('T2'); +- } +- +- test_MapLiteralEntry2() async { +- // SimpleIdentifier MapLiteralEntry MapLiteral VariableDeclaration +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- foo = {7:T^};'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestTopLevelVar('T1', 'int'); +- assertNotSuggested('T2'); +- } +- +- test_method_parameters_mixed_required_and_named() async { +- resolveSource('/libA.dart', ''' +-void m(x, {int y}) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_mixed_required_and_positional() async { +- resolveSource('/libA.dart', ''' +-void m(x, [int y]) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_named() async { +- resolveSource('/libA.dart', ''' +-void m({x, int y}) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_none() async { +- resolveSource('/libA.dart', ''' +-void m() {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, isEmpty); +- expect(suggestion.parameterTypes, isEmpty); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_positional() async { +- resolveSource('/libA.dart', ''' +-void m([x, int y]) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_required() async { +- resolveSource('/libA.dart', ''' +-void m(x, int y) {} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 2); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_MethodDeclaration_body_getters() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- } +- +- test_MethodDeclaration_body_static() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testC.dart', ''' +- class C { +- c1() {} +- var c2; +- static c3() {} +- static var c4;}'''); +- addTestSource(''' +- import "/testC.dart"; +- class B extends C { +- b1() {} +- var b2; +- static b3() {} +- static var b4;} +- class A extends B { +- a1() {} +- var a2; +- static a3() {} +- static var a4; +- static a() {^}}'''); +- +- await computeSuggestions(); +- assertNotSuggested('a1'); +- assertNotSuggested('a2'); +- assertNotSuggested('a3'); +- assertNotSuggested('a4'); +- assertNotSuggested('b1'); +- assertNotSuggested('b2'); +- assertNotSuggested('b3'); +- assertNotSuggested('b4'); +- assertNotSuggested('c1'); +- assertNotSuggested('c2'); +- assertNotSuggested('c3'); +- assertNotSuggested('c4'); +- } +- +- test_MethodDeclaration_members() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('_a'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertSuggestClass('bool'); +- } +- +- test_MethodDeclaration_parameters_named() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('b'); +- assertSuggestClass('int'); +- assertNotSuggested('_'); +- } +- +- test_MethodDeclaration_parameters_positional() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {Z a(X x, [int y=1]) {^}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertSuggestClass('String'); +- } +- +- test_MethodDeclaration_returnType() async { +- // ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 {^ zoo(z) { } String name; }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 {/* */ ^ zoo(z) { } String name; }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment2() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 {/** */ ^ zoo(z) { } String name; }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment3() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- resolveSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "/testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { +- /// some dartdoc +- ^ zoo(z) { } String name; }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertSuggestFunctionTypeAlias('D1', 'dynamic'); +- assertSuggestClass('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodInvocation_no_semicolon() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {x.^ m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_mixin_ordering() async { +- addSource('/libA.dart', ''' +-class B {} +-class M1 { +- void m() {} +-} +-class M2 { +- void m() {} +-} +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class C extends B with M1, M2 { +- void f() { +- ^ +- } +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- /** +- * Ensure that completions in one context don't appear in another +- */ +- test_multiple_contexts() async { +- // Create a 2nd context with source +- var context2 = AnalysisEngine.instance.createAnalysisContext(); +- context2.sourceFactory = +- new SourceFactory([new DartUriResolver(sdk), resourceResolver]); +- String content2 = 'class ClassFromAnotherContext { }'; +- Source source2 = +- provider.newFile('/context2/foo.dart', content2).createSource(); +- ChangeSet changeSet = new ChangeSet(); +- changeSet.addedSource(source2); +- context2.applyChanges(changeSet); +- context2.setContents(source2, content2); +- +- // Resolve the source in the 2nd context and update the index +- var result = context2.performAnalysisTask(); +- while (result.hasMoreWork) { +- result = context2.performAnalysisTask(); +- } +- +- // Check that source in 2nd context does not appear in completion in 1st +- addSource('/context1/libA.dart', ''' +- library libA; +- class ClassInLocalContext {int x;}'''); +- testFile = '/context1/completionTest.dart'; +- addTestSource(''' +- import "/context1/libA.dart"; +- import "/foo.dart"; +- main() {C^} +- '''); +- +- await computeSuggestions(); +- assertSuggestClass('ClassInLocalContext'); +- // Assert contributor does not include results from 2nd context. +- assertNotSuggested('ClassFromAnotherContext'); +- } +- +- test_new_instance() async { +- addTestSource('import "dart:math"; class A {x() {new Random().^}}'); +- +- await computeSuggestions(); +- assertNotSuggested('nextBool'); +- assertNotSuggested('nextDouble'); +- assertNotSuggested('nextInt'); +- assertNotSuggested('Random'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- } +- +- test_no_parameters_field() async { +- addSource('/libA.dart', ''' +-int x; +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestTopLevelVar('x', null); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_no_parameters_getter() async { +- resolveSource('/libA.dart', ''' +-int get x => null; +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestGetter('x', 'int'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_no_parameters_setter() async { +- addSource('/libA.dart', ''' +-set x(int value) {}; +-'''); +- addTestSource(''' +-import '/libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestSetter('x'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_parameterName_excludeTypes() async { +- addTestSource('m(int ^) {}'); +- await computeSuggestions(); +- assertNotSuggested('int'); +- assertNotSuggested('bool'); +- } +- +- test_partFile_TypeName() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- library libA; +- import "/testB.dart"; +- part "$testFile"; +- class A { } +- var m;'''); +- addTestSource(''' +- part of libA; +- class B { factory B.bar(int x) => null; } +- main() {new ^}'''); +- +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by ConstructorContributor +- assertNotSuggested('B.bar'); +- assertSuggestConstructor('Object'); +- assertSuggestConstructor('X.c'); +- assertNotSuggested('X._d'); +- // Suggested by LocalLibraryContributor +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_TypeName2() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +- lib libB; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- part of libA; +- class B { }'''); +- addTestSource(''' +- library libA; +- import "/testB.dart"; +- part "/testA.dart"; +- class A { A({String boo: 'hoo'}) { } } +- main() {new ^} +- var m;'''); +- +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by ConstructorContributor +- assertNotSuggested('A'); +- assertSuggestConstructor('Object'); +- assertSuggestConstructor('X.c'); +- assertNotSuggested('X._d'); +- // Suggested by LocalLibraryContributor +- assertNotSuggested('B'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_PrefixedIdentifier_class_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block +- addSource('/testB.dart', ''' +- lib B; +- class I { +- static const scI = 'boo'; +- X get f => new A(); +- get _g => new A();} +- class B implements I { +- static const int scB = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- addTestSource(''' +- import "/testB.dart"; +- class A extends B { +- static const String scA = 'foo'; +- w() { }} +- main() {A.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by StaticMemberContributor +- assertNotSuggested('scA'); +- assertNotSuggested('scB'); +- assertNotSuggested('scI'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('w'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_imported() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- static const int sc = 12; +- @deprecated var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- addTestSource(''' +- import "/testB.dart"; +- main() {A a; a.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_local() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +- main() {A a; a.^} +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- static const int sc = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_library() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "/testB.dart" as b; +- var T2; +- class A { } +- main() {b.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "/testB.dart" as b; +- var T2; +- class A { } +- foo(b.^ f) {}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "/testB.dart" as b; +- var T2; +- class A { } +- foo(b.^) {}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_parameter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- class _W {M y; var _z;} +- class X extends _W {} +- class M{}'''); +- addTestSource(''' +- import "/testB.dart"; +- foo(X x) {x.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('y'); +- assertNotSuggested('_z'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_prefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testA.dart', ''' +- class A {static int bar = 10;} +- _B() {}'''); +- addTestSource(''' +- import "/testA.dart"; +- class X {foo(){A^.bar}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestClass('A'); +- assertNotSuggested('X'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('_B'); +- } +- +- test_PrefixedIdentifier_propertyAccess() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('compareTo'); +- } +- +- test_PrefixedIdentifier_propertyAccess_newStmt() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^ int y = 0;}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('compareTo'); +- } +- +- test_PrefixedIdentifier_trailingStmt_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('const String g = "hello"; f() {g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_field() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g; f() {g.^ int y = 0;}}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_function() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g() => "one"; f() {g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('typedef String g(); f() {g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_typed() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {String g; g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_untyped() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {var g = "hello"; g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_method() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {f(String g) {g.^ int y = 0;}}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param2() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f(String g) {g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_topLevelVar() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g; f() {g.^ int y = 0;}'); +- +- await computeSuggestions(); +- assertNotSuggested('length'); +- } +- +- test_PropertyAccess_expression() async { +- // SimpleIdentifier MethodInvocation PropertyAccess ExpressionStatement +- addTestSource('class A {a() {"hello".to^String().length}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 8); +- assertNotSuggested('length'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PropertyAccess_noTarget() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){.^}}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_noTarget2() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('main() {.^}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_selector() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement Block +- addTestSource('class A {a() {"hello".length.^}}'); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEven'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_SwitchStatement_c() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {c^}}}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_SwitchStatement_case() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}'); +- +- await computeSuggestions(); +- assertNotSuggested('A'); +- assertNotSuggested('g'); +- assertNotSuggested('t'); +- assertSuggestClass('String'); +- } +- +- test_SwitchStatement_empty() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {^}}}'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ThisExpression_block() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A() {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {this.^ m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A() {this.^} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.^) {} +- A.z() {} +- var b; X _c; static sb; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('sb'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param2() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.b^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param3() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.^b) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param4() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.b, this.^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_TopLevelVariableDeclaration_typed_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} B ^'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_TopLevelVariableDeclaration_untyped_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} var ^'); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_TypeArgumentList() async { +- // SimpleIdentifier BinaryExpression ExpressionStatement +- resolveSource('/testA.dart', ''' +- class C1 {int x;} +- F1() => 0; +- typedef String T1(int blat);'''); +- addTestSource(''' +- import "/testA.dart";' +- class C2 {int x;} +- F2() => 0; +- typedef int T2(int blat); +- class C {} +- main() { C<^> c; }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('Object'); +- assertSuggestClass('C1'); +- assertSuggestFunctionTypeAlias('T1', 'String'); +- assertNotSuggested('C2'); +- assertNotSuggested('T2'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- } +- +- test_TypeArgumentList2() async { +- // TypeName TypeArgumentList TypeName +- addSource('/testA.dart', ''' +- class C1 {int x;} +- F1() => 0; +- typedef String T1(int blat);'''); +- addTestSource(''' +- import "/testA.dart";' +- class C2 {int x;} +- F2() => 0; +- typedef int T2(int blat); +- class C {} +- main() { C c; }'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestClass('C1'); +- assertNotSuggested('C2'); +- } +- +- test_TypeArgumentList_recursive() async { +- resolveSource('/testA.dart', ''' +-class A {} +-'''); +- resolveSource('/testB.dart', ''' +-export 'testA.dart'; +-export 'testB.dart'; +-class B {} +-'''); +- addTestSource(''' +-import '/testB.dart'; +-List<^> x; +-'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestClass('B'); +- } +- +- test_VariableDeclaration_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addSource('/testB.dart', ''' +- lib B; +- foo() { } +- class _B { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- class Y {Y.c(); Y._d(); z() {}} +- main() {var ^}'''); +- +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_VariableDeclarationList_final() async { +- // VariableDeclarationList VariableDeclarationStatement Block +- addTestSource('main() {final ^} class C { }'); +- +- await computeSuggestions(); +- assertSuggestClass('Object'); +- assertNotSuggested('C'); +- assertNotSuggested('=='); +- } +- +- test_VariableDeclarationStatement_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +- lib B; +- foo() { } +- class _B { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- class Y {Y.c(); Y._d(); z() {}} +- class C {bar(){var f; {var x;} var e = ^}}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertNotSuggested('_B'); +- assertNotSuggested('Y'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +- +- test_VariableDeclarationStatement_RHS_missing_semicolon() async { +- // VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- resolveSource('/testB.dart', ''' +- lib B; +- foo1() { } +- void bar1() { } +- class _B { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- foo2() { } +- void bar2() { } +- class Y {Y.c(); Y._d(); z() {}} +- class C {bar(){var f; {var x;} var e = ^ var g}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertSuggestFunction('foo1', 'dynamic'); +- assertNotSuggested('bar1'); +- assertNotSuggested('foo2'); +- assertNotSuggested('bar2'); +- assertNotSuggested('_B'); +- assertNotSuggested('Y'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart +deleted file mode 100644 +index bd52c9e09c9..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart ++++ /dev/null +@@ -1,607 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(InheritedReferenceContributorTest); +- }); +-} +- +-@reflectiveTest +-class InheritedReferenceContributorTest extends DartCompletionContributorTest { +- @override +- bool get isNullExpectedReturnTypeConsideredDynamic => false; +- +- @override +- DartCompletionContributor createContributor() { +- return new InheritedReferenceContributor(); +- } +- +- /// Sanity check. Permutations tested in local_ref_contributor. +- test_ArgDefaults_inherited_method_with_required_named() async { +- addMetaPackageSource(); +- resolveSource('/testB.dart', ''' +-import 'package:meta/meta.dart'; +- +-lib libB; +-class A { +- bool foo(int bar, {bool boo, @required int baz}) => false; +-}'''); +- addTestSource(''' +-import "testB.dart"; +-class B extends A { +- b() => f^ +-} +-'''); +- await computeSuggestions(); +- +- assertSuggestMethod('foo', 'A', 'bool', +- defaultArgListString: 'bar, baz: null'); +- } +- +- test_AwaitExpression_inherited() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- resolveSource('/testB.dart', ''' +-lib libB; +-class A { +- Future y() async {return 0;} +-}'''); +- addTestSource(''' +-import "testB.dart"; +-class B extends A { +- Future a() async {return 0;} +- foo() async {await ^} +-} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('foo'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertSuggestMethod('y', 'A', 'dynamic'); +- } +- +- test_Block_inherited_imported() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- resolveSource('/testB.dart', ''' +- lib B; +- class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; } +- class E extends F { var e1; e2() { } } +- class I { int i1; i2() { } } +- class M { var m1; int m2() { } }'''); +- addTestSource(''' +- import "testB.dart"; +- class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('e1', null); +- assertSuggestField('f1', null); +- assertSuggestField('i1', 'int'); +- assertSuggestField('m1', null); +- assertSuggestGetter('f3', null); +- assertSuggestSetter('f4'); +- assertSuggestMethod('e2', 'E', null); +- assertSuggestMethod('f2', 'F', null); +- assertSuggestMethod('i2', 'I', null); +- assertSuggestMethod('m2', 'M', 'int'); +- assertNotSuggested('=='); +- } +- +- test_Block_inherited_local() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addTestSource(''' +-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } } +-class E extends F { var e1; e2() { } } +-class I { int i1; i2() { } } +-class M { var m1; int m2() { } } +-class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('e1', null); +- assertSuggestField('f1', null); +- assertSuggestField('i1', 'int'); +- assertSuggestField('m1', null); +- assertSuggestGetter('f3', null); +- assertSuggestSetter('f4'); +- assertSuggestMethod('e2', 'E', null); +- assertSuggestMethod('f2', 'F', null); +- assertSuggestMethod('i2', 'I', null); +- assertSuggestMethod('m2', 'M', 'int'); +- } +- +- test_inherited() async { +- resolveSource('/testB.dart', ''' +-lib libB; +-class A2 { +- int x; +- int y() {return 0;} +- int x2; +- int y2() {return 0;} +-}'''); +- addTestSource(''' +-import "testB.dart"; +-class A1 { +- int x; +- int y() {return 0;} +- int x1; +- int y1() {return 0;} +-} +-class B extends A1 with A2 { +- int a; +- int b() {return 0;} +- foo() {^} +-} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('B'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('foo'); +- assertNotSuggested('A'); +- assertSuggestField('x', 'int'); +- assertSuggestMethod('y', 'A1', 'int'); +- assertSuggestField('x1', 'int'); +- assertSuggestMethod('y1', 'A1', 'int'); +- assertSuggestField('x2', 'int'); +- assertSuggestMethod('y2', 'A2', 'int'); +- } +- +- test_method_in_class() async { +- addTestSource(''' +-class A { +- void m(x, int y) {} +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_mixed_required_and_named() async { +- resolveSource('/libA.dart', ''' +-class A { +- void m(x, {int y}) {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_mixed_required_and_named_local() async { +- addTestSource(''' +-class A { +- void m(x, {int y}) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_mixed_required_and_positional() async { +- resolveSource('/libA.dart', ''' +-class A { +- void m(x, [int y]) {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_mixed_required_and_positional_local() async { +- addTestSource(''' +-class A { +- void m(x, [int y]) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_named() async { +- resolveSource('/libA.dart', ''' +-class A { +- void m({x, int y}) {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_named_local() async { +- addTestSource(''' +-class A { +- void m({x, int y}) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_none() async { +- resolveSource('/libA.dart', ''' +-class A { +- void m() {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, isEmpty); +- expect(suggestion.parameterTypes, isEmpty); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_none_local() async { +- addTestSource(''' +-class A { +- void m() {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, isEmpty); +- expect(suggestion.parameterTypes, isEmpty); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_positional() async { +- resolveSource('/libA.dart', ''' +-class A { +- void m([x, int y]) {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_positional_local() async { +- addTestSource(''' +-class A { +- void m([x, int y]) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_required() async { +- resolveSource('/libA.dart', ''' +-class A { +- void m(x, int y) {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 2); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_mixin_ordering() async { +- resolveSource('/libA.dart', ''' +-class B {} +-class M1 { +- void m() {} +-} +-class M2 { +- void m() {} +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class C extends B with M1, M2 { +- void f() { +- ^ +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestMethod('m', 'M1', 'void'); +- } +- +- test_no_parameters_field() async { +- resolveSource('/libA.dart', ''' +-class A { +- int x; +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestField('x', 'int'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_no_parameters_getter() async { +- resolveSource('/libA.dart', ''' +-class A { +- int get x => null; +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestGetter('x', 'int'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_no_parameters_setter() async { +- resolveSource('/libA.dart', ''' +-class A { +- set x(int value) {}; +-} +-'''); +- addTestSource(''' +-import 'libA.dart'; +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestSetter('x'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_outside_class() async { +- resolveSource('/testB.dart', ''' +-lib libB; +-class A2 { +- int x; +- int y() {return 0;} +- int x2; +- int y2() {return 0;} +-}'''); +- addTestSource(''' +-import "testB.dart"; +-class A1 { +- int x; +- int y() {return 0;} +- int x1; +- int y1() {return 0;} +-} +-class B extends A1 with A2 { +- int a; +- int b() {return 0;} +-} +-foo() {^} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('B'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('foo'); +- assertNotSuggested('A'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('x1'); +- assertNotSuggested('y1'); +- assertNotSuggested('x2'); +- assertNotSuggested('y2'); +- } +- +- test_static_field() async { +- resolveSource('/testB.dart', ''' +-lib libB; +-class A2 { +- int x; +- int y() {return 0;} +- int x2; +- int y2() {return 0;} +-}'''); +- addTestSource(''' +-import "testB.dart"; +-class A1 { +- int x; +- int y() {return 0;} +- int x1; +- int y1() {return 0;} +-} +-class B extends A1 with A2 { +- int a; +- int b() {return 0;} +- static foo = ^ +-} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('B'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('foo'); +- assertNotSuggested('A'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('x1'); +- assertNotSuggested('y1'); +- assertNotSuggested('x2'); +- assertNotSuggested('y2'); +- } +- +- test_static_method() async { +- resolveSource('/testB.dart', ''' +-lib libB; +-class A2 { +- int x; +- int y() {return 0;} +- int x2; +- int y2() {return 0;} +-}'''); +- addTestSource(''' +-import "testB.dart"; +-class A1 { +- int x; +- int y() {return 0;} +- int x1; +- int y1() {return 0;} +-} +-class B extends A1 with A2 { +- int a; +- int b() {return 0;} +- static foo() {^} +-} +-'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('B'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('foo'); +- assertNotSuggested('A'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('x1'); +- assertNotSuggested('y1'); +- assertNotSuggested('x2'); +- assertNotSuggested('y2'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart +deleted file mode 100644 +index 3bac1adfdc1..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart ++++ /dev/null +@@ -1,1826 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(KeywordContributorTest); +- }); +-} +- +-@reflectiveTest +-class KeywordContributorTest extends DartCompletionContributorTest { +- static const List CLASS_BODY_KEYWORDS = const [ +- Keyword.CONST, +- Keyword.DYNAMIC, +- Keyword.FACTORY, +- Keyword.FINAL, +- Keyword.GET, +- Keyword.OPERATOR, +- Keyword.SET, +- Keyword.STATIC, +- Keyword.VAR, +- Keyword.VOID +- ]; +- +- static const List DECLARATION_KEYWORDS = const [ +- Keyword.ABSTRACT, +- Keyword.CLASS, +- Keyword.CONST, +- Keyword.DYNAMIC, +- Keyword.FINAL, +- Keyword.TYPEDEF, +- Keyword.VAR, +- Keyword.VOID +- ]; +- +- static const List DIRECTIVE_AND_DECLARATION_KEYWORDS = const [ +- Keyword.ABSTRACT, +- Keyword.CLASS, +- Keyword.CONST, +- Keyword.DYNAMIC, +- Keyword.EXPORT, +- Keyword.FINAL, +- Keyword.IMPORT, +- Keyword.PART, +- Keyword.TYPEDEF, +- Keyword.VAR, +- Keyword.VOID +- ]; +- +- static const List DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS = +- const [ +- Keyword.ABSTRACT, +- Keyword.CLASS, +- Keyword.CONST, +- Keyword.DYNAMIC, +- Keyword.EXPORT, +- Keyword.FINAL, +- Keyword.IMPORT, +- Keyword.LIBRARY, +- Keyword.PART, +- Keyword.TYPEDEF, +- Keyword.VAR, +- Keyword.VOID +- ]; +- +- static const List NO_PSEUDO_KEYWORDS = const []; +- +- static const List STMT_START_IN_CLASS = const [ +- Keyword.ASSERT, +- Keyword.CONST, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SUPER, +- Keyword.SWITCH, +- Keyword.THIS, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]; +- +- static const List STMT_START_IN_LOOP_IN_CLASS = const [ +- Keyword.ASSERT, +- Keyword.BREAK, +- Keyword.CONST, +- Keyword.CONTINUE, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SUPER, +- Keyword.SWITCH, +- Keyword.THIS, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]; +- +- static const List STMT_START_IN_SWITCH_IN_CLASS = const [ +- Keyword.ASSERT, +- Keyword.BREAK, +- Keyword.CASE, +- Keyword.CONST, +- Keyword.DEFAULT, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SUPER, +- Keyword.SWITCH, +- Keyword.THIS, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]; +- +- static const List STMT_START_IN_SWITCH_OUTSIDE_CLASS = const [ +- Keyword.ASSERT, +- Keyword.BREAK, +- Keyword.CASE, +- Keyword.CONST, +- Keyword.DEFAULT, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SWITCH, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]; +- +- static const List STMT_START_OUTSIDE_CLASS = const [ +- Keyword.ASSERT, +- Keyword.CONST, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SWITCH, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]; +- +- static const List STMT_START_IN_LOOP_OUTSIDE_CLASS = const [ +- Keyword.ASSERT, +- Keyword.BREAK, +- Keyword.CONST, +- Keyword.CONTINUE, +- Keyword.DO, +- Keyword.FINAL, +- Keyword.FOR, +- Keyword.IF, +- Keyword.NEW, +- Keyword.RETURN, +- Keyword.SWITCH, +- Keyword.THROW, +- Keyword.TRY, +- Keyword.VAR, +- Keyword.VOID, +- Keyword.WHILE +- ]; +- +- static const List EXPRESSION_START_INSTANCE = const [ +- Keyword.CONST, +- Keyword.FALSE, +- Keyword.NEW, +- Keyword.NULL, +- Keyword.SUPER, +- Keyword.THIS, +- Keyword.TRUE, +- ]; +- +- static const List EXPRESSION_START_NO_INSTANCE = const [ +- Keyword.CONST, +- Keyword.FALSE, +- Keyword.NEW, +- Keyword.NULL, +- Keyword.TRUE, +- ]; +- +- void assertSuggestKeywords(Iterable expectedKeywords, +- {List pseudoKeywords: NO_PSEUDO_KEYWORDS, +- int relevance: DART_RELEVANCE_KEYWORD}) { +- Set expectedCompletions = new Set(); +- Map expectedOffsets = {}; +- Set actualCompletions = new Set(); +- expectedCompletions.addAll(expectedKeywords.map((k) => k.lexeme)); +- ['import', 'export', 'part'].forEach((s) { +- if (expectedCompletions.contains(s)) { +- expectedCompletions.remove(s); +- expectedCompletions.add('$s \'\';'); +- } +- }); +- +- expectedCompletions.addAll(pseudoKeywords); +- for (CompletionSuggestion s in suggestions) { +- if (s.kind == CompletionSuggestionKind.KEYWORD) { +- Keyword k = Keyword.keywords[s.completion]; +- if (k == null && !expectedCompletions.contains(s.completion)) { +- fail('Invalid keyword suggested: ${s.completion}'); +- } else { +- if (!actualCompletions.add(s.completion)) { +- fail('Duplicate keyword suggested: ${s.completion}'); +- } +- } +- } +- } +- if (!_equalSets(expectedCompletions, actualCompletions)) { +- StringBuffer msg = new StringBuffer(); +- msg.writeln('Expected:'); +- _appendCompletions(msg, expectedCompletions, actualCompletions); +- msg.writeln('but found:'); +- _appendCompletions(msg, actualCompletions, expectedCompletions); +- fail(msg.toString()); +- } +- for (CompletionSuggestion s in suggestions) { +- if (s.kind == CompletionSuggestionKind.KEYWORD) { +- if (s.completion.startsWith(Keyword.IMPORT.lexeme)) { +- int importRelevance = relevance; +- expect(s.relevance, equals(importRelevance), reason: s.completion); +- } else { +- if (s.completion == Keyword.RETHROW.lexeme) { +- expect(s.relevance, equals(relevance - 1), reason: s.completion); +- } else { +- expect(s.relevance, equals(relevance), reason: s.completion); +- } +- } +- int expectedOffset = expectedOffsets[s.completion]; +- if (expectedOffset == null) { +- expectedOffset = s.completion.length; +- } +- expect( +- s.selectionOffset, +- equals(s.completion.endsWith('\'\';') +- ? expectedOffset - 2 +- : expectedOffset)); +- expect(s.selectionLength, equals(0)); +- expect(s.isDeprecated, equals(false)); +- expect(s.isPotential, equals(false)); +- } +- } +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new KeywordContributor(); +- } +- +- fail_import_partial() async { +- addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";'); +- await computeSuggestions(); +- // TODO(danrubel) should not suggest declaration keywords +- assertNotSuggested('class'); +- } +- +- fail_import_partial4() async { +- addTestSource('^ imp import "package:foo/foo.dart";'); +- await computeSuggestions(); +- // TODO(danrubel) should not suggest declaration keywords +- assertNotSuggested('class'); +- } +- +- fail_import_partial5() async { +- addTestSource('library libA; imp^ import "package:foo/foo.dart";'); +- await computeSuggestions(); +- // TODO(danrubel) should not suggest declaration keywords +- assertNotSuggested('class'); +- } +- +- fail_import_partial6() async { +- addTestSource( +- 'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";'); +- await computeSuggestions(); +- // TODO(danrubel) should not suggest declaration keywords +- assertNotSuggested('class'); +- } +- +- test_after_class() async { +- addTestSource('class A {} ^'); +- await computeSuggestions(); +- assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH); +- } +- +- test_after_class2() async { +- addTestSource('class A {} c^'); +- await computeSuggestions(); +- assertSuggestKeywords(DECLARATION_KEYWORDS, relevance: DART_RELEVANCE_HIGH); +- } +- +- test_after_import() async { +- addTestSource('import "foo"; ^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_after_import2() async { +- addTestSource('import "foo"; c^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_anonymous_function_async() async { +- addTestSource('main() {foo(() ^ {}}}'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_anonymous_function_async2() async { +- addTestSource('main() {foo(() a^ {}}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_anonymous_function_async3() async { +- addTestSource('main() {foo(() async ^ {}}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_anonymous_function_async4() async { +- addTestSource('main() {foo(() ^ => 2}}'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_anonymous_function_async5() async { +- addTestSource('main() {foo(() ^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_anonymous_function_async6() async { +- addTestSource('main() {foo("bar", () as^{}}'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_anonymous_function_async7() async { +- addTestSource('main() {foo("bar", () as^ => null'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_argument() async { +- addTestSource('main() {foo(^);}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_argument2() async { +- addTestSource('main() {foo(n^);}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_argument_literal() async { +- addTestSource('main() {foo("^");}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_argument_named() async { +- addTestSource('main() {foo(bar: ^);}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_argument_named2() async { +- addTestSource('main() {foo(bar: n^);}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_argument_named_literal() async { +- addTestSource('main() {foo(bar: "^");}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_assignment_field() async { +- addTestSource('class A {var foo = ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_assignment_field2() async { +- addTestSource('class A {var foo = n^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_assignment_local() async { +- addTestSource('main() {var foo = ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_assignment_local2() async { +- addTestSource('main() {var foo = n^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_assignment_local2_async() async { +- addTestSource('main() async {var foo = n^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE, +- pseudoKeywords: ['await']); +- } +- +- test_assignment_local_async() async { +- addTestSource('main() async {var foo = ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE, +- pseudoKeywords: ['await']); +- } +- +- test_before_import() async { +- addTestSource('^ import foo;'); +- await computeSuggestions(); +- assertSuggestKeywords( +- [Keyword.EXPORT, Keyword.IMPORT, Keyword.LIBRARY, Keyword.PART], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_catch_1a() async { +- // '}' Block BlockFunctionBody FunctionExpression +- addTestSource('main() {try {} ^}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_1b() async { +- // [ExpressionStatement 'c'] Block BlockFunctionBody FunctionExpression +- addTestSource('main() {try {} c^}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_1c() async { +- // [EmptyStatement] Block BlockFunction FunctionExpression +- addTestSource('main() {try {} ^;}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_1d() async { +- // [EmptyStatement] Block BlockFunction FunctionExpression +- addTestSource('main() {try {} ^ Foo foo;}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_2a() async { +- // '}' Block BlockFunctionBody FunctionExpression +- addTestSource('main() {try {} on SomeException {} ^}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_2b() async { +- // [ExpressionStatement 'c'] Block BlockFunctionBody FunctionExpression +- addTestSource('main() {try {} on SomeException {} c^}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_2c() async { +- // [EmptyStatement] Block BlockFunction FunctionExpression +- addTestSource('main() {try {} on SomeException {} ^;}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_2d() async { +- // [EmptyStatement] Block BlockFunction FunctionExpression +- addTestSource('main() {try {} on SomeException {} ^ Foo foo;}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_3a() async { +- // '}' Block BlockFunctionBody FunctionExpression +- addTestSource('main() {try {} catch (e) {} ^}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_3b() async { +- // [ExpressionStatement 'c'] Block BlockFunctionBody FunctionExpression +- addTestSource('main() {try {} catch (e) {} c^}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_3c() async { +- // [EmptyStatement] Block BlockFunction FunctionExpression +- addTestSource('main() {try {} catch (e) {} ^;}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_3d() async { +- // [EmptyStatement] Block BlockFunction FunctionExpression +- addTestSource('main() {try {} catch (e) {} ^ Foo foo;}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- keywords.add(Keyword.FINALLY); +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_4a1() async { +- // [CatchClause] TryStatement Block +- addTestSource('main() {try {} ^ on SomeException {}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_4a2() async { +- // ['c' VariableDeclarationStatement] Block BlockFunctionBody +- addTestSource('main() {try {} c^ on SomeException {}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- // TODO(danrubel) finally should not be suggested here +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_4b1() async { +- // [CatchClause] TryStatement Block +- addTestSource('main() {try {} ^ catch (e) {}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_4b2() async { +- // ['c' ExpressionStatement] Block BlockFunctionBody +- addTestSource('main() {try {} c^ catch (e) {}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- // TODO(danrubel) finally should not be suggested here +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_4c1() async { +- // ['finally'] TryStatement Block +- addTestSource('main() {try {} ^ finally {}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_4c2() async { +- // ['c' ExpressionStatement] Block BlockFunctionBody +- addTestSource('main() {try {} c^ finally {}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.add(Keyword.CATCH); +- // TODO(danrubel) finally should not be suggested here +- keywords.add(Keyword.FINALLY); +- assertSuggestKeywords(keywords, pseudoKeywords: ['on']); +- } +- +- test_catch_block() async { +- // '}' Block CatchClause TryStatement Block +- addTestSource('main() {try {} catch (e) {^}}}'); +- await computeSuggestions(); +- var keywords = []; +- keywords.addAll(STMT_START_OUTSIDE_CLASS); +- keywords.add(Keyword.RETHROW); +- assertSuggestKeywords(keywords); +- } +- +- test_class() async { +- addTestSource('class A e^ { }'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_body() async { +- addTestSource('class A {^}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS); +- } +- +- test_class_body_beginning() async { +- addTestSource('class A {^ var foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS); +- } +- +- test_class_body_between() async { +- addTestSource('class A {var bar; ^ var foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS); +- } +- +- test_class_body_end() async { +- addTestSource('class A {var foo; ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS); +- } +- +- test_class_extends() async { +- addTestSource('class A extends foo ^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_extends2() async { +- addTestSource('class A extends foo i^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_extends3() async { +- addTestSource('class A extends foo i^ { }'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IMPLEMENTS, Keyword.WITH], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_extends_name() async { +- addTestSource('class A extends ^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_class_implements() async { +- addTestSource('class A ^ implements foo'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.EXTENDS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_implements2() async { +- addTestSource('class A e^ implements foo'); +- await computeSuggestions(); +- // TODO (danrubel) refinement: don't suggest implements +- assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_implements3() async { +- addTestSource('class A e^ implements foo { }'); +- await computeSuggestions(); +- // TODO (danrubel) refinement: don't suggest implements +- assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_implements_name() async { +- addTestSource('class A implements ^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_class_member_const_afterStatic() async { +- addTestSource(''' +-class C { +- static c^ +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.CONST, Keyword.FINAL]); +- } +- +- test_class_member_final_afterStatic() async { +- addTestSource(''' +-class C { +- static f^ +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.CONST, Keyword.FINAL]); +- } +- +- test_class_name() async { +- addTestSource('class ^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_class_noBody() async { +- addTestSource('class A ^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_noBody2() async { +- addTestSource('class A e^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_noBody3() async { +- addTestSource('class A e^ String foo;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.EXTENDS, Keyword.IMPLEMENTS], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_with() async { +- addTestSource('class A extends foo with bar ^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_with2() async { +- addTestSource('class A extends foo with bar i^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_with3() async { +- addTestSource('class A extends foo with bar i^ { }'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IMPLEMENTS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_class_with_name() async { +- addTestSource('class A extends foo with ^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_constructor_param() async { +- addTestSource('class A { A(^) {});}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.COVARIANT, Keyword.THIS]); +- } +- +- test_constructor_param2() async { +- addTestSource('class A { A(t^) {});}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.COVARIANT, Keyword.THIS]); +- } +- +- test_do_break_continue() async { +- addTestSource('main() {do {^} while (true);}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_do_break_continue2() async { +- addTestSource('class A {foo() {do {^} while (true);}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_empty() async { +- addTestSource('^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_for_break_continue() async { +- addTestSource('main() {for (int x in myList) {^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_for_break_continue2() async { +- addTestSource('class A {foo() {for (int x in myList) {^}}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_for_expression_in() async { +- addTestSource('main() {for (int x i^)}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_for_expression_in2() async { +- addTestSource('main() {for (int x in^)}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_for_expression_in_inInitializer() async { +- addTestSource('main() {for (int i^)}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_for_expression_init() async { +- addTestSource('main() {for (int x = i^)}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_for_expression_init2() async { +- addTestSource('main() {for (int x = in^)}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_for_initialization_var() async { +- addTestSource('main() {for (^)}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.VAR], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_function_async() async { +- addTestSource('main()^'); +- await computeSuggestions(); +- assertSuggestKeywords(DECLARATION_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_function_async2() async { +- addTestSource('main()^{}'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_function_async3() async { +- addTestSource('main()a^'); +- await computeSuggestions(); +- assertSuggestKeywords(DECLARATION_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_function_async4() async { +- addTestSource('main()a^{}'); +- await computeSuggestions(); +- assertSuggestKeywords(DECLARATION_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_function_async5() async { +- addTestSource('main()a^ Foo foo;'); +- await computeSuggestions(); +- assertSuggestKeywords(DECLARATION_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_function_body_inClass_constructorInitializer() async { +- addTestSource(r''' +-foo(p) {} +-class A { +- final f; +- A() : f = foo(() {^}); +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_function_body_inClass_constructorInitializer_async() async { +- addTestSource(r''' +-foo(p) {} +-class A { +- final f; +- A() : f = foo(() async {^}); +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']); +- } +- +- test_function_body_inClass_constructorInitializer_async_star() async { +- addTestSource(r''' +- foo(p) {} +- class A { +- final f; +- A() : f = foo(() async* {^}); +- } +- '''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_function_body_inClass_field() async { +- addTestSource(r''' +-class A { +- var f = () {^}; +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_function_body_inClass_methodBody() async { +- addTestSource(r''' +-class A { +- m() { +- f() {^}; +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_function_body_inClass_methodBody_inFunction() async { +- addTestSource(r''' +-class A { +- m() { +- f() { +- f2() {^}; +- }; +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_function_body_inClass_methodBody_inFunction_async() async { +- addTestSource(r''' +-class A { +- m() { +- f() { +- f2() async {^}; +- }; +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']); +- } +- +- test_function_body_inClass_methodBody_inFunction_async_star() async { +- addTestSource(r''' +- class A { +- m() { +- f() { +- f2() async* {^}; +- }; +- } +- } +- '''); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_function_body_inUnit() async { +- addTestSource('main() {^}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_function_body_inUnit_afterBlock() async { +- addTestSource('main() {{}^}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_function_body_inUnit_async() async { +- addTestSource('main() async {^}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']); +- } +- +- test_function_body_inUnit_async_star() async { +- addTestSource('main() async* {n^}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_function_body_inUnit_async_star2() async { +- addTestSource('main() async* {n^ foo}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_function_body_inUnit_sync_star() async { +- addTestSource('main() sync* {n^}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_function_body_inUnit_sync_star2() async { +- addTestSource('main() sync* {n^ foo}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_if_after_else() async { +- addTestSource('main() { if (true) {} else ^ }'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_if_afterThen_nextCloseCurlyBrace0() async { +- addTestSource('main() { if (true) {} ^ }'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS.toList()..add(Keyword.ELSE), +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_if_afterThen_nextCloseCurlyBrace1() async { +- addTestSource('main() { if (true) {} e^ }'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS.toList()..add(Keyword.ELSE), +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_if_afterThen_nextStatement0() async { +- addTestSource('main() { if (true) {} ^ print(0); }'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS.toList()..add(Keyword.ELSE), +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_if_condition_isKeyword() async { +- addTestSource('main() { if (v i^) {} }'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_if_condition_isKeyword2() async { +- addTestSource('main() { if (v i^ && false) {} }'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_if_expression_in_class() async { +- addTestSource('class A {foo() {if (^) }}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_if_expression_in_class2() async { +- addTestSource('class A {foo() {if (n^) }}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_if_expression_in_function() async { +- addTestSource('foo() {if (^) }'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_if_expression_in_function2() async { +- addTestSource('foo() {if (n^) }'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_if_in_class() async { +- addTestSource('class A {foo() {if (true) ^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_if_in_class2() async { +- addTestSource('class A {foo() {if (true) ^;}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_if_in_class3() async { +- addTestSource('class A {foo() {if (true) r^;}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_if_in_class4() async { +- addTestSource('class A {foo() {if (true) ^ go();}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_if_outside_class() async { +- addTestSource('foo() {if (true) ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_if_outside_class2() async { +- addTestSource('foo() {if (true) ^;}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_if_outside_class3() async { +- addTestSource('foo() {if (true) r^;}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_if_outside_class4() async { +- addTestSource('foo() {if (true) ^ go();}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_OUTSIDE_CLASS); +- } +- +- test_import() async { +- addTestSource('import "foo" deferred as foo ^;'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['show', 'hide'], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_as() async { +- addTestSource('import "foo" deferred ^;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_as2() async { +- addTestSource('import "foo" deferred a^;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_as3() async { +- addTestSource('import "foo" deferred a^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred() async { +- addTestSource('import "foo" ^ as foo;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred2() async { +- addTestSource('import "foo" d^ as foo;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred3() async { +- addTestSource('import "foo" d^ show foo;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as'], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred4() async { +- addTestSource('import "foo" d^ hide foo;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as'], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred5() async { +- addTestSource('import "foo" d^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred6() async { +- addTestSource('import "foo" d^ import'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_as() async { +- addTestSource('import "foo" ^;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_as2() async { +- addTestSource('import "foo" d^;'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_as3() async { +- addTestSource('import "foo" ^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_as4() async { +- addTestSource('import "foo" d^'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_as5() async { +- addTestSource('import "foo" sh^ import "bar"; import "baz";'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.AS], +- pseudoKeywords: ['deferred as', 'show', 'hide'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_not() async { +- addTestSource('import "foo" as foo ^;'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['show', 'hide'], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_deferred_partial() async { +- addTestSource('import "package:foo/foo.dart" def^ as foo;'); +- await computeSuggestions(); +- expect(replacementOffset, 30); +- expect(replacementLength, 3); +- assertSuggestKeywords([Keyword.DEFERRED], relevance: DART_RELEVANCE_HIGH); +- expect(suggestions[0].selectionOffset, 8); +- expect(suggestions[0].selectionLength, 0); +- } +- +- test_import_incomplete() async { +- addTestSource('import "^"'); +- await computeSuggestions(); +- expect(suggestions, isEmpty); +- } +- +- test_import_partial() async { +- addTestSource('imp^ import "package:foo/foo.dart"; import "bar.dart";'); +- await computeSuggestions(); +- expect(replacementOffset, 0); +- expect(replacementLength, 3); +- // TODO(danrubel) should not suggest declaration keywords +- assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_partial2() async { +- addTestSource('^imp import "package:foo/foo.dart";'); +- await computeSuggestions(); +- expect(replacementOffset, 0); +- expect(replacementLength, 3); +- // TODO(danrubel) should not suggest declaration keywords +- assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_partial3() async { +- addTestSource(' ^imp import "package:foo/foo.dart"; import "bar.dart";'); +- await computeSuggestions(); +- expect(replacementOffset, 1); +- expect(replacementLength, 3); +- // TODO(danrubel) should not suggest declaration keywords +- assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_partial4() async { +- addTestSource('^ imp import "package:foo/foo.dart";'); +- await computeSuggestions(); +- expect(replacementOffset, 0); +- expect(replacementLength, 0); +- // TODO(danrubel) should not suggest declaration keywords +- assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_partial5() async { +- addTestSource('library libA; imp^ import "package:foo/foo.dart";'); +- await computeSuggestions(); +- expect(replacementOffset, 14); +- expect(replacementLength, 3); +- // TODO(danrubel) should not suggest declaration keywords +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_import_partial6() async { +- addTestSource( +- 'library bar; import "zoo.dart"; imp^ import "package:foo/foo.dart";'); +- await computeSuggestions(); +- expect(replacementOffset, 32); +- expect(replacementLength, 3); +- // TODO(danrubel) should not suggest declaration keywords +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_is_expression() async { +- addTestSource('main() {if (x is^)}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_is_expression_partial() async { +- addTestSource('main() {if (x i^)}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_library() async { +- addTestSource('library foo;^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_library_declaration() async { +- addTestSource('library ^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_library_declaration2() async { +- addTestSource('library a^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_library_declaration3() async { +- addTestSource('library a.^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_library_name() async { +- addTestSource('library ^'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_method_async() async { +- addTestSource('class A { foo() ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_method_async2() async { +- addTestSource('class A { foo() ^{}}'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async', 'async*', 'sync*'], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_method_async3() async { +- addTestSource('class A { foo() a^}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_method_async4() async { +- addTestSource('class A { foo() a^{}}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_method_async5() async { +- addTestSource('class A { foo() ^ Foo foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_method_async6() async { +- addTestSource('class A { foo() a^ Foo foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_method_async7() async { +- addTestSource('class A { foo() ^ => Foo foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords([], +- pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH); +- } +- +- test_method_async8() async { +- addTestSource('class A { foo() a^ Foo foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(CLASS_BODY_KEYWORDS, +- pseudoKeywords: ['async', 'async*', 'sync*']); +- } +- +- test_method_body() async { +- addTestSource('class A { foo() {^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS); +- } +- +- test_method_body2() async { +- addTestSource('class A { foo() => ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_method_body3() async { +- addTestSource('class A { foo() => ^ Foo foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_method_body4() async { +- addTestSource('class A { foo() => ^;}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_method_body_async() async { +- addTestSource('class A { foo() async {^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']); +- } +- +- test_method_body_async2() async { +- addTestSource('class A { foo() async => ^}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']); +- } +- +- test_method_body_async3() async { +- addTestSource('class A { foo() async => ^ Foo foo;}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']); +- } +- +- test_method_body_async4() async { +- addTestSource('class A { foo() async => ^;}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE, pseudoKeywords: ['await']); +- } +- +- test_method_body_async_star() async { +- addTestSource('class A { foo() async* {^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_CLASS, +- pseudoKeywords: ['await', 'yield', 'yield*']); +- } +- +- test_method_body_expression1() async { +- addTestSource('class A { foo() {return b == true ? ^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_method_body_expression2() async { +- addTestSource('class A { foo() {return b == true ? 1 : ^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_method_body_return() async { +- addTestSource('class A { foo() {return ^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_INSTANCE); +- } +- +- test_method_invocation() async { +- addTestSource('class A { foo() {bar.^}}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_method_invocation2() async { +- addTestSource('class A { foo() {bar.as^}}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_method_param() async { +- addTestSource('class A { foo(^) {});}'); +- await computeSuggestions(); +- expect(suggestions, isNotEmpty); +- assertSuggestKeywords([Keyword.COVARIANT]); +- } +- +- test_method_param2() async { +- addTestSource('class A { foo(t^) {});}'); +- await computeSuggestions(); +- expect(suggestions, isNotEmpty); +- assertSuggestKeywords([Keyword.COVARIANT]); +- } +- +- test_method_param_named_init() async { +- addTestSource('class A { foo({bool bar: ^}) {}}'); +- await computeSuggestions(); +- expect(suggestions, isNotEmpty); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_method_param_named_init2() async { +- addTestSource('class A { foo({bool bar: f^}) {}}'); +- await computeSuggestions(); +- expect(suggestions, isNotEmpty); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_method_param_positional_init() async { +- addTestSource('class A { foo([bool bar = ^]) {}}'); +- await computeSuggestions(); +- expect(suggestions, isNotEmpty); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_method_param_positional_init2() async { +- addTestSource('class A { foo([bool bar = f^]) {}}'); +- await computeSuggestions(); +- expect(suggestions, isNotEmpty); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_named_constructor_invocation() async { +- addTestSource('void main() {new Future.^}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_newInstance() async { +- addTestSource('class A { foo() {new ^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_newInstance2() async { +- addTestSource('class A { foo() {new ^ print("foo");}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_newInstance_prefixed() async { +- addTestSource('class A { foo() {new A.^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_newInstance_prefixed2() async { +- addTestSource('class A { foo() {new A.^ print("foo");}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_part_of() async { +- addTestSource('part of foo;^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_partial_class() async { +- addTestSource('cl^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_DECLARATION_AND_LIBRARY_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_partial_class2() async { +- addTestSource('library a; cl^'); +- await computeSuggestions(); +- assertSuggestKeywords(DIRECTIVE_AND_DECLARATION_KEYWORDS, +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_prefixed_field() async { +- addTestSource('class A { int x; foo() {x.^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_prefixed_field2() async { +- addTestSource('class A { int x; foo() {x.^ print("foo");}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_prefixed_library() async { +- addTestSource('import "b" as b; class A { foo() {b.^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_prefixed_local() async { +- addTestSource('class A { foo() {int x; x.^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_prefixed_local2() async { +- addTestSource('class A { foo() {int x; x.^ print("foo");}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_property_access() async { +- addTestSource('class A { get x => 7; foo() {new A().^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([]); +- } +- +- test_switch_expression() async { +- addTestSource('main() {switch(^) {}}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_switch_expression2() async { +- addTestSource('main() {switch(n^) {}}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_switch_expression3() async { +- addTestSource('main() {switch(n^)}'); +- await computeSuggestions(); +- assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE); +- } +- +- test_switch_start() async { +- addTestSource('main() {switch(1) {^}}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_start2() async { +- addTestSource('main() {switch(1) {^ case 1:}}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_start3() async { +- addTestSource('main() {switch(1) {^default:}}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_start4() async { +- addTestSource('main() {switch(1) {^ default:}}'); +- await computeSuggestions(); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_start5() async { +- addTestSource('main() {switch(1) {c^ default:}}'); +- await computeSuggestions(); +- expect(replacementOffset, 19); +- expect(replacementLength, 1); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_start6() async { +- addTestSource('main() {switch(1) {c^}}'); +- await computeSuggestions(); +- expect(replacementOffset, 19); +- expect(replacementLength, 1); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_start7() async { +- addTestSource('main() {switch(1) { c^ }}'); +- await computeSuggestions(); +- expect(replacementOffset, 20); +- expect(replacementLength, 1); +- assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT], +- relevance: DART_RELEVANCE_HIGH); +- } +- +- test_switch_statement() async { +- addTestSource('main() {switch(1) {case 1:^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_SWITCH_OUTSIDE_CLASS); +- } +- +- test_switch_statement2() async { +- addTestSource('class A{foo() {switch(1) {case 1:^}}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_SWITCH_IN_CLASS); +- } +- +- test_while_break_continue() async { +- addTestSource('main() {while (true) {^}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_LOOP_OUTSIDE_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- test_while_break_continue2() async { +- addTestSource('class A {foo() {while (true) {^}}}'); +- await computeSuggestions(); +- assertSuggestKeywords(STMT_START_IN_LOOP_IN_CLASS, +- relevance: DART_RELEVANCE_KEYWORD); +- } +- +- void _appendCompletions( +- StringBuffer msg, Iterable completions, Iterable other) { +- List sorted = completions.toList(); +- sorted.sort((c1, c2) => c1.compareTo(c2)); +- sorted.forEach( +- (c) => msg.writeln(' $c, ${other.contains(c) ? '' : '<<<<<<<<<<<'}')); +- } +- +- bool _equalSets(Iterable iter1, Iterable iter2) { +- if (iter1.length != iter2.length) return false; +- if (iter1.any((c) => !iter2.contains(c))) return false; +- if (iter2.any((c) => !iter1.contains(c))) return false; +- return true; +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart +deleted file mode 100644 +index 0cd20680cc5..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart ++++ /dev/null +@@ -1,320 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/label_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LabelContributorTest); +- }); +-} +- +-@reflectiveTest +-class LabelContributorTest extends DartCompletionContributorTest { +- CompletionSuggestion assertSuggestLabel(String name, +- {int relevance: DART_RELEVANCE_DEFAULT, +- CompletionSuggestionKind kind: CompletionSuggestionKind.IDENTIFIER}) { +- CompletionSuggestion cs = +- assertSuggest(name, csKind: kind, relevance: relevance); +- expect(cs.returnType, isNull); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.flags, 0); +- expect(element.kind, equals(ElementKind.LABEL)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new LabelContributor(); +- } +- +- test_break_ignores_outer_functions_using_closure() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- var f = () { +- bar: while (true) { break ^ } +- }; +- } +-} +-'''); +- await computeSuggestions(); +- // Labels in outer functions are never accessible. +- assertSuggestLabel('bar'); +- assertNotSuggested('foo'); +- } +- +- test_break_ignores_outer_functions_using_local_function() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- void f() { +- bar: while (true) { break ^ } +- }; +- } +-} +-'''); +- await computeSuggestions(); +- // Labels in outer functions are never accessible. +- assertSuggestLabel('bar'); +- assertNotSuggested('foo'); +- } +- +- test_break_ignores_toplevel_variables() async { +- addTestSource(''' +-int x; +-void main() { +- while (true) { +- break ^ +- } +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('x'); +- } +- +- test_break_ignores_unrelated_statements() async { +- addTestSource(''' +-void main() { +- foo: while (true) {} +- while (true) { break ^ } +- bar: while (true) {} +-} +-'''); +- await computeSuggestions(); +- // The scope of the label defined by a labeled statement is just the +- // statement itself, so neither "foo" nor "bar" are in scope at the caret +- // position. +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- } +- +- test_break_to_enclosing_loop() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- bar: while (true) { +- break ^ +- } +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- assertSuggestLabel('bar'); +- } +- +- test_continue_from_loop_to_switch() async { +- addTestSource(''' +-void main() { +- switch (x) { +- foo: case 1: +- break; +- bar: case 2: +- while (true) { +- continue ^; +- } +- break; +- baz: case 3: +- break; +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- assertSuggestLabel('bar'); +- assertSuggestLabel('baz'); +- } +- +- test_continue_from_switch_to_loop() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- switch (x) { +- case 1: +- continue ^; +- } +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- } +- +- test_continue_ignores_outer_functions_using_closure_with_loop() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- var f = () { +- bar: while (true) { continue ^ } +- }; +- } +-} +-'''); +- await computeSuggestions(); +- // Labels in outer functions are never accessible. +- assertSuggestLabel('bar'); +- assertNotSuggested('foo'); +- } +- +- test_continue_ignores_outer_functions_using_closure_with_switch() async { +- addTestSource(''' +-void main() { +- switch (x) { +- foo: case 1: +- var f = () { +- bar: while (true) { continue ^ } +- }; +- } +-} +-'''); +- await computeSuggestions(); +- // Labels in outer functions are never accessible. +- assertSuggestLabel('bar'); +- assertNotSuggested('foo'); +- } +- +- test_continue_ignores_outer_functions_using_local_function_with_loop() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- void f() { +- bar: while (true) { continue ^ } +- }; +- } +-} +-'''); +- await computeSuggestions(); +- // Labels in outer functions are never accessible. +- assertSuggestLabel('bar'); +- assertNotSuggested('foo'); +- } +- +- test_continue_ignores_outer_functions_using_local_function_with_switch() async { +- addTestSource(''' +-void main() { +- switch (x) { +- foo: case 1: +- void f() { +- bar: while (true) { continue ^ } +- }; +- } +-} +-'''); +- await computeSuggestions(); +- // Labels in outer functions are never accessible. +- assertSuggestLabel('bar'); +- assertNotSuggested('foo'); +- } +- +- test_continue_ignores_unrelated_statements() async { +- addTestSource(''' +-void main() { +- foo: while (true) {} +- while (true) { continue ^ } +- bar: while (true) {} +-} +-'''); +- await computeSuggestions(); +- // The scope of the label defined by a labeled statement is just the +- // statement itself, so neither "foo" nor "bar" are in scope at the caret +- // position. +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- } +- +- test_continue_to_earlier_case() async { +- addTestSource(''' +-void main() { +- switch (x) { +- foo: case 1: +- break; +- case 2: +- continue ^; +- case 3: +- break; +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- } +- +- test_continue_to_enclosing_loop() async { +- addTestSource(''' +-void main() { +- foo: while (true) { +- bar: while (true) { +- continue ^ +- } +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- assertSuggestLabel('bar'); +- } +- +- test_continue_to_enclosing_switch() async { +- addTestSource(''' +-void main() { +- switch (x) { +- foo: case 1: +- break; +- bar: case 2: +- switch (y) { +- case 1: +- continue ^; +- } +- break; +- baz: case 3: +- break; +- } +-} +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- assertSuggestLabel('bar'); +- assertSuggestLabel('baz'); +- } +- +- test_continue_to_later_case() async { +- addTestSource(''' +-void main() { +- switch (x) { +- case 1: +- break; +- case 2: +- continue ^; +- foo: case 3: +- break; +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- } +- +- test_continue_to_same_case() async { +- addTestSource(''' +-void main() { +- switch (x) { +- case 1: +- break; +- foo: case 2: +- continue ^; +- case 3: +- break; +-'''); +- await computeSuggestions(); +- assertSuggestLabel('foo'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart +deleted file mode 100644 +index 2c49eca8a03..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart ++++ /dev/null +@@ -1,251 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LibraryMemberContributorTest); +- }); +-} +- +-@reflectiveTest +-class LibraryMemberContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new LibraryMemberContributor(); +- } +- +- test_libraryPrefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('import "dart:async" as bar; foo() {bar.^}'); +- await computeSuggestions(); +- assertSuggestClass('Future'); +- assertNotSuggested('loadLibrary'); +- } +- +- test_libraryPrefix2() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}'); +- await computeSuggestions(); +- assertSuggestClass('Future'); +- } +- +- test_libraryPrefix3() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}'); +- await computeSuggestions(); +- assertSuggestConstructor('Future'); +- assertSuggestConstructor('Future.delayed'); +- } +- +- test_libraryPrefix_cascade() async { +- addTestSource(''' +- import "dart:math" as math; +- main() {math..^}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_libraryPrefix_cascade2() async { +- addTestSource(''' +- import "dart:math" as math; +- main() {math.^.}'''); +- await computeSuggestions(); +- assertSuggestFunction('min', 'T'); +- } +- +- test_libraryPrefix_cascade3() async { +- addTestSource(''' +- import "dart:math" as math; +- main() {math..^a}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_libraryPrefix_cascade4() async { +- addTestSource(''' +- import "dart:math" as math; +- main() {math.^.a}'''); +- await computeSuggestions(); +- assertSuggestFunction('min', 'T'); +- } +- +- test_libraryPrefix_deferred() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('import "dart:async" deferred as bar; foo() {bar.^}'); +- await computeSuggestions(); +- assertSuggestClass('Future'); +- assertSuggestFunction('loadLibrary', 'Future'); +- } +- +- test_libraryPrefix_deferred_inPart() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart'; +- addSource(libFile, ''' +- library testA; +- import "dart:async" deferred as bar; +- part "$testFile";'''); +- addTestSource('part of testA; foo() {bar.^}'); +- // Assume that libraries containing has been computed for part files +- await computeLibrariesContaining(); +- await computeSuggestions(); +- assertSuggestClass('Future'); +- assertSuggestFunction('loadLibrary', 'Future'); +- assertNotSuggested('foo'); +- } +- +- test_libraryPrefix_with_exports() async { +- addSource('/libA.dart', 'library libA; class A { }'); +- addSource('/libB.dart', ''' +- library libB; +- export "/libA.dart"; +- class B { } +- @deprecated class B1 { }'''); +- addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }'); +- await computeSuggestions(); +- assertSuggestClass('B'); +- assertSuggestClass('B1', relevance: DART_RELEVANCE_LOW, isDeprecated: true); +- assertSuggestClass('A'); +- assertNotSuggested('C'); +- } +- +- test_PrefixedIdentifier_library() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "/testB.dart" as b; +- var T2; +- class A { } +- main() {b.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertSuggestClass('Y'); +- assertSuggestTopLevelVar('T1', null); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_inPart() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart'; +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addSource(libFile, ''' +- library testA; +- import "/testB.dart" as b; +- part "$testFile"; +- var T2; +- class A { }'''); +- addTestSource(''' +- part of testA; +- main() {b.^}'''); +- // Assume that libraries containing has been computed for part files +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertSuggestClass('Y'); +- assertSuggestTopLevelVar('T1', null); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "/testB.dart" as b; +- var T2; +- class A { } +- foo(b.^ f) {}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertSuggestClass('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "/testB.dart" as b; +- var T2; +- class A { } +- foo(b.^) {}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('X'); +- assertSuggestClass('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_parameter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- class _W {M y; var _z;} +- class X extends _W {} +- class M{}'''); +- addTestSource(''' +- import "/testB.dart"; +- foo(X x) {x.^}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_PrefixedIdentifier_prefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testA.dart', ''' +- class A {static int bar = 10;} +- _B() {}'''); +- addTestSource(''' +- import "/testA.dart"; +- class X {foo(){A^.bar}}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart +deleted file mode 100644 +index 3343e5e5166..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart ++++ /dev/null +@@ -1,329 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LibraryPrefixContributorTest); +- }); +-} +- +-@reflectiveTest +-class LibraryPrefixContributorTest extends DartCompletionContributorTest { +- void assertSuggestLibraryPrefixes(List expectedPrefixes) { +- for (String prefix in expectedPrefixes) { +- CompletionSuggestion cs = assertSuggest(prefix, +- csKind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_DEFAULT); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.LIBRARY)); +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- assertHasNoParameterInfo(cs); +- } +- if (suggestions.length != expectedPrefixes.length) { +- failedCompletion('expected only ${expectedPrefixes.length} suggestions'); +- } +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new LibraryPrefixContributor(); +- } +- +- test_Block() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- ^ var r; +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['g']); +- } +- +- test_Block_final_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- final var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['g']); +- } +- +- test_Block_final_var() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['g']); +- } +- +- test_ClassDeclaration_body() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-@deprecated class A {^} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['x']); +- } +- +- test_ClassDeclaration_body_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['x']); +- } +- +- test_ClassDeclaration_body_final_field() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ A(){}} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['x']); +- } +- +- test_ClassDeclaration_body_final_field2() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as Soo; +-class A {final S^ A();} +-class _B {} +-A Sew;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestLibraryPrefixes(['Soo']); +- } +- +- test_ClassDeclaration_body_final_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ final foo;} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['x']); +- } +- +- test_ClassDeclaration_body_final_var() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ var foo;} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLibraryPrefixes(['x']); +- } +- +- test_InstanceCreationExpression() async { +- addSource('/testA.dart', ''' +-class A {foo(){var f; {var x;}}} +-class B {B(this.x, [String boo]) { } int x;} +-class C {C.bar({boo: 'hoo', int z: 0}) { } }'''); +- addTestSource(''' +-import "/testA.dart" as t; +-import "dart:math" as math; +-main() {new ^ String x = "hello";}'''); +- await computeSuggestions(); +- assertSuggestLibraryPrefixes(['math', 't']); +- } +- +- test_InstanceCreationExpression2() async { +- addTestSource('import "dart:convert" as json;f() {var x=new js^}'); +- await computeSuggestions(); +- assertSuggestLibraryPrefixes(['json']); +- } +- +- test_InstanceCreationExpression_inPart() async { +- addSource('/testA.dart', ''' +-class A {foo(){var f; {var x;}}} +-class B {B(this.x, [String boo]) { } int x;} +-class C {C.bar({boo: 'hoo', int z: 0}) { } }'''); +- addSource('/testB.dart', ''' +-library testB; +-import "/testA.dart" as t; +-import "dart:math" as math; +-part "$testFile" +-main() {new ^ String x = "hello";}'''); +- addTestSource(''' +-part of testB; +-main() {new ^ String x = "hello";}'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- assertSuggestLibraryPrefixes(['math', 't']); +- } +- +- test_InstanceCreationExpression_inPart_detached() async { +- addSource('/testA.dart', ''' +-class A {foo(){var f; {var x;}}} +-class B {B(this.x, [String boo]) { } int x;} +-class C {C.bar({boo: 'hoo', int z: 0}) { } }'''); +- addSource('/testB.dart', ''' +-library testB; +-import "/testA.dart" as t; +-import "dart:math" as math; +-//part "$testFile" +-main() {new ^ String x = "hello";}'''); +- addTestSource(''' +-//part of testB; +-main() {new ^ String x = "hello";}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart +deleted file mode 100644 +index 89c378da9e2..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart ++++ /dev/null +@@ -1,3975 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LocalConstructorContributorTest); +- }); +-} +- +-@reflectiveTest +-class LocalConstructorContributorTest extends DartCompletionContributorTest { +- CompletionSuggestion assertSuggestLocalVariable( +- String name, String returnType, +- {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) { +- // Local variables should only be suggested by LocalReferenceContributor +- CompletionSuggestion cs = assertSuggest(name, +- csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance); +- expect(cs.returnType, returnType != null ? returnType : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.LOCAL_VARIABLE)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, returnType != null ? returnType : 'dynamic'); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestParameter(String name, String returnType, +- {int relevance: DART_RELEVANCE_PARAMETER}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance); +- expect(cs.returnType, returnType != null ? returnType : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.PARAMETER)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, +- equals(returnType != null ? returnType : 'dynamic')); +- return cs; +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new LocalConstructorContributor(); +- } +- +- /// Sanity check. Permutations tested in local_ref_contributor. +- test_ArgDefaults_cons_with_required_named() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +- +-class A { +- A(int bar, {bool boo, @required int baz}); +- baz() { +- new A^ +- } +-}'''); +- await computeSuggestions(); +- +- assertSuggestConstructor('A', defaultArgListString: 'bar, baz: null'); +- } +- +- test_ArgumentList() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart'; +-class B { } +-String bar() => true; +-void main() {expect(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_imported_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-expect(arg) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart' +-class B { } +-String bar() => true; +-void main() {expect(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_functionalArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar() => true; +-void main() {new A(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_typedefArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-typedef Funct(); +-class A { A(Funct f) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar() => true; +-void main() {new A(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart' +-expect(arg) { } +-class B { } +-String bar() => true; +-void main() {expect(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_method() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart' +-class B { +- expect(arg) { } +- void foo() {expect(^)}} +-String bar() => true;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_functionalArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar(f()) => true; +-void main() {bar(^);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_methodArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { String bar(f()) => true; } +-void main() {new B().bar(^);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_namedParam() async { +- // SimpleIdentifier NamedExpression ArgumentList MethodInvocation +- // ExpressionStatement +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { }'''); +- addTestSource(''' +-import '/libA.dart' +-String bar() => true; +-void main() {expect(foo: ^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('main'); +- } +- +- test_AsExpression() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +- class A {var b; X _c; foo() {var a; (a as ^).foo();}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_AssignmentExpression_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int ^b = 1;}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_AssignmentExpression_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int b = ^}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_AssignmentExpression_type() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- ^ b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- ^ +- b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- int^ b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- i^ +- b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('identical'); +- } +- +- test_AwaitExpression() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- addTestSource(''' +-class A {int x; int y() => 0;} +-main() async {A a; await ^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_BinaryExpression_LHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = ^ + 2;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- } +- +- test_BinaryExpression_RHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = 2 + ^;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('=='); +- } +- +- test_Block() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- ^ var r; +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- final ^ +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final2() async { +- addTestSource('main() {final S^ v;}'); +- await computeSuggestions(); +- +- assertNotSuggested('String'); +- } +- +- test_Block_final3() async { +- addTestSource('main() {final ^ v;}'); +- await computeSuggestions(); +- +- assertNotSuggested('String'); +- } +- +- test_Block_final_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- final var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final_var() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_identifier_partial() async { +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B { }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-class D3 { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-Z D2() {int x;} +-class X {a() {var f; {var x;} D^ var r;} void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- +- // imported elements are portially filtered +- //assertNotSuggested('A'); +- assertNotSuggested('_B'); +- //assertNotSuggested('C'); +- // hidden element suggested as low relevance +- assertNotSuggested('D'); +- assertNotSuggested('D1'); +- assertNotSuggested('D2'); +- // unimported elements suggested with low relevance +- assertNotSuggested('D3'); +- //assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- //assertSuggestLibraryPrefix('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- //assertNotSuggested('Object'); +- //assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- //assertSuggestTopLevelVarGetterSetter('T1', 'String'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- //assertNotSuggested('T5'); +- //assertSuggestTopLevelVar('_T6', null); +- assertNotSuggested('=='); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- } +- +- test_Block_inherited_imported() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addSource('/testB.dart', ''' +-lib B; +-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; } +-class E extends F { var e1; e2() { } } +-class I { int i1; i2() { } } +-class M { var m1; int m2() { } }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // TODO (danrubel) prefer fields over getters +- // If add `get e1;` to interface I +- // then suggestions include getter e1 rather than field e1 +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- //assertNotSuggested('m2'); +- assertNotSuggested('=='); +- } +- +- test_Block_inherited_local() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addTestSource(''' +-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } } +-class E extends F { var e1; e2() { } } +-class I { int i1; i2() { } } +-class M { var m1; int m2() { } } +-class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- assertNotSuggested('m2'); +- } +- +- test_Block_local_function() async { +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- p^ var r; +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertNotSuggested('partT8'); +- assertNotSuggested('partBoo'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_unimported() async { +- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }'); +- addSource( +- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }'); +- testFile = '/proj/completionTest.dart'; +- addTestSource('class C {foo(){F^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('Foo'); +- // TODO(danrubel) implement +- assertNotSuggested('Foo2'); +- assertNotSuggested('Future'); +- } +- +- test_CascadeExpression_selector1() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A {var b; X _c;} +-class X{} +-// looks like a cascade to the parser +-// but the user is trying to get completions for a non-cascade +-main() {A a; a.^.z}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2() async { +- // SimpleIdentifier PropertyAccess CascadeExpression ExpressionStatement +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A {var b; X _c;} +-class X{} +-main() {A a; a..^z}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2_withTrailingReturn() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A {var b; X _c;} +-class X{} +-main() {A a; a..^ return}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_target() async { +- // SimpleIdentifier CascadeExpression ExpressionStatement +- addTestSource(''' +-class A {var b; X _c;} +-class X{} +-main() {A a; a^..b}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_CatchClause_onType() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^ {}}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_onType_noBrackets() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_typed() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_untyped() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e'); +- assertNotSuggested('s'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-@deprecated class A {^} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ A(){}} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('String'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field2() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as Soo; +-class A {final S^ A();} +-class _B {} +-A Sew;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('String'); +- assertNotSuggested('Sew'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('Soo'); +- } +- +- test_ClassDeclaration_body_final_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ final foo;} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_var() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ var foo;} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_Combinator_hide() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +-library libAB; +-part '/partAB.dart'; +-class A { } +-class B { }'''); +- addSource('/partAB.dart', ''' +-part of libAB; +-var T1; +-PB F1() => new PB(); +-class PB { }'''); +- addSource('/testCD.dart', ''' +-class C { } +-class D { }'''); +- addTestSource(''' +-import "/testAB.dart" hide ^; +-import "/testCD.dart"; +-class X {}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_Combinator_show() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +-library libAB; +-part '/partAB.dart'; +-class A { } +-class B { }'''); +- addSource('/partAB.dart', ''' +-part of libAB; +-var T1; +-PB F1() => new PB(); +-typedef PB2 F2(int blat); +-class Clz = Object with Object; +-class PB { }'''); +- addSource('/testCD.dart', ''' +-class C { } +-class D { }'''); +- addTestSource(''' +-import "/testAB.dart" show ^; +-import "/testCD.dart"; +-class X {}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_ConditionalExpression_elseExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T1 : T^}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_elseExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T1 : ^}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_partial_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T^}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_partial_thenExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? ^}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T^ : c}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_constructor_parameters_mixed_required_and_named() async { +- addTestSource('class A {A(x, {int y}) {^}}'); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- } +- +- test_constructor_parameters_mixed_required_and_positional() async { +- addTestSource('class A {A(x, [int y]) {^}}'); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- } +- +- test_constructor_parameters_named() async { +- addTestSource('class A {A({x, int y}) {^}}'); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- } +- +- test_constructor_parameters_positional() async { +- addTestSource('class A {A([x, int y]) {^}}'); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- } +- +- test_constructor_parameters_required() async { +- addTestSource('class A {A(x, int y) {^}}'); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- } +- +- test_ConstructorName_importedClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-var m; +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-var m; +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- main() {new String.fr^omCharCodes([]);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 13); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('fromCharCodes'); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('isNotEmpty'); +- assertNotSuggested('length'); +- assertNotSuggested('Object'); +- assertNotSuggested('String'); +- } +- +- test_ConstructorName_localClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}} +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_localFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +-int T1; +-F1() { } +-class X {factory X.c(); factory X._d(); z() {}} +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_DefaultFormalParameter_named_expression() async { +- // DefaultFormalParameter FormalParameterList MethodDeclaration +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {a(blat: ^) { }}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('String'); +- assertNotSuggested('identical'); +- assertNotSuggested('bar'); +- } +- +- test_enum() async { +- addTestSource('enum E { one, two } main() {^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- } +- +- test_enum_deprecated() async { +- addTestSource('@deprecated enum E { one, two } main() {^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- } +- +- test_ExpressionStatement_identifier() async { +- // SimpleIdentifier ExpressionStatement Block +- addSource('/testA.dart', ''' +-_B F1() { } +-class A {int x;} +-class _B { }'''); +- addTestSource(''' +-import "/testA.dart"; +-typedef int F2(int blat); +-class Clz = Object with Object; +-class C {foo(){^} void bar() {}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertNotSuggested('C'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('F2'); +- assertNotSuggested('Clz'); +- assertNotSuggested('C'); +- assertNotSuggested('x'); +- assertNotSuggested('_B'); +- } +- +- test_ExpressionStatement_name() async { +- // ExpressionStatement Block BlockFunctionBody MethodDeclaration +- addSource('/testA.dart', ''' +- B T1; +- class B{}'''); +- addTestSource(''' +- import "/testA.dart"; +- class C {a() {C ^}}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_typed() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "/testA.dart"; +- class C {A ^}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_var() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "/testA.dart"; +- class C {var ^}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_FieldFormalParameter_in_non_constructor() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource('class A {B(this.^foo) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 3); +- assertNoSuggestions(); +- } +- +- test_ForEachStatement_body_typed() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (int foo in bar) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_body_untyped() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (foo in bar) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_iterable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (int foo in ^) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_loopVariable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ in args) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('String'); +- } +- +- test_ForEachStatement_loopVariable_type() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ foo in args) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('String'); +- } +- +- test_ForEachStatement_loopVariable_type2() async { +- // DeclaredIdentifier ForEachStatement Block +- addTestSource('main(args) {for (S^ foo in args) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('String'); +- } +- +- test_FormalParameterList() async { +- // FormalParameterList MethodDeclaration +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {a(^) { }}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('String'); +- assertNotSuggested('identical'); +- assertNotSuggested('bar'); +- } +- +- test_ForStatement_body() async { +- // Block ForStatement +- addTestSource('main(args) {for (int i; i < 10; ++i) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('i'); +- assertNotSuggested('Object'); +- } +- +- test_ForStatement_condition() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; i^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- } +- +- test_ForStatement_initializer() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {List a; for (^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('int'); +- } +- +- test_ForStatement_updaters() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; index < 10; i^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- } +- +- test_ForStatement_updaters_prefix_expression() async { +- // SimpleIdentifier PrefixExpression ForStatement +- addTestSource(''' +-void bar() { } +-main() {for (int index = 0; index < 10; ++i^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- assertNotSuggested('main'); +- assertNotSuggested('bar'); +- } +- +- test_function_parameters_mixed_required_and_named() async { +- addTestSource(''' +-void m(x, {int y}) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_function_parameters_mixed_required_and_positional() async { +- addTestSource(''' +-void m(x, [int y]) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_function_parameters_named() async { +- addTestSource(''' +-void m({x, int y}) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_function_parameters_none() async { +- addTestSource(''' +-void m() {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_function_parameters_positional() async { +- addTestSource(''' +-void m([x, int y]) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_function_parameters_required() async { +- addTestSource(''' +-void m(x, int y) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_FunctionDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-/* */ ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment2() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-/** */ ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment3() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-/// some dartdoc +-class C2 { } +-^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionExpression_body_function() async { +- // Block BlockFunctionBody FunctionExpression +- addTestSource(''' +- void bar() { } +- String foo(List args) {x.then((R b) {^});}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('args'); +- assertNotSuggested('b'); +- assertNotSuggested('Object'); +- } +- +- test_IfStatement() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (true) ^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_condition() async { +- // SimpleIdentifier IfStatement Block BlockFunctionBody +- addTestSource(''' +-class A {int x; int y() => 0;} +-main(){var a; if (^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_IfStatement_empty() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (^) something}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_invocation() async { +- // SimpleIdentifier PrefixIdentifier IfStatement +- addTestSource(''' +-main() {var a; if (a.^) something}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('toString'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_ignore_symbol_being_completed() async { +- addTestSource('class MyClass { } main(MC^) { }'); +- await computeSuggestions(); +- assertNotSuggested('MyClass'); +- assertNotSuggested('MC'); +- } +- +- test_ImportDirective_dart() async { +- // SimpleStringLiteral ImportDirective +- addTestSource(''' +-import "dart^"; +-main() {}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_inDartDoc_reference1() async { +- addTestSource(''' +-/// The [^ +-main(aaa, bbb) {}'''); +- await computeSuggestions(); +- assertNotSuggested('main'); +- } +- +- test_inDartDoc_reference2() async { +- addTestSource(''' +-/// The [m^ +-main(aaa, bbb) {}'''); +- await computeSuggestions(); +- assertNotSuggested('main'); +- } +- +- test_inDartDoc_reference3() async { +- addTestSource(''' +-/// The [^] +-main(aaa, bbb) {}'''); +- await computeSuggestions(); +- assertNotSuggested('main'); +- } +- +- test_inDartDoc_reference4() async { +- addTestSource(''' +-/// The [m^] +-main(aaa, bbb) {}'''); +- await computeSuggestions(); +- assertNotSuggested('main'); +- } +- +- test_IndexExpression() async { +- // ExpressionStatement Block +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} f[^]}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_IndexExpression2() async { +- // SimpleIdentifier IndexExpression ExpressionStatement Block +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} f[T^]}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_InstanceCreationExpression() async { +- addTestSource(''' +-class A {foo(){var f; {var x;}}} +-class B {B(this.x, [String boo]) { } int x;} +-class C {C.bar({boo: 'hoo', int z: 0}) { } } +-main() {new ^ String x = "hello";}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion; +- +- suggestion = assertSuggestConstructor('A', elemOffset: -1); +- expect(suggestion.element.parameters, '()'); +- expect(suggestion.element.returnType, 'A'); +- expect(suggestion.declaringType, 'A'); +- expect(suggestion.parameterNames, hasLength(0)); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- +- suggestion = assertSuggestConstructor('B'); +- expect(suggestion.element.parameters, '(int x, [String boo])'); +- expect(suggestion.element.returnType, 'B'); +- expect(suggestion.declaringType, 'B'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'int'); +- expect(suggestion.parameterNames[1], 'boo'); +- expect(suggestion.parameterTypes[1], 'String'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- +- suggestion = assertSuggestConstructor('C.bar'); +- expect(suggestion.element.parameters, '({dynamic boo: \'hoo\', int z: 0})'); +- expect(suggestion.element.returnType, 'C'); +- expect(suggestion.declaringType, 'C'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'boo'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'z'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_InstanceCreationExpression_assignment_expression_filter() async { +- addTestSource(''' +-class A {} class B extends A {} class C implements A {} class D {} +-main() { +- A a; +- a = new ^ +-}'''); +- await computeSuggestions(); +- +- assertSuggestConstructor('A', +- elemOffset: -1, +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestConstructor('B', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertSuggestConstructor('C', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('D'); +- } +- +- test_InstanceCreationExpression_assignment_expression_filter2() async { +- addTestSource(''' +-class A {} class B extends A {} class C implements A {} class D {} +-main() { +- A a; +- a = new ^; +-}'''); +- await computeSuggestions(); +- +- assertSuggestConstructor('A', +- elemOffset: -1, +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestConstructor('B', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertSuggestConstructor('C', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('D'); +- } +- +- test_InstanceCreationExpression_imported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {A(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-import "dart:async"; +-int T2; +-F2() { } +-class B {B(this.x, [String boo]) { } int x;} +-class C {foo(){var f; {var x;} new ^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('Future'); +- assertNotSuggested('A'); +- assertSuggestConstructor('B'); +- assertSuggestConstructor('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('foo'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- } +- +- test_InstanceCreationExpression_unimported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){new F^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('Future'); +- assertNotSuggested('Foo'); +- } +- +- test_InstanceCreationExpression_variable_declaration_filter() async { +- addTestSource(''' +-class A {} class B extends A {} class C implements A {} class D {} +-main() { +- A a = new ^ +-}'''); +- await computeSuggestions(); +- +- assertSuggestConstructor('A', +- elemOffset: -1, +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestConstructor('B', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertSuggestConstructor('C', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('D'); +- } +- +- test_InstanceCreationExpression_variable_declaration_filter2() async { +- addTestSource(''' +-class A {} class B extends A {} class C implements A {} class D {} +-main() { +- A a = new ^; +-}'''); +- await computeSuggestions(); +- +- assertSuggestConstructor('A', +- elemOffset: -1, +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestConstructor('B', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertSuggestConstructor('C', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('D'); +- } +- +- test_InterpolationExpression() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-main() {String name; print("hello \$^");}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_InterpolationExpression_block() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-main() {String name; print("hello \${^}");}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_InterpolationExpression_block2() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addTestSource('main() {String name; print("hello \${n^}");}'); +- await computeSuggestions(); +- +- assertNotSuggested('name'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- } +- +- test_InterpolationExpression_prefix_selector() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${name.^}");}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('length'); +- assertNotSuggested('name'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_InterpolationExpression_prefix_selector2() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \$name.^");}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_InterpolationExpression_prefix_target() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${nam^e.length}");}'); +- await computeSuggestions(); +- +- assertNotSuggested('name'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- assertNotSuggested('length'); +- } +- +- test_IsExpression() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addSource('/testB.dart', ''' +-lib B; +-foo() { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-class Y {Y.c(); Y._d(); z() {}} +-main() {var x; if (x is ^) { }}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('x'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- } +- +- test_IsExpression_target() async { +- // IfStatement Block BlockFunctionBody +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {int x; int y() => 0;} +-main(){var a; if (^ is A)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +-class A {int x; int y() => 0;} +-main(){var a; if (a is ^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type_partial() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +-class A {int x; int y() => 0;} +-main(){var a; if (a is Obj^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_keyword() async { +- addSource('/testB.dart', ''' +-lib B; +-int newT1; +-int T1; +-nowIsIt() { } +-class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-String newer() {} +-var m; +-main() {new^ X.c();}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- // Imported suggestion are filtered by 1st character +- assertNotSuggested('nowIsIt'); +- assertNotSuggested('T1'); +- assertNotSuggested('newT1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- assertNotSuggested('newer'); +- } +- +- test_Literal_list() async { +- // ']' ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([^]);}'); +- await computeSuggestions(); +- +- assertNotSuggested('Some'); +- assertNotSuggested('String'); +- } +- +- test_Literal_list2() async { +- // SimpleIdentifier ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([S^]);}'); +- await computeSuggestions(); +- +- assertNotSuggested('Some'); +- assertNotSuggested('String'); +- } +- +- test_Literal_string() async { +- // SimpleStringLiteral ExpressionStatement Block +- addTestSource('class A {a() {"hel^lo"}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_localVariableDeclarationName() async { +- addTestSource('main() {String m^}'); +- await computeSuggestions(); +- +- assertNotSuggested('main'); +- assertNotSuggested('min'); +- } +- +- test_MapLiteralEntry() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-foo = {^'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- } +- +- test_MapLiteralEntry1() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-foo = {T^'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- } +- +- test_MapLiteralEntry2() async { +- // SimpleIdentifier MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-foo = {7:T^};'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- } +- +- test_method_parameters_mixed_required_and_named() async { +- addTestSource(''' +-class A { +- void m(x, {int y}) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_mixed_required_and_positional() async { +- addTestSource(''' +-class A { +- void m(x, [int y]) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_named() async { +- addTestSource(''' +-class A { +- void m({x, int y}) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_none() async { +- addTestSource(''' +-class A { +- void m() {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_positional() async { +- addTestSource(''' +-class A { +- void m([x, int y]) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_required() async { +- addTestSource(''' +-class A { +- void m(x, int y) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_MethodDeclaration_body_getters() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- } +- +- test_MethodDeclaration_body_static() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testC.dart', ''' +-class C { +- c1() {} +- var c2; +- static c3() {} +- static var c4;}'''); +- addTestSource(''' +-import "/testC.dart"; +-class B extends C { +- b1() {} +- var b2; +- static b3() {} +- static var b4;} +-class A extends B { +- a1() {} +- var a2; +- static a3() {} +- static var a4; +- static a() {^}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('a1'); +- assertNotSuggested('a2'); +- assertNotSuggested('a3'); +- assertNotSuggested('a4'); +- assertNotSuggested('b1'); +- assertNotSuggested('b2'); +- assertNotSuggested('b3'); +- assertNotSuggested('b4'); +- assertNotSuggested('c1'); +- assertNotSuggested('c2'); +- assertNotSuggested('c3'); +- assertNotSuggested('c4'); +- } +- +- test_MethodDeclaration_members() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('_a'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('bool'); +- } +- +- test_MethodDeclaration_parameters_named() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('b'); +- assertNotSuggested('int'); +- assertNotSuggested('_'); +- } +- +- test_MethodDeclaration_parameters_positional() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {Z a(X x, [int y=1]) {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('String'); +- } +- +- test_MethodDeclaration_returnType() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 {^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 {/* */ ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment2() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 {/** */ ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment3() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { +- /// some dartdoc +- ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodInvocation_no_semicolon() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {x.^ m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_missing_params_constructor() async { +- addTestSource('class C1{C1{} main(){C^}}'); +- await computeSuggestions(); +- } +- +- test_missing_params_function() async { +- addTestSource('int f1{} main(){f^}'); +- await computeSuggestions(); +- } +- +- test_missing_params_method() async { +- addTestSource('class C1{int f1{} main(){f^}}'); +- await computeSuggestions(); +- } +- +- test_new_instance() async { +- addTestSource('import "dart:math"; class A {x() {new Random().^}}'); +- await computeSuggestions(); +- +- assertNotSuggested('nextBool'); +- assertNotSuggested('nextDouble'); +- assertNotSuggested('nextInt'); +- assertNotSuggested('Random'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- } +- +- test_overrides() async { +- addTestSource(''' +-class A {m() {}} +-class B extends A {m() {^}} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_parameterName_excludeTypes() async { +- addTestSource('m(int ^) {}'); +- await computeSuggestions(); +- +- assertNotSuggested('int'); +- assertNotSuggested('bool'); +- } +- +- test_partFile_TypeName() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +-library libA; +-import "/testB.dart"; +-part "$testFile"; +-class A { } +-var m;'''); +- addTestSource(''' +-part of libA; +-class B { factory B.bar(int x) => null; } +-main() {new ^}'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestConstructor('B.bar'); +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_TypeName2() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +-part of libA; +-class B { }'''); +- addTestSource(''' +-library libA; +-import "/testB.dart"; +-part "/testA.dart"; +-class A { A({String boo: 'hoo'}) { } } +-main() {new ^} +-var m;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestConstructor('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('B'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_PrefixedIdentifier_class_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block +- addSource('/testB.dart', ''' +-lib B; +-class I { +- static const scI = 'boo'; +- X get f => new A(); +- get _g => new A();} +-class B implements I { +- static const int scB = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- addTestSource(''' +-import "/testB.dart"; +-class A extends B { +- static const String scA = 'foo'; +- w() { }} +-main() {A.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by StaticMemberContributor +- assertNotSuggested('scA'); +- assertNotSuggested('scB'); +- assertNotSuggested('scI'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('w'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_imported() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +-lib B; +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- static const int sc = 12; +- @deprecated var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- addTestSource(''' +-import "/testB.dart"; +-main() {A a; a.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_local() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-main() {A a; a.^} +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- static const int sc = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_library() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +-lib B; +-var T1; +-class X { } +-class Y { }'''); +- addTestSource(''' +-import "/testB.dart" as b; +-var T2; +-class A { } +-main() {b.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +-lib B; +-var T1; +-class X { } +-class Y { }'''); +- addTestSource(''' +-import "/testB.dart" as b; +-var T2; +-class A { } +-foo(b.^ f) {}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +-lib B; +-var T1; +-class X { } +-class Y { }'''); +- addTestSource(''' +-import "/testB.dart" as b; +-var T2; +-class A { } +-foo(b.^) {}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_parameter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +-lib B; +-class _W {M y; var _z;} +-class X extends _W {} +-class M{}'''); +- addTestSource(''' +-import "/testB.dart"; +-foo(X x) {x.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('y'); +- assertNotSuggested('_z'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_prefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testA.dart', ''' +-class A {static int bar = 10;} +-_B() {}'''); +- addTestSource(''' +-import "/testA.dart"; +-class X {foo(){A^.bar}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('_B'); +- } +- +- test_PrefixedIdentifier_propertyAccess() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('compareTo'); +- } +- +- test_PrefixedIdentifier_propertyAccess_newStmt() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^ int y = 0;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('compareTo'); +- } +- +- test_PrefixedIdentifier_trailingStmt_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('const String g = "hello"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_field() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g; f() {g.^ int y = 0;}}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_function() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g() => "one"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('typedef String g(); f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_typed() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {String g; g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_untyped() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {var g = "hello"; g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_method() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {f(String g) {g.^ int y = 0;}}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param2() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f(String g) {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_topLevelVar() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_prioritization() async { +- addTestSource('main() {var ab; var _ab; ^}'); +- await computeSuggestions(); +- assertNotSuggested('ab'); +- assertNotSuggested('_ab'); +- } +- +- test_prioritization_private() async { +- addTestSource('main() {var ab; var _ab; _^}'); +- await computeSuggestions(); +- assertNotSuggested('ab'); +- assertNotSuggested('_ab'); +- } +- +- test_prioritization_public() async { +- addTestSource('main() {var ab; var _ab; a^}'); +- await computeSuggestions(); +- assertNotSuggested('ab'); +- assertNotSuggested('_ab'); +- } +- +- test_PropertyAccess_expression() async { +- // SimpleIdentifier MethodInvocation PropertyAccess ExpressionStatement +- addTestSource('class A {a() {"hello".to^String().length}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 8); +- assertNotSuggested('length'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PropertyAccess_noTarget() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){.^}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_noTarget2() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('main() {.^}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_selector() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement Block +- addTestSource('class A {a() {"hello".length.^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEven'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_shadowed_name() async { +- addTestSource('var a; class A { var a; m() { ^ } }'); +- await computeSuggestions(); +- assertNotSuggested('a'); +- } +- +- test_SwitchStatement_c() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {c^}}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_SwitchStatement_case() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}'); +- await computeSuggestions(); +- +- assertNotSuggested('A'); +- assertNotSuggested('g'); +- assertNotSuggested('t'); +- assertNotSuggested('String'); +- } +- +- test_SwitchStatement_empty() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {^}}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_ThisExpression_block() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A() {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {this.^ m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A() {this.^} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.^) {} +- A.z() {} +- var b; X _c; static sb; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('sb'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param2() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.b^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param3() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.^b) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param4() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.b, this.^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_TopLevelVariableDeclaration_typed_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} B ^'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_TopLevelVariableDeclaration_untyped_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} var ^'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_TypeArgumentList() async { +- // SimpleIdentifier BinaryExpression ExpressionStatement +- addSource('/testA.dart', ''' +-class C1 {int x;} +-F1() => 0; +-typedef String T1(int blat);'''); +- addTestSource(''' +-import "/testA.dart";' +-class C2 {int x;} +-F2() => 0; +-typedef int T2(int blat); +-class C {} +-main() { C<^> c; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('C1'); +- assertNotSuggested('T1'); +- assertNotSuggested('C2'); +- assertNotSuggested('T2'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- } +- +- test_TypeArgumentList2() async { +- // TypeName TypeArgumentList TypeName +- addSource('/testA.dart', ''' +-class C1 {int x;} +-F1() => 0; +-typedef String T1(int blat);'''); +- addTestSource(''' +-import "/testA.dart";' +-class C2 {int x;} +-F2() => 0; +-typedef int T2(int blat); +-class C {} +-main() { C c; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('C1'); +- assertNotSuggested('C2'); +- } +- +- test_VariableDeclaration_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addSource('/testB.dart', ''' +-lib B; +-foo() { } +-class _B { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-class Y {Y.c(); Y._d(); z() {}} +-main() {var ^}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_VariableDeclarationList_final() async { +- // VariableDeclarationList VariableDeclarationStatement Block +- addTestSource('main() {final ^} class C { }'); +- await computeSuggestions(); +- +- assertNotSuggested('Object'); +- assertNotSuggested('C'); +- assertNotSuggested('=='); +- } +- +- test_VariableDeclarationStatement_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +-lib B; +-foo() { } +-class _B { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-class Y {Y.c(); Y._d(); z() {}} +-class C {bar(){var f; {var x;} var e = ^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('_B'); +- assertNotSuggested('Y'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +- +- test_VariableDeclarationStatement_RHS_missing_semicolon() async { +- // VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +-lib B; +-foo1() { } +-void bar1() { } +-class _B { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-foo2() { } +-void bar2() { } +-class Y {Y.c(); Y._d(); z() {}} +-class C {bar(){var f; {var x;} var e = ^ var g}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('foo1'); +- assertNotSuggested('bar1'); +- assertNotSuggested('foo2'); +- assertNotSuggested('bar2'); +- assertNotSuggested('_B'); +- assertNotSuggested('Y'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart +deleted file mode 100644 +index 9d776dce62e..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart ++++ /dev/null +@@ -1,282 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LocalLibraryContributorTest); +- }); +-} +- +-@reflectiveTest +-class LocalLibraryContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new LocalLibraryContributor(); +- } +- +- test_partFile_Constructor() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- library libA; +- import "/testB.dart"; +- part "$testFile"; +- class A { } +- var m;'''); +- addTestSource(''' +- part of libA; +- class B { factory B.bar(int x) => null; } +- main() {new ^}'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestConstructor('A'); +- // Suggested by LocalConstructorContributor +- assertNotSuggested('B.bar'); +- // Suggested by ImportedReferenceContributor +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_Constructor2() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- part of libA; +- class B { }'''); +- addTestSource(''' +- library libA; +- import "/testB.dart"; +- part "/testA.dart"; +- class A { A({String boo: 'hoo'}) { } } +- main() {new ^} +- var m;'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestConstructor('B'); +- // Suggested by ConstructorContributor +- assertNotSuggested('A'); +- // Suggested by ImportedReferenceContributor +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_InstanceCreationExpression_assignment_filter() async { +- // ConstructorName InstanceCreationExpression VariableDeclarationList +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- part of libA; +- class A {} class B extends A {} class C implements A {} class D {} +- '''); +- addTestSource(''' +- library libA; +- import "/testB.dart"; +- part "/testA.dart"; +- class Local { } +- main() { +- A a; +- // FAIL: +- a = new ^ +- } +- var m;'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // A is suggested with a higher relevance +- assertSuggestConstructor('A', +- elemOffset: -1, +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestConstructor('B', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertSuggestConstructor('C', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- // D is sorted out +- assertNotSuggested('D'); +- +- // Suggested by ConstructorContributor +- assertNotSuggested('Local'); +- +- // Suggested by ImportedReferenceContributor +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_InstanceCreationExpression_variable_declaration_filter() async { +- // ConstructorName InstanceCreationExpression VariableDeclarationList +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- part of libA; +- class A {} class B extends A {} class C implements A {} class D {} +- '''); +- addTestSource(''' +- library libA; +- import "/testB.dart"; +- part "/testA.dart"; +- class Local { } +- main() { +- A a = new ^ +- } +- var m;'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // A is suggested with a higher relevance +- assertSuggestConstructor('A', +- elemOffset: -1, +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestConstructor('B', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- assertSuggestConstructor('C', +- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT); +- // D is sorted out +- assertNotSuggested('D'); +- +- // Suggested by ConstructorContributor +- assertNotSuggested('Local'); +- +- // Suggested by ImportedReferenceContributor +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_TypeName() async { +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- library libA; +- import "/testB.dart"; +- part "$testFile"; +- class A { var a1; a2(){}} +- var m; +- typedef t1(int blue); +- int af() {return 0;}'''); +- addTestSource(''' +- part of libA; +- class B { factory B.bar(int x) => null; } +- main() {^}'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestFunction('af', 'int', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestTopLevelVar('m', null, +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestFunctionTypeAlias('t1', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('a1'); +- assertNotSuggested('a2'); +- // Suggested by LocalConstructorContributor +- assertNotSuggested('B.bar'); +- // Suggested by ImportedReferenceContributor +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- } +- +- test_partFile_TypeName2() async { +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- part of libA; +- class B { var b1; b2(){}} +- int bf() => 0; +- typedef t1(int blue); +- var n;'''); +- addTestSource(''' +- library libA; +- import "/testB.dart"; +- part "/testA.dart"; +- class A { A({String boo: 'hoo'}) { } } +- main() {^} +- var m;'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestFunction('bf', 'int', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestTopLevelVar('n', null, +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestFunctionTypeAlias('t1', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('b1'); +- assertNotSuggested('b2'); +- // Suggested by ConstructorContributor +- assertNotSuggested('A'); +- // Suggested by ImportedReferenceContributor +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart +deleted file mode 100644 +index 64f561ff66f..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart ++++ /dev/null +@@ -1,4585 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LocalReferenceContributorTest); +- }); +-} +- +-@reflectiveTest +-class LocalReferenceContributorTest extends DartCompletionContributorTest { +- CompletionSuggestion assertSuggestLocalVariable( +- String name, String returnType, +- {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) { +- // Local variables should only be suggested by LocalReferenceContributor +- CompletionSuggestion cs = assertSuggest(name, +- csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance); +- expect(cs.returnType, returnType != null ? returnType : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.LOCAL_VARIABLE)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, returnType != null ? returnType : 'dynamic'); +- assertHasNoParameterInfo(cs); +- return cs; +- } +- +- CompletionSuggestion assertSuggestParameter(String name, String returnType, +- {int relevance: DART_RELEVANCE_PARAMETER}) { +- CompletionSuggestion cs = assertSuggest(name, +- csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance); +- expect(cs.returnType, returnType != null ? returnType : 'dynamic'); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.PARAMETER)); +- expect(element.name, equals(name)); +- expect(element.parameters, isNull); +- expect(element.returnType, +- equals(returnType != null ? returnType : 'dynamic')); +- return cs; +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new LocalReferenceContributor(); +- } +- +- test_ArgDefaults_function() async { +- addTestSource(''' +-bool hasLength(int a, bool b) => false; +-void main() {h^}'''); +- await computeSuggestions(); +- +- assertSuggestFunction('hasLength', 'bool', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION, +- defaultArgListString: 'a, b', +- defaultArgumentListTextRanges: [0, 1, 3, 1]); +- } +- +- test_ArgDefaults_function_none() async { +- addTestSource(''' +-bool hasLength() => false; +-void main() {h^}'''); +- await computeSuggestions(); +- +- assertSuggestFunction('hasLength', 'bool', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION, +- defaultArgListString: null, +- defaultArgumentListTextRanges: null); +- } +- +- test_ArgDefaults_function_with_optional_positional() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +- +-bool foo(int bar, [bool boo, int baz]) => false; +-void main() {h^}'''); +- await computeSuggestions(); +- +- assertSuggestFunction('foo', 'bool', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION, +- defaultArgListString: 'bar', +- defaultArgumentListTextRanges: [0, 3]); +- } +- +- test_ArgDefaults_function_with_required_named() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +- +-bool foo(int bar, {bool boo, @required int baz}) => false; +-void main() {h^}'''); +- await computeSuggestions(); +- +- assertSuggestFunction('foo', 'bool', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION, +- defaultArgListString: 'bar, baz: null', +- defaultArgumentListTextRanges: [0, 3, 10, 4]); +- } +- +- test_ArgDefaults_method_with_required_named() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +- +-class A { +- bool foo(int bar, {bool boo, @required int baz}) => false; +- baz() { +- f^ +- } +-}'''); +- await computeSuggestions(); +- +- assertSuggestMethod('foo', 'A', 'bool', +- relevance: DART_RELEVANCE_LOCAL_METHOD, +- defaultArgListString: 'bar, baz: null', +- defaultArgumentListTextRanges: [0, 3, 10, 4]); +- } +- +- test_ArgumentList() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart'; +-class B { } +-String bar() => true; +-void main() {expect(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_imported_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-expect(arg) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart' +-class B { } +-String bar() => true; +-void main() {expect(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_functionalArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar() => true; +-void main() {new A(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_typedefArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-typedef Funct(); +-class A { A(Funct f) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar() => true; +-void main() {new A(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart' +-expect(arg) { } +-class B { } +-String bar() => true; +-void main() {expect(^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_method() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import '/libA.dart' +-class B { +- expect(arg) { } +- void foo() {expect(^)}} +-String bar() => true;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_functionalArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar(f()) => true; +-void main() {boo(){} bar(^);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestFunction('boo', 'dynamic', +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_functionalArg2() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { } +-String bar({inc()}) => true; +-void main() {boo(){} bar(inc: ^);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertSuggestFunction('bar', 'String', +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION + DART_RELEVANCE_INCREMENT); +- assertSuggestFunction('boo', 'dynamic', +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION + DART_RELEVANCE_INCREMENT); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_methodArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +-library A; +-class A { A(f()) { } } +-bool hasLength(int expected) { } +-void baz() { }'''); +- addTestSource(''' +-import 'dart:async'; +-import '/libA.dart'; +-class B { String bar(f()) => true; } +-void main() {new B().bar(^);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_namedFieldParam_tear_off() async { +- addSource('/libA.dart', ''' +-typedef void VoidCallback(); +- +-class Button { +- final VoidCallback onPressed; +- Button({this.onPressed}); +-} +-'''); +- addTestSource(''' +-import '/libA.dart'; +- +-class PageState { +- void _incrementCounter() { } +- build() => +- new Button( +- onPressed: ^ +- ); +-} +-'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggest('_incrementCounter', +- csKind: CompletionSuggestionKind.IDENTIFIER); +- } +- +- test_ArgumentList_namedParam() async { +- // SimpleIdentifier NamedExpression ArgumentList MethodInvocation +- // ExpressionStatement +- addSource('/libA.dart', ''' +-library A; +-bool hasLength(int expected) { }'''); +- addTestSource(''' +-import '/libA.dart' +-String bar() => true; +-void main() {expect(foo: ^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestFunction('bar', 'String', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('hasLength'); +- assertNotSuggested('main'); +- } +- +- test_ArgumentList_namedParam_filter() async { +- // SimpleIdentifier NamedExpression ArgumentList +- // InstanceCreationExpression +- addTestSource(''' +- class A {} +- class B extends A {} +- class C implements A {} +- class D {} +- class E { +- A a; +- E({A someA}); +- } +- A a = new A(); +- B b = new B(); +- C c = new C(); +- D d = new D(); +- E e = new E(someA: ^); +- '''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestTopLevelVar('a', 'A', +- relevance: +- DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE + DART_RELEVANCE_INCREMENT); +- assertSuggestTopLevelVar('b', 'B', +- relevance: +- DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE + DART_RELEVANCE_INCREMENT); +- assertSuggestTopLevelVar('c', 'C', +- relevance: +- DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE + DART_RELEVANCE_INCREMENT); +- assertSuggestTopLevelVar('d', 'D', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestTopLevelVar('e', 'E', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- } +- +- test_ArgumentList_namedParam_tear_off() async { +- addSource('/libA.dart', ''' +-typedef void VoidCallback(); +- +-class Button { +- Button({VoidCallback onPressed}); +-} +-'''); +- addTestSource(''' +-import '/libA.dart'; +- +-class PageState { +- void _incrementCounter() { } +- build() => +- new Button( +- onPressed: ^ +- ); +-} +-'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggest('_incrementCounter', +- csKind: CompletionSuggestionKind.IDENTIFIER); +- } +- +- test_ArgumentList_namedParam_tear_off_1() async { +- addSource('/libA.dart', ''' +-typedef void VoidCallback(); +- +-class Button { +- Button({VoidCallback onPressed, int x}); +-} +-'''); +- addTestSource(''' +-import '/libA.dart'; +- +-class PageState { +- void _incrementCounter() { } +- build() => +- new Button( +- onPressed: ^ +- ); +-} +-'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggest('_incrementCounter', +- csKind: CompletionSuggestionKind.IDENTIFIER); +- } +- +- test_ArgumentList_namedParam_tear_off_2() async { +- addSource('/libA.dart', ''' +-typedef void VoidCallback(); +- +-class Button { +- Button({ int x, VoidCallback onPressed); +-} +-'''); +- addTestSource(''' +-import '/libA.dart'; +- +-class PageState { +- void _incrementCounter() { } +- build() => +- new Button( +- onPressed: ^ +- ); +-} +-'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggest('_incrementCounter', +- csKind: CompletionSuggestionKind.IDENTIFIER); +- } +- +- test_AsExpression_type() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +- class A {var b; X _c; foo() {var a; (a as ^).foo();}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertSuggestClass('A'); +- assertNotSuggested('=='); +- } +- +- test_AsExpression_type_filter_extends() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +-class A {} class B extends A {} class C extends A {} class D {} +-f(A a){ (a as ^) }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('D'); +- assertNotSuggested('Object'); +- } +- +- test_AsExpression_type_filter_implements() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +-class A {} class B implements A {} class C implements A {} class D {} +-f(A a){ (a as ^) }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('D'); +- assertNotSuggested('Object'); +- } +- +- test_AsExpression_type_filter_undefined_type() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +-class A {} +-f(U u){ (u as ^) }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- } +- +- test_AssignmentExpression_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int ^b = 1;}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_AssignmentExpression_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int b = ^}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('a', 'int'); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_AssignmentExpression_type() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- ^ b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertNotSuggested('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- ^ +- b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertNotSuggested('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertSuggestLocalVariable('a', 'int'); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- int^ b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertSuggestClass('A'); +- assertNotSuggested('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +-class A {} main() { +- int a; +- i^ +- b = 1; +-}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestClass('A'); +- assertNotSuggested('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertSuggestLocalVariable('a', 'int'); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('identical'); +- } +- +- test_AwaitExpression() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- addTestSource(''' +-class A {int x; int y() => 0;} +-main() async {A a; await ^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('a', 'A'); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_AwaitExpression2() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- addTestSource(''' +- class A { +- int x; +- Future y() async {return 0;} +- foo() async {await ^ await y();} +- } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestMethod('y', 'A', 'Future', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_BinaryExpression_LHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = ^ + 2;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('a', 'int'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- } +- +- test_BinaryExpression_RHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = 2 + ^;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('a', 'int'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('=='); +- } +- +- test_Block() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- ^ var r; +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggestClass('X', elemFile: testFile); +- assertSuggestClass('Z'); +- assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestMethod('b', 'X', 'void', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestFunction('localF', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestLocalVariable('f', null); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertSuggestFunction('D2', 'Z', relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertSuggestTopLevelVar('T5', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestTopLevelVar('_T6', null, relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('=='); +- assertSuggestGetter('T7', 'String', +- relevance: DART_RELEVANCE_LOCAL_ACCESSOR); +- assertSuggestSetter('T8', relevance: DART_RELEVANCE_LOCAL_ACCESSOR); +- assertSuggestGetter('clog', 'int', +- relevance: DART_RELEVANCE_LOCAL_ACCESSOR); +- assertSuggestSetter('blog', relevance: DART_RELEVANCE_LOCAL_ACCESSOR); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- final ^ +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggestClass('X'); +- assertSuggestClass('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final2() async { +- addTestSource('main() {final S^ v;}'); +- await computeSuggestions(); +- +- assertNotSuggested('String'); +- } +- +- test_Block_final3() async { +- addTestSource('main() {final ^ v;}'); +- await computeSuggestions(); +- +- assertNotSuggested('String'); +- } +- +- test_Block_final_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- final var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggestClass('X'); +- assertSuggestClass('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final_var() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertSuggestClass('X'); +- assertSuggestClass('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_identifier_partial() async { +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B { }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-class D3 { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-Z D2() {int x;} +-class X {a() {var f; {var x;} D^ var r;} void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertSuggestClass('X'); +- assertSuggestClass('Z'); +- assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestMethod('b', 'X', 'void', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestLocalVariable('f', null); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- +- // imported elements are portially filtered +- //assertNotSuggested('A'); +- assertNotSuggested('_B'); +- //assertNotSuggested('C'); +- // hidden element suggested as low relevance +- assertNotSuggested('D'); +- assertNotSuggested('D1'); +- assertSuggestFunction('D2', 'Z', relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- // unimported elements suggested with low relevance +- assertNotSuggested('D3'); +- //assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- //assertSuggestLibraryPrefix('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- //assertNotSuggested('Object'); +- //assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- //assertSuggestTopLevelVarGetterSetter('T1', 'String'); +- assertNotSuggested('_T2'); +- //assertNotSuggested('T3'); +- assertNotSuggested('_T4'); +- //assertSuggestTopLevelVar('T5', 'int', relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- //assertSuggestTopLevelVar('_T6', null); +- assertNotSuggested('=='); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- } +- +- test_Block_inherited_imported() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- resolveSource('/testB.dart', ''' +-lib B; +-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; } +-class E extends F { var e1; e2() { } } +-class I { int i1; i2() { } } +-class M { var m1; int m2() { } }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // TODO (danrubel) prefer fields over getters +- // If add `get e1;` to interface I +- // then suggestions include getter e1 rather than field e1 +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- //assertNotSuggested('m2'); +- assertNotSuggested('=='); +- } +- +- test_Block_inherited_local() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addTestSource(''' +-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } } +-class E extends F { var e1; e2() { } } +-class I { int i1; i2() { } } +-class M { var m1; int m2() { } } +-class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- assertNotSuggested('m2'); +- } +- +- test_Block_local_function() async { +- addSource('/testAB.dart', ''' +-export "dart:math" hide max; +-class A {int x;} +-@deprecated D1() {int x;} +-class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +-String T1; +-var _T2; +-class C { } +-class D { }'''); +- addSource('/testEEF.dart', ''' +-class EE { } +-class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +-class H { } +-int T3; +-var _T4;'''); // not imported +- addTestSource(''' +-import "/testAB.dart"; +-import "/testCD.dart" hide D; +-import "/testEEF.dart" show EE; +-import "/testG.dart" as g; +-int T5; +-var _T6; +-String get T7 => 'hello'; +-set T8(int value) { partT8() {} } +-Z D2() {int x;} +-class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- p^ var r; +- } +- void b() { }} +-class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertNotSuggested('partT8'); +- assertNotSuggested('partBoo'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_unimported() async { +- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }'); +- addSource( +- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }'); +- testFile = '/proj/completionTest.dart'; +- addTestSource('class C {foo(){F^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('Foo'); +- // TODO(danrubel) implement +- assertNotSuggested('Foo2'); +- assertNotSuggested('Future'); +- } +- +- test_CascadeExpression_selector1() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A {var b; X _c;} +-class X{} +-// looks like a cascade to the parser +-// but the user is trying to get completions for a non-cascade +-main() {A a; a.^.z}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2() async { +- // SimpleIdentifier PropertyAccess CascadeExpression ExpressionStatement +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A {var b; X _c;} +-class X{} +-main() {A a; a..^z}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2_withTrailingReturn() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "/testB.dart"; +-class A {var b; X _c;} +-class X{} +-main() {A a; a..^ return}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_target() async { +- // SimpleIdentifier CascadeExpression ExpressionStatement +- addTestSource(''' +-class A {var b; X _c;} +-class X{} +-main() {A a; a^..b}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertSuggestLocalVariable('a', 'A'); +- assertSuggestClass('A'); +- assertSuggestClass('X'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_CatchClause_onType() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^ {}}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_onType_noBrackets() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A', elemOffset: 6); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_typed() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestParameter('e', 'E'); +- assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_untyped() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestParameter('e', null); +- assertSuggestParameter('s', 'StackTrace'); +- assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-@deprecated class A {^} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- CompletionSuggestion suggestionA = assertSuggestClass('A', +- relevance: DART_RELEVANCE_LOW, isDeprecated: true); +- if (suggestionA != null) { +- expect(suggestionA.element.isDeprecated, isTrue); +- expect(suggestionA.element.isPrivate, isFalse); +- } +- CompletionSuggestion suggestionB = assertSuggestClass('_B'); +- if (suggestionB != null) { +- expect(suggestionB.element.isDeprecated, isFalse); +- expect(suggestionB.element.isPrivate, isTrue); +- } +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestClass('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ A(){}} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestClass('_B'); +- assertNotSuggested('String'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field2() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as Soo; +-class A {final S^ A();} +-class _B {} +-A Sew;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestClass('A'); +- assertSuggestClass('_B'); +- assertNotSuggested('String'); +- assertNotSuggested('Sew'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('Soo'); +- } +- +- test_ClassDeclaration_body_final_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ final foo;} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestClass('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_var() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +-class B { }'''); +- addTestSource(''' +-import "testB.dart" as x; +-class A {final ^ var foo;} +-class _B {} +-A T;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- assertSuggestClass('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- // Suggested by LibraryPrefixContributor +- assertNotSuggested('x'); +- } +- +- test_Combinator_hide() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +-library libAB; +-part '/partAB.dart'; +-class A { } +-class B { }'''); +- addSource('/partAB.dart', ''' +-part of libAB; +-var T1; +-PB F1() => new PB(); +-class PB { }'''); +- addSource('/testCD.dart', ''' +-class C { } +-class D { }'''); +- addTestSource(''' +-import "/testAB.dart" hide ^; +-import "/testCD.dart"; +-class X {}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_Combinator_show() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +-library libAB; +-part '/partAB.dart'; +-class A { } +-class B { }'''); +- addSource('/partAB.dart', ''' +-part of libAB; +-var T1; +-PB F1() => new PB(); +-typedef PB2 F2(int blat); +-class Clz = Object with Object; +-class PB { }'''); +- addSource('/testCD.dart', ''' +-class C { } +-class D { }'''); +- addTestSource(''' +-import "/testAB.dart" show ^; +-import "/testCD.dart"; +-class X {}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_ConditionalExpression_elseExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T1 : T^}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_elseExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T1 : ^}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('x'); +- assertSuggestLocalVariable('f', null); +- assertSuggestMethod('foo', 'C', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestClass('C'); +- assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_partial_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T^}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_partial_thenExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? ^}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('x'); +- assertSuggestLocalVariable('f', null); +- assertSuggestMethod('foo', 'C', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestClass('C'); +- assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_ConditionalExpression_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} return a ? T^ : c}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_constructor_parameters_mixed_required_and_named() async { +- addTestSource('class A {A(x, {int y}) {^}}'); +- await computeSuggestions(); +- assertSuggestParameter('x', null); +- assertSuggestParameter('y', 'int'); +- } +- +- test_constructor_parameters_mixed_required_and_positional() async { +- addTestSource('class A {A(x, [int y]) {^}}'); +- await computeSuggestions(); +- assertSuggestParameter('x', null); +- assertSuggestParameter('y', 'int'); +- } +- +- test_constructor_parameters_named() async { +- addTestSource('class A {A({x, int y}) {^}}'); +- await computeSuggestions(); +- assertSuggestParameter('x', null); +- assertSuggestParameter('y', 'int'); +- } +- +- test_constructor_parameters_positional() async { +- addTestSource('class A {A([x, int y]) {^}}'); +- await computeSuggestions(); +- assertSuggestParameter('x', null); +- assertSuggestParameter('y', 'int'); +- } +- +- test_constructor_parameters_required() async { +- addTestSource('class A {A(x, int y) {^}}'); +- await computeSuggestions(); +- assertSuggestParameter('x', null); +- assertSuggestParameter('y', 'int'); +- } +- +- test_ConstructorName_importedClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-var m; +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-var m; +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- main() {new String.fr^omCharCodes([]);}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 13); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('fromCharCodes'); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('isNotEmpty'); +- assertNotSuggested('length'); +- assertNotSuggested('Object'); +- assertNotSuggested('String'); +- } +- +- test_ConstructorName_localClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}} +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_localFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +-int T1; +-F1() { } +-class X {factory X.c(); factory X._d(); z() {}} +-main() {new X.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_DefaultFormalParameter_named_expression() async { +- // DefaultFormalParameter FormalParameterList MethodDeclaration +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {a(blat: ^) { }}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestFunction('foo', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestClass('A'); +- assertNotSuggested('String'); +- assertNotSuggested('identical'); +- } +- +- test_doc_classMember() async { +- String docLines = r''' +- /// My documentation. +- /// Short description. +- /// +- /// Longer description. +-'''; +- void assertDoc(CompletionSuggestion suggestion) { +- expect(suggestion.docSummary, 'My documentation.\nShort description.'); +- expect(suggestion.docComplete, +- 'My documentation.\nShort description.\n\nLonger description.'); +- } +- +- addTestSource(''' +-class C { +-$docLines +- int myField; +- +-$docLines +- myMethod() {} +- +-$docLines +- int get myGetter => 0; +- +- main() {^} +-}'''); +- await computeSuggestions(); +- { +- CompletionSuggestion suggestion = assertSuggestField('myField', 'int', +- relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertDoc(suggestion); +- } +- { +- CompletionSuggestion suggestion = assertSuggestMethod( +- 'myMethod', 'C', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertDoc(suggestion); +- } +- { +- CompletionSuggestion suggestion = assertSuggestGetter('myGetter', 'int', +- relevance: DART_RELEVANCE_LOCAL_ACCESSOR); +- assertDoc(suggestion); +- } +- } +- +- test_doc_topLevel() async { +- String docLines = r''' +-/// My documentation. +-/// Short description. +-/// +-/// Longer description. +-'''; +- void assertDoc(CompletionSuggestion suggestion) { +- expect(suggestion.docSummary, 'My documentation.\nShort description.'); +- expect(suggestion.docComplete, +- 'My documentation.\nShort description.\n\nLonger description.'); +- } +- +- addTestSource(''' +-$docLines +-class MyClass {} +- +-$docLines +-class MyClassTypeAlias = Object with MyClass; +- +-$docLines +-enum MyEnum {A, B, C} +- +-$docLines +-void myFunction() {} +- +-$docLines +-int myVariable; +- +-main() {^} +-'''); +- await computeSuggestions(); +- { +- CompletionSuggestion suggestion = assertSuggestClass('MyClass'); +- assertDoc(suggestion); +- } +- { +- CompletionSuggestion suggestion = +- assertSuggestClassTypeAlias('MyClassTypeAlias'); +- assertDoc(suggestion); +- } +- { +- CompletionSuggestion suggestion = assertSuggestEnum('MyEnum'); +- assertDoc(suggestion); +- } +- { +- CompletionSuggestion suggestion = assertSuggestFunction( +- 'myFunction', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertDoc(suggestion); +- } +- { +- CompletionSuggestion suggestion = assertSuggestTopLevelVar( +- 'myVariable', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertDoc(suggestion); +- } +- } +- +- test_enum() async { +- addTestSource('enum E { one, two } main() {^}'); +- await computeSuggestions(); +- assertSuggestEnum('E'); +- assertSuggestEnumConst('E.one'); +- assertSuggestEnumConst('E.two'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- } +- +- test_enum_deprecated() async { +- addTestSource('@deprecated enum E { one, two } main() {^}'); +- await computeSuggestions(); +- assertSuggestEnum('E', isDeprecated: true); +- assertSuggestEnumConst('E.one', isDeprecated: true); +- assertSuggestEnumConst('E.two', isDeprecated: true); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- } +- +- test_enum_filter() async { +- // SimpleIdentifier NamedExpression ArgumentList +- // InstanceCreationExpression +- addTestSource(''' +- enum E { one, two } +- enum F { three, four } +- class A {} +- class B { +- B({E someE}); +- } +- A a = new A(); +- B b = new B(someE: ^); +- '''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestEnumConst('E.one', +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertSuggestEnumConst('E.two', +- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT); +- assertNotSuggested('a'); +- assertNotSuggested('F.three'); +- assertNotSuggested('F.four'); +- } +- +- test_ExpressionStatement_identifier() async { +- // SimpleIdentifier ExpressionStatement Block +- addSource('/testA.dart', ''' +-_B F1() { } +-class A {int x;} +-class _B { }'''); +- addTestSource(''' +-import "/testA.dart"; +-typedef int F2(int blat); +-class Clz = Object with Object; +-class C {foo(){^} void bar() {}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertSuggestClass('C'); +- assertSuggestMethod('foo', 'C', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestMethod('bar', 'C', 'void', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestFunctionTypeAlias('F2', 'int'); +- assertSuggestClassTypeAlias('Clz'); +- assertSuggestClass('C'); +- assertNotSuggested('x'); +- assertNotSuggested('_B'); +- } +- +- test_ExpressionStatement_name() async { +- // ExpressionStatement Block BlockFunctionBody MethodDeclaration +- addSource('/testA.dart', ''' +- B T1; +- class B{}'''); +- addTestSource(''' +- import "/testA.dart"; +- class C {a() {C ^}}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_typed() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "/testA.dart"; +- class C {A ^}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_var() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "/testA.dart"; +- class C {var ^}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_FieldFormalParameter_in_non_constructor() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource('class A {B(this.^foo) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 3); +- assertNoSuggestions(); +- } +- +- test_ForEachStatement() async { +- // SimpleIdentifier ForEachStatement +- addTestSource('main() {List values; for (int index in ^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('values', 'List'); +- assertNotSuggested('index'); +- } +- +- test_ForEachStatement2() async { +- // SimpleIdentifier ForEachStatement +- addTestSource('main() {List values; for (int index in i^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestLocalVariable('values', 'List'); +- assertNotSuggested('index'); +- } +- +- test_ForEachStatement3() async { +- // SimpleIdentifier ParenthesizedExpression ForEachStatement +- addTestSource('main() {List values; for (int index in (i^))}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestLocalVariable('values', 'List'); +- assertNotSuggested('index'); +- } +- +- test_ForEachStatement_body_typed() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (int foo in bar) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestParameter('args', null); +- assertSuggestLocalVariable('foo', 'int'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_body_untyped() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (foo in bar) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestParameter('args', null); +- assertSuggestLocalVariable('foo', null); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_iterable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (int foo in ^) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestParameter('args', null); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_loopVariable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ in args) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('String'); +- } +- +- test_ForEachStatement_loopVariable_type() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ foo in args) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('String'); +- } +- +- test_ForEachStatement_loopVariable_type2() async { +- // DeclaredIdentifier ForEachStatement Block +- addTestSource('main(args) {for (S^ foo in args) {}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('String'); +- } +- +- test_FormalParameterList() async { +- // FormalParameterList MethodDeclaration +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {a(^) { }}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertSuggestClass('A'); +- assertNotSuggested('String'); +- assertNotSuggested('identical'); +- assertNotSuggested('bar'); +- } +- +- test_ForStatement_body() async { +- // Block ForStatement +- addTestSource('main(args) {for (int i; i < 10; ++i) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('i', 'int'); +- assertNotSuggested('Object'); +- } +- +- test_ForStatement_condition() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; i^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestLocalVariable('index', 'int'); +- } +- +- test_ForStatement_initializer() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {List a; for (^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('int'); +- } +- +- test_ForStatement_updaters() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; index < 10; i^)}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestLocalVariable('index', 'int'); +- } +- +- test_ForStatement_updaters_prefix_expression() async { +- // SimpleIdentifier PrefixExpression ForStatement +- addTestSource(''' +-void bar() { } +-main() {for (int index = 0; index < 10; ++i^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestLocalVariable('index', 'int'); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('bar'); +- } +- +- test_function_parameters_mixed_required_and_named() async { +- addTestSource(''' +-void m(x, {int y}) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_function_parameters_mixed_required_and_positional() async { +- addTestSource(''' +-void m(x, [int y]) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_function_parameters_named() async { +- addTestSource(''' +-void m({x, int y}) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_function_parameters_none() async { +- addTestSource(''' +-void m() {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- expect(suggestion.parameterNames, isEmpty); +- expect(suggestion.parameterTypes, isEmpty); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_function_parameters_positional() async { +- addTestSource(''' +-void m([x, int y]) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_function_parameters_required() async { +- addTestSource(''' +-void m(x, int y) {} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 2); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_FunctionDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-/* */ ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment2() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-/** */ ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment3() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-/// some dartdoc +-class C2 { } +-^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionExpression_body_function() async { +- // Block BlockFunctionBody FunctionExpression +- addTestSource(''' +- void bar() { } +- String foo(List args) {x.then((R b) {^});}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- var f = assertSuggestFunction('foo', 'String', +- isDeprecated: false, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- if (f != null) { +- expect(f.element.isPrivate, isFalse); +- } +- assertSuggestFunction('bar', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestParameter('args', 'List'); +- assertSuggestParameter('b', 'R'); +- assertNotSuggested('Object'); +- } +- +- test_IfStatement() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (true) ^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('Object'); +- assertSuggestClass('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_condition() async { +- // SimpleIdentifier IfStatement Block BlockFunctionBody +- addTestSource(''' +-class A {int x; int y() => 0;} +-main(){var a; if (^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('a', null); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_IfStatement_empty() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (^) something}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT); +- assertNotSuggested('Object'); +- assertSuggestClass('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_empty_private() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (_^) something}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('Object'); +- assertSuggestClass('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_invocation() async { +- // SimpleIdentifier PrefixIdentifier IfStatement +- addTestSource(''' +-main() {var a; if (a.^) something}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('toString'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_ignore_symbol_being_completed() async { +- addTestSource('class MyClass { } main(MC^) { }'); +- await computeSuggestions(); +- assertSuggestClass('MyClass'); +- assertNotSuggested('MC'); +- } +- +- test_ImportDirective_dart() async { +- // SimpleStringLiteral ImportDirective +- addTestSource(''' +-import "dart^"; +-main() {}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_inDartDoc_reference3() async { +- addTestSource(''' +-/// The [^] +-main(aaa, bbb) {}'''); +- await computeSuggestions(); +- assertSuggestFunction('main', null, +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- } +- +- test_inDartDoc_reference4() async { +- addTestSource(''' +-/// The [m^] +-main(aaa, bbb) {}'''); +- await computeSuggestions(); +- assertSuggestFunction('main', null, +- kind: CompletionSuggestionKind.IDENTIFIER, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- } +- +- test_IndexExpression() async { +- // ExpressionStatement Block +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} f[^]}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('x'); +- assertSuggestLocalVariable('f', null); +- assertSuggestMethod('foo', 'C', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestClass('C'); +- assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_IndexExpression2() async { +- // SimpleIdentifier IndexExpression ExpressionStatement Block +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-class B {int x;} +-class C {foo(){var f; {var x;} f[T^]}}'''); +- await computeSuggestions(); +- +- // top level results are partially filtered based on first char +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertNotSuggested('T1'); +- } +- +- test_InstanceCreationExpression() async { +- addTestSource(''' +-class A {foo(){var f; {var x;}}} +-class B {B(this.x, [String boo]) { } int x;} +-class C {C.bar({boo: 'hoo', int z: 0}) { } } +-main() {new ^ String x = "hello";}'''); +- await computeSuggestions(); +- // Suggested by LocalConstructorContributor +- assertNoSuggestions(); +- } +- +- test_InstanceCreationExpression_imported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-class A {A(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-import "dart:async"; +-int T2; +-F2() { } +-class B {B(this.x, [String boo]) { } int x;} +-class C {foo(){var f; {var x;} new ^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('Future'); +- assertNotSuggested('A'); +- // Suggested by LocalConstructorContributor +- assertNotSuggested('B'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('foo'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- } +- +- test_InstanceCreationExpression_unimported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){new F^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('Future'); +- assertNotSuggested('Foo'); +- } +- +- test_InterpolationExpression() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-main() {String name; print("hello \$^");}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertSuggestLocalVariable('name', 'String'); +- } +- +- test_InterpolationExpression_block() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-main() {String name; print("hello \${^}");}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertSuggestLocalVariable('name', 'String'); +- } +- +- test_InterpolationExpression_block2() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addTestSource('main() {String name; print("hello \${n^}");}'); +- await computeSuggestions(); +- +- assertSuggestLocalVariable('name', 'String'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- } +- +- test_InterpolationExpression_prefix_selector() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${name.^}");}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('length'); +- assertNotSuggested('name'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_InterpolationExpression_prefix_selector2() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \$name.^");}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_InterpolationExpression_prefix_target() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${nam^e.length}");}'); +- await computeSuggestions(); +- +- assertSuggestLocalVariable('name', 'String'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- assertNotSuggested('length'); +- } +- +- test_IsExpression() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addSource('/testB.dart', ''' +-lib B; +-foo() { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-class Y {Y.c(); Y._d(); z() {}} +-main() {var x; if (x is ^) { }}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertSuggestClass('Y'); +- assertNotSuggested('x'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- } +- +- test_IsExpression_target() async { +- // IfStatement Block BlockFunctionBody +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {int x; int y() => 0;} +-main(){var a; if (^ is A)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestLocalVariable('a', null); +- assertSuggestFunction('main', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestFunction('foo', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('bar'); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +-class A {int x; int y() => 0;} +-main(){var a; if (a is ^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type_filter_extends() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +-class A {} class B extends A {} class C extends A {} class D {} +-f(A a){ if (a is ^) {}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('D'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type_filter_implements() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +-class A {} class B implements A {} class C implements A {} class D {} +-f(A a){ if (a is ^) {}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('B'); +- assertSuggestClass('C'); +- assertNotSuggested('A'); +- assertNotSuggested('D'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type_filter_undefined_type() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +-class A {} +-f(U u){ (u as ^) }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestClass('A'); +- } +- +- test_IsExpression_type_partial() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +-class A {int x; int y() => 0;} +-main(){var a; if (a is Obj^)}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertSuggestClass('A'); +- assertNotSuggested('Object'); +- } +- +- test_keyword() async { +- addSource('/testB.dart', ''' +-lib B; +-int newT1; +-int T1; +-nowIsIt() { } +-class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-String newer() {} +-var m; +-main() {new^ X.c();}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- // Imported suggestion are filtered by 1st character +- assertNotSuggested('nowIsIt'); +- assertNotSuggested('T1'); +- assertNotSuggested('newT1'); +- assertNotSuggested('z'); +- assertSuggestTopLevelVar('m', 'dynamic', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestFunction('newer', 'String', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- } +- +- test_Literal_list() async { +- // ']' ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([^]);}'); +- await computeSuggestions(); +- +- assertSuggestLocalVariable('Some', null); +- assertNotSuggested('String'); +- } +- +- test_Literal_list2() async { +- // SimpleIdentifier ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([S^]);}'); +- await computeSuggestions(); +- +- assertSuggestLocalVariable('Some', null); +- assertNotSuggested('String'); +- } +- +- test_Literal_string() async { +- // SimpleStringLiteral ExpressionStatement Block +- addTestSource('class A {a() {"hel^lo"}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_localVariableDeclarationName() async { +- addTestSource('main() {String m^}'); +- await computeSuggestions(); +- +- assertNotSuggested('main'); +- assertNotSuggested('min'); +- } +- +- test_MapLiteralEntry() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-foo = {^'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- } +- +- test_MapLiteralEntry1() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-foo = {T^'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('T1'); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- } +- +- test_MapLiteralEntry2() async { +- // SimpleIdentifier MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { } +-foo = {7:T^};'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('T1'); +- assertSuggestTopLevelVar('T2', 'int', +- relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE); +- } +- +- test_method_parameters_mixed_required_and_named() async { +- addTestSource(''' +-class A { +- void m(x, {int y}) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_mixed_required_and_positional() async { +- addTestSource(''' +-class A { +- void m(x, [int y]) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_named() async { +- addTestSource(''' +-class A { +- void m({x, int y}) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_none() async { +- addTestSource(''' +-class A { +- void m() {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_positional() async { +- addTestSource(''' +-class A { +- void m([x, int y]) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_method_parameters_required() async { +- addTestSource(''' +-class A { +- void m(x, int y) {} +-} +-class B extends A { +- main() {^} +-} +-'''); +- await computeSuggestions(); +- assertNotSuggested('m'); +- } +- +- test_MethodDeclaration_body_getters() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- CompletionSuggestion methodA = assertSuggestMethod('a', 'A', 'Z', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- if (methodA != null) { +- expect(methodA.element.isDeprecated, isFalse); +- expect(methodA.element.isPrivate, isFalse); +- } +- CompletionSuggestion getterF = assertSuggestGetter('f', 'X', +- relevance: DART_RELEVANCE_LOW, isDeprecated: true); +- if (getterF != null) { +- expect(getterF.element.isDeprecated, isTrue); +- expect(getterF.element.isPrivate, isFalse); +- } +- CompletionSuggestion getterG = +- assertSuggestGetter('_g', null, relevance: DART_RELEVANCE_DEFAULT); +- if (getterG != null) { +- expect(getterG.element.isDeprecated, isFalse); +- expect(getterG.element.isPrivate, isTrue); +- } +- } +- +- test_MethodDeclaration_body_static() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testC.dart', ''' +-class C { +- c1() {} +- var c2; +- static c3() {} +- static var c4;}'''); +- addTestSource(''' +-import "/testC.dart"; +-class B extends C { +- b1() {} +- var b2; +- static b3() {} +- static var b4;} +-class A extends B { +- a1() {} +- var a2; +- static a3() {} +- static var a4; +- static a() {^}}'''); +- await computeSuggestions(); +- +- assertNotSuggested('a1'); +- assertNotSuggested('a2'); +- assertSuggestMethod('a3', 'A', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestField('a4', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- assertNotSuggested('b1'); +- assertNotSuggested('b2'); +- assertNotSuggested('b3'); +- assertNotSuggested('b4'); +- assertNotSuggested('c1'); +- assertNotSuggested('c2'); +- assertNotSuggested('c3'); +- assertNotSuggested('c4'); +- } +- +- test_MethodDeclaration_members() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- CompletionSuggestion methodA = +- assertSuggestMethod('_a', 'A', 'Z', relevance: DART_RELEVANCE_DEFAULT); +- if (methodA != null) { +- expect(methodA.element.isDeprecated, isFalse); +- expect(methodA.element.isPrivate, isTrue); +- } +- CompletionSuggestion getterF = assertSuggestField('f', 'X', +- relevance: DART_RELEVANCE_LOW, isDeprecated: true); +- if (getterF != null) { +- expect(getterF.element.isDeprecated, isTrue); +- expect(getterF.element.isPrivate, isFalse); +- expect(getterF.element.parameters, isNull); +- } +- // If user did not type '_' then relevance of private members is not raised +- CompletionSuggestion getterG = +- assertSuggestField('_g', null, relevance: DART_RELEVANCE_DEFAULT); +- if (getterG != null) { +- expect(getterG.element.isDeprecated, isFalse); +- expect(getterG.element.isPrivate, isTrue); +- expect(getterF.element.parameters, isNull); +- } +- assertNotSuggested('bool'); +- } +- +- test_MethodDeclaration_members_private() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X f; Z _a() {_^} var _g;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- CompletionSuggestion methodA = assertSuggestMethod('_a', 'A', 'Z', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- if (methodA != null) { +- expect(methodA.element.isDeprecated, isFalse); +- expect(methodA.element.isPrivate, isTrue); +- } +- CompletionSuggestion getterF = assertSuggestField('f', 'X', +- relevance: DART_RELEVANCE_LOW, isDeprecated: true); +- if (getterF != null) { +- expect(getterF.element.isDeprecated, isTrue); +- expect(getterF.element.isPrivate, isFalse); +- expect(getterF.element.parameters, isNull); +- } +- // If user prefixed completion with '_' then suggestion of private members +- // should be the same as public members +- CompletionSuggestion getterG = +- assertSuggestField('_g', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- if (getterG != null) { +- expect(getterG.element.isDeprecated, isFalse); +- expect(getterG.element.isPrivate, isTrue); +- expect(getterF.element.parameters, isNull); +- } +- assertNotSuggested('bool'); +- } +- +- test_MethodDeclaration_parameters_named() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- CompletionSuggestion methodA = assertSuggestMethod('a', 'A', 'Z', +- relevance: DART_RELEVANCE_LOW, isDeprecated: true); +- if (methodA != null) { +- expect(methodA.element.isDeprecated, isTrue); +- expect(methodA.element.isPrivate, isFalse); +- } +- assertSuggestParameter('x', 'X'); +- assertSuggestParameter('y', null); +- assertSuggestParameter('b', null); +- assertNotSuggested('int'); +- assertNotSuggested('_'); +- } +- +- test_MethodDeclaration_parameters_positional() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource(''' +-foo() { } +-void bar() { } +-class A {Z a(X x, [int y=1]) {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestFunction('foo', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestFunction('bar', 'void', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestMethod('a', 'A', 'Z', relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestParameter('x', 'X'); +- assertSuggestParameter('y', 'int'); +- assertNotSuggested('String'); +- } +- +- test_MethodDeclaration_returnType() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 {^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 {/* */ ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment2() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 {/** */ ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment3() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +-int T1; +-F1() { } +-typedef D1(); +-class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +-import "/testA.dart"; +-int T2; +-F2() { } +-typedef D2(); +-class C2 { +- /// some dartdoc +- ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertSuggestFunctionTypeAlias('D2', null); +- assertSuggestClass('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodInvocation_no_semicolon() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {x.^ m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_missing_params_constructor() async { +- addTestSource('class C1{C1{} main(){C^}}'); +- await computeSuggestions(); +- } +- +- test_missing_params_function() async { +- addTestSource('int f1{} main(){f^}'); +- await computeSuggestions(); +- } +- +- test_missing_params_method() async { +- addTestSource('class C1{int f1{} main(){f^}}'); +- await computeSuggestions(); +- } +- +- test_new_instance() async { +- addTestSource('import "dart:math"; class A {x() {new Random().^}}'); +- await computeSuggestions(); +- +- assertNotSuggested('nextBool'); +- assertNotSuggested('nextDouble'); +- assertNotSuggested('nextInt'); +- assertNotSuggested('Random'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- } +- +- test_overrides() async { +- addTestSource(''' +-class A {m() {}} +-class B extends A {m() {^}} +-'''); +- await computeSuggestions(); +- assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD); +- } +- +- test_parameterName_excludeTypes() async { +- addTestSource('m(int ^) {}'); +- await computeSuggestions(); +- +- assertNotSuggested('int'); +- assertNotSuggested('bool'); +- } +- +- test_partFile_TypeName() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +-library libA; +-import "/testB.dart"; +-part "$testFile"; +-class A { } +-var m;'''); +- addTestSource(''' +-part of libA; +-class B { factory B.bar(int x) => null; } +-main() {new ^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LocalConstructorContributor +- assertNotSuggested('B.bar'); +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_TypeName2() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +-lib B; +-int T1; +-F1() { } +-class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +-part of libA; +-class B { }'''); +- addTestSource(''' +-library libA; +-import "/testB.dart"; +-part "/testA.dart"; +-class A { A({String boo: 'hoo'}) { } } +-main() {new ^} +-var m;'''); +- await computeLibrariesContaining(); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LocalConstructorContributor +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('B'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_PrefixedIdentifier_class_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block +- addSource('/testB.dart', ''' +-lib B; +-class I { +- static const scI = 'boo'; +- X get f => new A(); +- get _g => new A();} +-class B implements I { +- static const int scB = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- addTestSource(''' +-import "/testB.dart"; +-class A extends B { +- static const String scA = 'foo'; +- w() { }} +-main() {A.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by StaticMemberContributor +- assertNotSuggested('scA'); +- assertNotSuggested('scB'); +- assertNotSuggested('scI'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('w'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_imported() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +-lib B; +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- static const int sc = 12; +- @deprecated var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- addTestSource(''' +-import "/testB.dart"; +-main() {A a; a.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_local() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-main() {A a; a.^} +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- static const int sc = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_library() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +-lib B; +-var T1; +-class X { } +-class Y { }'''); +- addTestSource(''' +-import "/testB.dart" as b; +-var T2; +-class A { } +-main() {b.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +-lib B; +-var T1; +-class X { } +-class Y { }'''); +- addTestSource(''' +-import "/testB.dart" as b; +-var T2; +-class A { } +-foo(b.^ f) {}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +-lib B; +-var T1; +-class X { } +-class Y { }'''); +- addTestSource(''' +-import "/testB.dart" as b; +-var T2; +-class A { } +-foo(b.^) {}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_parameter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +-lib B; +-class _W {M y; var _z;} +-class X extends _W {} +-class M{}'''); +- addTestSource(''' +-import "/testB.dart"; +-foo(X x) {x.^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('y'); +- assertNotSuggested('_z'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_prefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testA.dart', ''' +-class A {static int bar = 10;} +-_B() {}'''); +- addTestSource(''' +-import "/testA.dart"; +-class X {foo(){A^.bar}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertSuggestClass('X'); +- assertSuggestMethod('foo', 'X', null, +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertNotSuggested('bar'); +- assertNotSuggested('_B'); +- } +- +- test_PrefixedIdentifier_propertyAccess() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('compareTo'); +- } +- +- test_PrefixedIdentifier_propertyAccess_newStmt() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^ int y = 0;}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('compareTo'); +- } +- +- test_PrefixedIdentifier_trailingStmt_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('const String g = "hello"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_field() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g; f() {g.^ int y = 0;}}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_function() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g() => "one"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('typedef String g(); f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_typed() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {String g; g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_untyped() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {var g = "hello"; g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_method() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {f(String g) {g.^ int y = 0;}}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param2() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f(String g) {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_PrefixedIdentifier_trailingStmt_topLevelVar() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- +- assertNotSuggested('length'); +- } +- +- test_prioritization() async { +- addTestSource('main() {var ab; var _ab; ^}'); +- await computeSuggestions(); +- assertSuggestLocalVariable('ab', null); +- assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT); +- } +- +- test_prioritization_private() async { +- addTestSource('main() {var ab; var _ab; _^}'); +- await computeSuggestions(); +- assertSuggestLocalVariable('ab', null); +- assertSuggestLocalVariable('_ab', null); +- } +- +- test_prioritization_public() async { +- addTestSource('main() {var ab; var _ab; a^}'); +- await computeSuggestions(); +- assertSuggestLocalVariable('ab', null); +- assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT); +- } +- +- test_PropertyAccess_expression() async { +- // SimpleIdentifier MethodInvocation PropertyAccess ExpressionStatement +- addTestSource('class A {a() {"hello".to^String().length}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 8); +- assertNotSuggested('length'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PropertyAccess_noTarget() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){.^}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_noTarget2() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('main() {.^}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_selector() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement Block +- addTestSource('class A {a() {"hello".length.^}}'); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('isEven'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_shadowed_name() async { +- addTestSource('var a; class A { var a; m() { ^ } }'); +- await computeSuggestions(); +- assertSuggestField('a', null, relevance: DART_RELEVANCE_LOCAL_FIELD); +- } +- +- test_SwitchStatement_c() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {c^}}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_SwitchStatement_case() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}'); +- await computeSuggestions(); +- +- assertSuggestClass('A'); +- assertSuggestMethod('g', 'A', 'String', +- relevance: DART_RELEVANCE_LOCAL_METHOD); +- assertSuggestLocalVariable('t', null); +- assertNotSuggested('String'); +- } +- +- test_SwitchStatement_case_var() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('g(int x) {var t; switch(x) {case 0: var bar; b^}}'); +- await computeSuggestions(); +- +- assertSuggestFunction('g', 'dynamic', +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertSuggestLocalVariable('t', 'dynamic', +- relevance: DART_RELEVANCE_LOCAL_VARIABLE); +- assertSuggestParameter('x', 'int', relevance: DART_RELEVANCE_PARAMETER); +- assertSuggestLocalVariable('bar', 'dynamic', +- relevance: DART_RELEVANCE_LOCAL_VARIABLE); +- assertNotSuggested('String'); +- } +- +- test_SwitchStatement_empty() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {^}}}'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_ThisExpression_block() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A() {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {this.^ m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A() {this.^} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.^) {} +- A.z() {} +- var b; X _c; static sb; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Contributed by FieldFormalContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('sb'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param2() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.b^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Contributed by FieldFormalContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param3() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.^b) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- // Contributed by FieldFormalContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param4() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +-main() { } +-class I {X get f => new A();get _g => new A();} +-class A implements I { +- A(this.b, this.^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +-class X{}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- // Contributed by FieldFormalContributor +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_TopLevelVariableDeclaration_typed_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} B ^'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_TopLevelVariableDeclaration_untyped_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} var ^'); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_TypeArgumentList() async { +- // SimpleIdentifier BinaryExpression ExpressionStatement +- addSource('/testA.dart', ''' +-class C1 {int x;} +-F1() => 0; +-typedef String T1(int blat);'''); +- addTestSource(''' +-import "/testA.dart";' +-class C2 {int x;} +-F2() => 0; +-typedef int T2(int blat); +-class C {} +-main() { C<^> c; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('C1'); +- assertNotSuggested('T1'); +- assertSuggestClass('C2'); +- assertSuggestFunctionTypeAlias('T2', 'int'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- } +- +- test_TypeArgumentList2() async { +- // TypeName TypeArgumentList TypeName +- addSource('/testA.dart', ''' +-class C1 {int x;} +-F1() => 0; +-typedef String T1(int blat);'''); +- addTestSource(''' +-import "/testA.dart";' +-class C2 {int x;} +-F2() => 0; +-typedef int T2(int blat); +-class C {} +-main() { C c; }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('C1'); +- assertSuggestClass('C2'); +- } +- +- test_VariableDeclaration_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addSource('/testB.dart', ''' +-lib B; +-foo() { } +-class _B { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-class Y {Y.c(); Y._d(); z() {}} +-main() {var ^}'''); +- await computeSuggestions(); +- +- assertNoSuggestions(); +- } +- +- test_VariableDeclarationList_final() async { +- // VariableDeclarationList VariableDeclarationStatement Block +- addTestSource('main() {final ^} class C { }'); +- await computeSuggestions(); +- +- assertNotSuggested('Object'); +- assertSuggestClass('C'); +- assertNotSuggested('=='); +- } +- +- test_VariableDeclarationStatement_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +-lib B; +-foo() { } +-class _B { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-class Y {Y.c(); Y._d(); z() {}} +-class C {bar(){var f; {var x;} var e = ^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('_B'); +- assertSuggestClass('Y'); +- assertSuggestClass('C'); +- assertSuggestLocalVariable('f', null); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +- +- test_VariableDeclarationStatement_RHS_missing_semicolon() async { +- // VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +-lib B; +-foo1() { } +-void bar1() { } +-class _B { } +-class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +-import "/testB.dart"; +-foo2() { } +-void bar2() { } +-class Y {Y.c(); Y._d(); z() {}} +-class C {bar(){var f; {var x;} var e = ^ var g}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('foo1'); +- assertNotSuggested('bar1'); +- assertSuggestFunction('foo2', null, +- relevance: DART_RELEVANCE_LOCAL_FUNCTION); +- assertNotSuggested('bar2'); +- assertNotSuggested('_B'); +- assertSuggestClass('Y'); +- assertSuggestClass('C'); +- assertSuggestLocalVariable('f', null); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart +deleted file mode 100644 +index f753d8a99b9..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart ++++ /dev/null +@@ -1,171 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(NamedConstructorContributorTest); +- }); +-} +- +-@reflectiveTest +-class NamedConstructorContributorTest extends DartCompletionContributorTest { +- CompletionSuggestion assertSuggestNamedConstructor( +- String name, String returnType, +- [int relevance = DART_RELEVANCE_DEFAULT, +- CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) { +- CompletionSuggestion cs = +- assertSuggest(name, csKind: kind, relevance: relevance); +- Element element = cs.element; +- expect(element, isNotNull); +- expect(element.kind, equals(ElementKind.CONSTRUCTOR)); +- expect(element.name, equals(name)); +- String param = element.parameters; +- expect(param, isNotNull); +- expect(param[0], equals('(')); +- expect(param[param.length - 1], equals(')')); +- expect(element.returnType, equals(returnType)); +- assertHasParameterInfo(cs); +- return cs; +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new NamedConstructorContributor(); +- } +- +- test_ConstructorName_importedClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- var m; +- main() {new X.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestNamedConstructor('c', 'X'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedClass_unresolved() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- var m; +- main() {new X.^}'''); +- // Assume that imported libraries are NOT resolved +- //await resolveLibraryUnit(libSource); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestNamedConstructor('c', 'X'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +- import "/testB.dart"; +- var m; +- main() {new X.^}'''); +- +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestNamedConstructor('c', 'X'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- main() {new String.fr^omCharCodes([]);}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 13); +- assertSuggestNamedConstructor('fromCharCodes', 'String'); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('isNotEmpty'); +- assertNotSuggested('length'); +- assertNotSuggested('Object'); +- assertNotSuggested('String'); +- } +- +- test_ConstructorName_localClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}} +- main() {new X.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestNamedConstructor('c', 'X'); +- assertSuggestNamedConstructor('_d', 'X'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_localFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- int T1; +- F1() { } +- class X {factory X.c(); factory X._d(); z() {}} +- main() {new X.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestNamedConstructor('c', 'X'); +- assertSuggestNamedConstructor('_d', 'X'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart +deleted file mode 100644 +index e0d356c12b2..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart ++++ /dev/null +@@ -1,112 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/override_contributor.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- // Revisit this contributor and these tests +- // once DartChangeBuilder API has solidified. +- // initializeTestEnvironment(); +- // defineReflectiveTests(InheritedContributorTest); +-} +- +-@reflectiveTest +-class OverrideContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new OverrideContributor(); +- } +- +- test_fromMultipleSuperclasses() async { +- addTestSource(r''' +-class A { +- A suggested1(int x) => null; +- B suggested2(String y) => null; +-} +-class B extends A { +- B suggested2(String y) => null; +- C suggested3([String z]) => null; +-} +-class C extends B { +- sugg^ +-} +-'''); +- await computeSuggestions(); +- _assertOverride('''@override +- A suggested1(int x) { +- // TODO: implement suggested1 +- return null; +- }'''); +- _assertOverride( +- '''@override\n A suggested1(int x) {\n // TODO: implement suggested1\n return null;\n }'''); +- _assertOverride( +- '''@override\n B suggested2(String y) {\n // TODO: implement suggested2\n return null;\n }'''); +- _assertOverride( +- '''@override\n C suggested3([String z]) {\n // TODO: implement suggested3\n return null;\n }'''); +- } +- +- test_fromPart() async { +- addSource('/myLib.dart', ''' +-library myLib; +-part '$testFile' +-part '/otherPart.dart' +-class A { +- A suggested1(int x) => null; +- B suggested2(String y) => null; +-} +-'''); +- addSource('/otherPart.dart', ''' +-part of myLib; +-class B extends A { +- B suggested2(String y) => null; +- C suggested3([String z]) => null; +-} +-'''); +- addTestSource(r''' +-part of myLib; +-class C extends B { +- sugg^ +-} +-'''); +- // assume information for context.getLibrariesContaining has been cached +- await computeLibrariesContaining(); +- await computeSuggestions(); +- _assertOverride('''@override +- A suggested1(int x) { +- // TODO: implement suggested1 +- return null; +- }'''); +- _assertOverride( +- '''@override\n A suggested1(int x) {\n // TODO: implement suggested1\n return null;\n }'''); +- _assertOverride( +- '''@override\n B suggested2(String y) {\n // TODO: implement suggested2\n return null;\n }'''); +- _assertOverride( +- '''@override\n C suggested3([String z]) {\n // TODO: implement suggested3\n return null;\n }'''); +- } +- +- CompletionSuggestion _assertOverride(String completion) { +- CompletionSuggestion cs = getSuggest( +- completion: completion, +- csKind: CompletionSuggestionKind.IDENTIFIER, +- elemKind: null); +- if (cs == null) { +- failedCompletion('expected $completion', suggestions); +- } +- expect(cs.kind, equals(CompletionSuggestionKind.IDENTIFIER)); +- expect(cs.relevance, equals(DART_RELEVANCE_HIGH)); +- expect(cs.importUri, null); +-// expect(cs.selectionOffset, equals(completion.length)); +-// expect(cs.selectionLength, equals(0)); +- expect(cs.isDeprecated, isFalse); +- expect(cs.isPotential, isFalse); +- expect(cs.element, isNotNull); +- return cs; +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart +deleted file mode 100644 +index 8df73bdd194..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart ++++ /dev/null +@@ -1,285 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(StaticMemberContributorTest); +- }); +-} +- +-@reflectiveTest +-class StaticMemberContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new StaticMemberContributor(); +- } +- +- fail_enumConst_deprecated() async { +- addTestSource('@deprecated enum E { one, two } main() {E.^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- // TODO(danrubel) Investigate why enum suggestion is not marked +- // as deprecated if enum ast element is deprecated +- assertSuggestEnumConst('one', isDeprecated: true); +- assertSuggestEnumConst('two', isDeprecated: true); +- assertNotSuggested('index'); +- assertSuggestField('values', 'List', isDeprecated: true); +- } +- +- test_enumConst() async { +- addTestSource('enum E { one, two } main() {E.^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertSuggestEnumConst('one'); +- assertSuggestEnumConst('two'); +- assertNotSuggested('index'); +- assertSuggestField('values', 'List'); +- } +- +- test_enumConst2() async { +- addTestSource('enum E { one, two } main() {E.o^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertSuggestEnumConst('one'); +- assertSuggestEnumConst('two'); +- assertNotSuggested('index'); +- assertSuggestField('values', 'List'); +- } +- +- test_enumConst3() async { +- addTestSource('enum E { one, two } main() {E.^ int g;}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertSuggestEnumConst('one'); +- assertSuggestEnumConst('two'); +- assertNotSuggested('index'); +- assertSuggestField('values', 'List'); +- } +- +- test_enumConst_cascade1() async { +- addTestSource('enum E { one, two } main() {E..^}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_enumConst_cascade2() async { +- addTestSource('enum E { one, two } main() {E.^.}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertSuggestEnumConst('one'); +- assertSuggestEnumConst('two'); +- assertNotSuggested('index'); +- assertSuggestField('values', 'List'); +- } +- +- test_enumConst_cascade3() async { +- addTestSource('enum E { one, two } main() {E..o^}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_enumConst_cascade4() async { +- addTestSource('enum E { one, two } main() {E.^.o}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertSuggestEnumConst('one'); +- assertSuggestEnumConst('two'); +- assertNotSuggested('index'); +- assertSuggestField('values', 'List'); +- } +- +- test_keyword() async { +- addTestSource('class C { static C get instance => null; } main() {C.in^}'); +- await computeSuggestions(); +- assertSuggestGetter('instance', 'C'); +- } +- +- test_only_static() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-class B { +- static int b1; +-} +-class C extends B { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C.^}'''); +- await computeSuggestions(); +- assertNotSuggested('b1'); +- assertNotSuggested('f1'); +- assertSuggestField('f2', 'int'); +- assertNotSuggested('m1'); +- assertSuggestMethod('m2', 'C', null); +- } +- +- test_only_static2() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource(''' +-class B { +- static int b1; +-} +-class C extends B { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C.^ print("something");}'''); +- await computeSuggestions(); +- assertNotSuggested('b1'); +- assertNotSuggested('f1'); +- assertSuggestField('f2', 'int'); +- assertNotSuggested('m1'); +- assertSuggestMethod('m2', 'C', null); +- } +- +- test_only_static_cascade1() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-class B { +- static int b1; +-} +-class C extends B { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C..^}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_only_static_cascade2() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-class B { +- static int b1; +-} +-class C extends B { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C.^.}'''); +- await computeSuggestions(); +- assertNotSuggested('b1'); +- assertNotSuggested('f1'); +- assertSuggestField('f2', 'int'); +- assertNotSuggested('m1'); +- assertSuggestMethod('m2', 'C', null); +- } +- +- test_only_static_cascade3() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-class B { +- static int b1; +-} +-class C extends B { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C..m^()}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_only_static_cascade4() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-class B { +- static int b1; +-} +-class C extends B { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C.^.m()}'''); +- await computeSuggestions(); +- assertNotSuggested('b1'); +- assertNotSuggested('f1'); +- assertSuggestField('f2', 'int'); +- assertNotSuggested('m1'); +- assertSuggestMethod('m2', 'C', null); +- } +- +- test_only_static_cascade_prefixed1() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-import "dart:async" as async; +-void main() {async.Future..w^()}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_only_static_cascade_prefixed2() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-import "dart:async" as async; +-void main() {async.Future.^.w()}'''); +- await computeSuggestions(); +- assertSuggestMethod('wait', 'Future', 'Future'); +- } +- +- test_PrefixedIdentifier_class_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block +- addSource('/testB.dart', ''' +- lib B; +- class I { +- static const scI = 'boo'; +- X get f => new A(); +- get _g => new A();} +- class B implements I { +- static const int scB = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- addTestSource(''' +- import "/testB.dart"; +- class A extends B { +- static const String scA = 'foo'; +- w() { }} +- main() {A.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('scA', 'String'); +- assertNotSuggested('scB'); +- assertNotSuggested('scI'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('w'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart +deleted file mode 100644 +index 72c879315a7..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart ++++ /dev/null +@@ -1,52 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'arglist_contributor_test.dart' as arglist_test; +-import 'combinator_contributor_test.dart' as combinator_test; +-import 'common_usage_sorter_test.dart' as common_usage_test; +-import 'completion_manager_test.dart' as completion_manager; +-import 'field_formal_contributor_test.dart' as field_formal_contributor_test; +-import 'imported_reference_contributor_test.dart' as imported_ref_test; +-import 'inherited_reference_contributor_test.dart' as inherited_ref_test; +-import 'keyword_contributor_test.dart' as keyword_test; +-import 'label_contributor_test.dart' as label_contributor_test; +-import 'library_member_contributor_test.dart' as library_member_test; +-import 'library_prefix_contributor_test.dart' as library_prefix_test; +-import 'local_constructor_contributor_test.dart' as local_constructor_test; +-import 'local_library_contributor_test.dart' as local_lib_test; +-import 'local_reference_contributor_test.dart' as local_ref_test; +-import 'named_constructor_contributor_test.dart' as named_contributor_test; +-import 'override_contributor_test.dart' as override_contributor_test; +-import 'static_member_contributor_test.dart' as static_contributor_test; +-import 'type_member_contributor_test.dart' as type_member_contributor_test; +-import 'uri_contributor_test.dart' as uri_contributor_test; +-import 'variable_name_contributor_test.dart' as variable_name_contributor_test; +- +-/// Utility for manually running all tests. +-main() { +- defineReflectiveSuite(() { +- arglist_test.main(); +- combinator_test.main(); +- common_usage_test.main(); +- completion_manager.main(); +- field_formal_contributor_test.main(); +- imported_ref_test.main(); +- inherited_ref_test.main(); +- keyword_test.main(); +- label_contributor_test.main(); +- library_member_test.main(); +- library_prefix_test.main(); +- local_constructor_test.main(); +- local_lib_test.main(); +- local_ref_test.main(); +- named_contributor_test.main(); +- override_contributor_test.main(); +- static_contributor_test.main(); +- type_member_contributor_test.main(); +- uri_contributor_test.main(); +- variable_name_contributor_test.main(); +- }, name: 'dart'); +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart +deleted file mode 100644 +index a47714ce074..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart ++++ /dev/null +@@ -1,4027 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(TypeMemberContributorTest); +- }); +-} +- +-@reflectiveTest +-class TypeMemberContributorTest extends DartCompletionContributorTest { +- /** +- * Check whether a declaration of the form [shadower] in a derived class +- * shadows a declaration of the form [shadowee] in a base class, for the +- * purposes of what is shown during completion. [shouldBeShadowed] indicates +- * whether shadowing is expected. +- */ +- Future check_shadowing( +- String shadower, String shadowee, bool shouldBeShadowed) async { +- addTestSource(''' +-class Base { +- $shadowee +-} +-class Derived extends Base { +- $shadower +-} +-void f(Derived d) { +- d.^ +-} +-'''); +- await computeSuggestions(); +- List suggestionsForX = suggestions +- .where((CompletionSuggestion s) => s.completion == 'x') +- .toList(); +- expect(suggestionsForX, hasLength(1)); +- if (shouldBeShadowed) { +- expect(suggestionsForX[0].declaringType, 'Derived'); +- } else { +- expect(suggestionsForX[0].declaringType, 'Base'); +- } +- } +- +- @override +- DartCompletionContributor createContributor() { +- return new TypeMemberContributor(); +- } +- +- test_ArgDefaults_method() async { +- addTestSource(''' +-class A { +- bool a(int b, bool c) => false; +-} +- +-void main() {new A().a^}'''); +- await computeSuggestions(); +- +- assertSuggestMethod('a', 'A', 'bool', defaultArgListString: 'b, c'); +- } +- +- test_ArgDefaults_method_none() async { +- addTestSource(''' +-class A { +- bool a() => false; +-} +- +-void main() {new A().a^}'''); +- await computeSuggestions(); +- +- assertSuggestMethod('a', 'A', 'bool', defaultArgListString: null); +- } +- +- test_ArgDefaults_method_with_optional_positional() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +- +-class A { +- bool foo(int bar, [bool boo, int baz]) => false; +-} +- +-void main() {new A().f^}'''); +- await computeSuggestions(); +- +- assertSuggestMethod('foo', 'A', 'bool', defaultArgListString: 'bar'); +- } +- +- test_ArgDefaults_method_with_required_named() async { +- addMetaPackageSource(); +- addTestSource(''' +-import 'package:meta/meta.dart'; +- +-class A { +- bool foo(int bar, {bool boo, @required int baz}) => false; +-} +- +-void main() {new A().f^}'''); +- await computeSuggestions(); +- +- assertSuggestMethod('foo', 'A', 'bool', +- defaultArgListString: 'bar, baz: null'); +- } +- +- test_ArgumentList() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart'; +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_imported_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- expect(arg) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_functionalArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- class A { A(f()) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { } +- String bar() => true; +- void main() {new A(^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_InstanceCreationExpression_typedefArg() async { +- // ArgumentList InstanceCreationExpression ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- typedef Funct(); +- class A { A(Funct f) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { } +- String bar() => true; +- void main() {new A(^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_function() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- expect(arg) { } +- class B { } +- String bar() => true; +- void main() {expect(^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_local_method() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import '/libA.dart' +- class B { +- expect(arg) { } +- void foo() {expect(^)}} +- String bar() => true;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_functionalArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- class A { A(f()) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { } +- String bar(f()) => true; +- void main() {bar(^);}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_MethodInvocation_methodArg() async { +- // ArgumentList MethodInvocation ExpressionStatement Block +- addSource('/libA.dart', ''' +- library A; +- class A { A(f()) { } } +- bool hasLength(int expected) { } +- void baz() { }'''); +- addTestSource(''' +- import 'dart:async'; +- import '/libA.dart'; +- class B { String bar(f()) => true; } +- void main() {new B().bar(^);}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST); +- assertNotSuggested('hasLength'); +- assertNotSuggested('identical'); +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('main'); +- assertNotSuggested('baz'); +- assertNotSuggested('print'); +- } +- +- test_ArgumentList_namedParam() async { +- // SimpleIdentifier NamedExpression ArgumentList MethodInvocation +- // ExpressionStatement +- addSource('/libA.dart', ''' +- library A; +- bool hasLength(int expected) { }'''); +- addTestSource(''' +- import '/libA.dart' +- String bar() => true; +- void main() {expect(foo: ^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('bar'); +- assertNotSuggested('hasLength'); +- assertNotSuggested('main'); +- } +- +- test_AsExpression() async { +- // SimpleIdentifier TypeName AsExpression +- addTestSource(''' +- class A {var b; X _c; foo() {var a; (a as ^).foo();}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_AssignmentExpression_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int ^b = 1;}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_AssignmentExpression_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource('class A {} main() {int a; int b = ^}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_AssignmentExpression_type() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- ^ b = 1;}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- ^ +- b = 1;}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- int^ b = 1;}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS +- // the user may be either (1) entering a type for the assignment +- // or (2) starting a new statement. +- // Consider suggesting only types +- // if only spaces separates the 1st and 2nd identifiers. +- //assertNotSuggested('a'); +- //assertNotSuggested('main'); +- //assertNotSuggested('identical'); +- } +- +- test_AssignmentExpression_type_partial_newline() async { +- // SimpleIdentifier TypeName VariableDeclarationList +- // VariableDeclarationStatement Block +- addTestSource(''' +- class A {} main() { +- int a; +- i^ +- b = 1;}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('int'); +- // Allow non-types preceding an identifier on LHS of assignment +- // if newline follows first identifier +- // because user is probably starting a new statement +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('identical'); +- } +- +- test_AwaitExpression() async { +- // SimpleIdentifier AwaitExpression ExpressionStatement +- addTestSource(''' +- class A {int x; int y() => 0;} +- main() async {A a; await ^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_BinaryExpression_LHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = ^ + 2;}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- } +- +- test_BinaryExpression_RHS() async { +- // SimpleIdentifier BinaryExpression VariableDeclaration +- // VariableDeclarationList VariableDeclarationStatement +- addTestSource('main() {int a = 1, b = 2 + ^;}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('=='); +- } +- +- test_Block() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "testAB.dart"; +- import "testCD.dart" hide D; +- import "testEEF.dart" show EE; +- import "testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- ^ var r; +- } +- void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "testAB.dart"; +- import "testCD.dart" hide D; +- import "testEEF.dart" show EE; +- import "testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- final ^ +- } +- void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final2() async { +- addTestSource('main() {final S^ v;}'); +- await computeSuggestions(); +- +- assertNotSuggested('String'); +- } +- +- test_Block_final3() async { +- addTestSource('main() {final ^ v;}'); +- await computeSuggestions(); +- +- assertNotSuggested('String'); +- } +- +- test_Block_final_final() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "testAB.dart"; +- import "testCD.dart" hide D; +- import "testEEF.dart" show EE; +- import "testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- final var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_final_var() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "testAB.dart"; +- import "testCD.dart" hide D; +- import "testEEF.dart" show EE; +- import "testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- final ^ +- var f; +- localF(int arg1) { } +- {var x;} +- } +- void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('localF'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- assertNotSuggested('partT8'); +- +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('C'); +- assertNotSuggested('partBoo'); +- // hidden element suggested as low relevance +- // but imported results are partially filtered +- //assertNotSuggested('D'); +- //assertNotSuggested( +- // 'D1', null, true, COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('D2'); +- assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- assertNotSuggested('Object'); +- assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('T1'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- assertNotSuggested('T5'); +- assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- assertNotSuggested('T7'); +- assertNotSuggested('T8'); +- assertNotSuggested('clog'); +- assertNotSuggested('blog'); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- assertNotSuggested('Uri'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_identifier_partial() async { +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B { }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- class D3 { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "testAB.dart"; +- import "testCD.dart" hide D; +- import "testEEF.dart" show EE; +- import "testG.dart" as g; +- int T5; +- var _T6; +- Z D2() {int x;} +- class X {a() {var f; {var x;} D^ var r;} void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- +- assertNotSuggested('X'); +- assertNotSuggested('Z'); +- assertNotSuggested('a'); +- assertNotSuggested('b'); +- assertNotSuggested('f'); +- // Don't suggest locals out of scope +- assertNotSuggested('r'); +- assertNotSuggested('x'); +- +- // imported elements are portially filtered +- //assertNotSuggested('A'); +- assertNotSuggested('_B'); +- //assertNotSuggested('C'); +- // hidden element suggested as low relevance +- assertNotSuggested('D'); +- assertNotSuggested('D1'); +- assertNotSuggested('D2'); +- // unimported elements suggested with low relevance +- assertNotSuggested('D3'); +- //assertNotSuggested('EE'); +- // hidden element suggested as low relevance +- //assertNotSuggested('F'); +- //assertNotSuggested('g'); +- assertNotSuggested('G'); +- //assertNotSuggested('H'); +- //assertNotSuggested('Object'); +- //assertNotSuggested('min'); +- //assertNotSuggested( +- // 'max', +- // 'num', +- // false, +- // COMPLETION_RELEVANCE_LOW); +- //assertSuggestTopLevelVarGetterSetter('T1', 'String'); +- assertNotSuggested('_T2'); +- //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW); +- assertNotSuggested('_T4'); +- //assertNotSuggested('T5'); +- //assertNotSuggested('_T6'); +- assertNotSuggested('=='); +- // TODO (danrubel) suggest HtmlElement as low relevance +- assertNotSuggested('HtmlElement'); +- } +- +- test_Block_inherited_imported() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addSource('/testB.dart', ''' +- lib B; +- class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; } +- class E extends F { var e1; e2() { } } +- class I { int i1; i2() { } } +- class M { var m1; int m2() { } }'''); +- addTestSource(''' +- import "testB.dart"; +- class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // TODO (danrubel) prefer fields over getters +- // If add `get e1;` to interface I +- // then suggestions include getter e1 rather than field e1 +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- //assertNotSuggested('m2'); +- assertNotSuggested('=='); +- } +- +- test_Block_inherited_local() async { +- // Block BlockFunctionBody MethodDeclaration ClassDeclaration +- addTestSource(''' +- class F { var f1; f2() { } get f3 => 0; set f4(fx) { } } +- class E extends F { var e1; e2() { } } +- class I { int i1; i2() { } } +- class M { var m1; int m2() { } } +- class A extends E implements I with M {a() {^}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e1'); +- assertNotSuggested('f1'); +- assertNotSuggested('i1'); +- assertNotSuggested('m1'); +- assertNotSuggested('f3'); +- assertNotSuggested('f4'); +- assertNotSuggested('e2'); +- assertNotSuggested('f2'); +- assertNotSuggested('i2'); +- assertNotSuggested('m2'); +- } +- +- test_Block_local_function() async { +- addSource('/testAB.dart', ''' +- export "dart:math" hide max; +- class A {int x;} +- @deprecated D1() {int x;} +- class _B {boo() { partBoo() {}} }'''); +- addSource('/testCD.dart', ''' +- String T1; +- var _T2; +- class C { } +- class D { }'''); +- addSource('/testEEF.dart', ''' +- class EE { } +- class F { }'''); +- addSource('/testG.dart', 'class G { }'); +- addSource('/testH.dart', ''' +- class H { } +- int T3; +- var _T4;'''); // not imported +- addTestSource(''' +- import "testAB.dart"; +- import "testCD.dart" hide D; +- import "testEEF.dart" show EE; +- import "testG.dart" as g; +- int T5; +- var _T6; +- String get T7 => 'hello'; +- set T8(int value) { partT8() {} } +- Z D2() {int x;} +- class X { +- int get clog => 8; +- set blog(value) { } +- a() { +- var f; +- localF(int arg1) { } +- {var x;} +- p^ var r; +- } +- void b() { }} +- class Z { }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('partT8'); +- assertNotSuggested('partBoo'); +- assertNotSuggested('parseIPv6Address'); +- assertNotSuggested('parseHex'); +- } +- +- test_Block_unimported() async { +- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }'); +- addSource( +- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }'); +- testFile = provider.convertPath('/proj/completionTest.dart'); +- addTestSource('class C {foo(){F^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('Foo'); +- // TODO(danrubel) implement +- assertNotSuggested('Foo2'); +- assertNotSuggested('Future'); +- } +- +- test_CascadeExpression_method1() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart"; +- class A {var b; X _c;} +- class X{} +- // looks like a cascade to the parser +- // but the user is trying to get completions for a non-cascade +- main() {A a; a.^.z()}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector1() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart"; +- class A {var b; X _c;} +- class X{} +- // looks like a cascade to the parser +- // but the user is trying to get completions for a non-cascade +- main() {A a; a.^.z}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2() async { +- // SimpleIdentifier PropertyAccess CascadeExpression ExpressionStatement +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart"; +- class A {var b; X _c;} +- class X{} +- main() {A a; a..^z}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_selector2_withTrailingReturn() async { +- // PropertyAccess CascadeExpression ExpressionStatement Block +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart"; +- class A {var b; X _c;} +- class X{} +- main() {A a; a..^ return}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('X'); +- assertNotSuggested('z'); +- assertNotSuggested('=='); +- } +- +- test_CascadeExpression_target() async { +- // SimpleIdentifier CascadeExpression ExpressionStatement +- addTestSource(''' +- class A {var b; X _c;} +- class X{} +- main() {A a; a^..b}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_CatchClause_onType() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^ {}}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_onType_noBrackets() async { +- // TypeName CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on ^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_typed() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_CatchClause_untyped() async { +- // Block CatchClause TryStatement +- addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('e'); +- assertNotSuggested('s'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- @deprecated class A {^} +- class _B {} +- A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^} +- class _B {} +- A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^ A(){}} +- class _B {} +- A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('String'); +- assertNotSuggested('T'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_field2() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as Soo; +- class A {final S^ A();} +- class _B {} +- A Sew;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('String'); +- assertNotSuggested('Sew'); +- assertNotSuggested('Soo'); +- } +- +- test_ClassDeclaration_body_final_final() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^ final foo;} +- class _B {} +- A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- assertNotSuggested('x'); +- } +- +- test_ClassDeclaration_body_final_var() async { +- // ClassDeclaration CompilationUnit +- addSource('/testB.dart', ''' +- class B { }'''); +- addTestSource(''' +- import "testB.dart" as x; +- class A {final ^ var foo;} +- class _B {} +- A T;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('_B'); +- assertNotSuggested('Object'); +- assertNotSuggested('T'); +- assertNotSuggested('x'); +- } +- +- test_Combinator_hide() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +- library libAB; +- part '/partAB.dart'; +- class A { } +- class B { }'''); +- addSource('/partAB.dart', ''' +- part of libAB; +- var T1; +- PB F1() => new PB(); +- class PB { }'''); +- addSource('/testCD.dart', ''' +- class C { } +- class D { }'''); +- addTestSource(''' +- import "testAB.dart" hide ^; +- import "testCD.dart"; +- class X {}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_Combinator_show() async { +- // SimpleIdentifier HideCombinator ImportDirective +- addSource('/testAB.dart', ''' +- library libAB; +- part '/partAB.dart'; +- class A { } +- class B { }'''); +- addSource('/partAB.dart', ''' +- part of libAB; +- var T1; +- PB F1() => new PB(); +- typedef PB2 F2(int blat); +- class Clz = Object with Object; +- class PB { }'''); +- addSource('/testCD.dart', ''' +- class C { } +- class D { }'''); +- addTestSource(''' +- import "testAB.dart" show ^; +- import "testCD.dart"; +- class X {}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ConditionalExpression_elseExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T1 : T^}}'''); +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_elseExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T1 : ^}}'''); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_partial_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T^}}'''); +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_partial_thenExpression_empty() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? ^}}'''); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConditionalExpression_thenExpression() async { +- // SimpleIdentifier ConditionalExpression ReturnStatement +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} return a ? T^ : c}}'''); +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_ConstructorName_importedClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- var m; +- main() {new X.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- var m; +- main() {new X.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_importedFactory2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- main() {new String.fr^omCharCodes([]);}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 13); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('fromCharCodes'); +- assertNotSuggested('isEmpty'); +- assertNotSuggested('isNotEmpty'); +- assertNotSuggested('length'); +- assertNotSuggested('Object'); +- assertNotSuggested('String'); +- } +- +- test_ConstructorName_localClass() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}} +- main() {new X.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_ConstructorName_localFactory() async { +- // SimpleIdentifier PrefixedIdentifier TypeName ConstructorName +- // InstanceCreationExpression +- addTestSource(''' +- int T1; +- F1() { } +- class X {factory X.c(); factory X._d(); z() {}} +- main() {new X.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by NamedConstructorContributor +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_DefaultFormalParameter_named_expression() async { +- // DefaultFormalParameter FormalParameterList MethodDeclaration +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {a(blat: ^) { }}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('String'); +- assertNotSuggested('identical'); +- assertNotSuggested('bar'); +- } +- +- test_enumConst() async { +- addTestSource('enum E { one, two } main() {E.^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- // Suggested by StaticMemberContributor +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- assertNotSuggested('index'); +- assertNotSuggested('values'); +- } +- +- test_enumConst2() async { +- addTestSource('enum E { one, two } main() {E.o^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- // Suggested by StaticMemberContributor +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- assertNotSuggested('index'); +- assertNotSuggested('values'); +- } +- +- test_enumConst3() async { +- addTestSource('enum E { one, two } main() {E.^ int g;}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- // Suggested by StaticMemberContributor +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- assertNotSuggested('index'); +- assertNotSuggested('values'); +- } +- +- test_enumConst_index() async { +- addTestSource('enum E { one, two } main() {E.one.^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- assertSuggestField('index', 'int'); +- assertNotSuggested('values'); +- } +- +- test_enumConst_index2() async { +- addTestSource('enum E { one, two } main() {E.one.i^}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- assertSuggestField('index', 'int'); +- assertNotSuggested('values'); +- } +- +- test_enumConst_index3() async { +- addTestSource('enum E { one, two } main() {E.one.^ int g;}'); +- await computeSuggestions(); +- assertNotSuggested('E'); +- assertNotSuggested('one'); +- assertNotSuggested('two'); +- assertSuggestField('index', 'int'); +- assertNotSuggested('values'); +- } +- +- test_ExpressionStatement_identifier() async { +- // SimpleIdentifier ExpressionStatement Block +- addSource('/testA.dart', ''' +- _B F1() { } +- class A {int x;} +- class _B { }'''); +- addTestSource(''' +- import "testA.dart"; +- typedef int F2(int blat); +- class Clz = Object with Object; +- class C {foo(){^} void bar() {}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertNotSuggested('C'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('F2'); +- assertNotSuggested('Clz'); +- assertNotSuggested('C'); +- assertNotSuggested('x'); +- assertNotSuggested('_B'); +- } +- +- test_ExpressionStatement_name() async { +- // ExpressionStatement Block BlockFunctionBody MethodDeclaration +- addSource('/testA.dart', ''' +- B T1; +- class B{}'''); +- addTestSource(''' +- import "testA.dart"; +- class C {a() {C ^}}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_typed() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "testA.dart"; +- class C {A ^}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_FieldDeclaration_name_var() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // FieldDeclaration +- addSource('/testA.dart', 'class A { }'); +- addTestSource(''' +- import "testA.dart"; +- class C {var ^}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_FieldFormalParameter_in_non_constructor() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource('class A {B(this.^foo) {}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 3); +- assertNoSuggestions(); +- } +- +- test_ForEachStatement_body_typed() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (int foo in bar) {^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_body_untyped() async { +- // Block ForEachStatement +- addTestSource('main(args) {for (foo in bar) {^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_iterable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (int foo in ^) {}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('Object'); +- } +- +- test_ForEachStatement_loopVariable() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ in args) {}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('String'); +- } +- +- test_ForEachStatement_loopVariable_type() async { +- // SimpleIdentifier ForEachStatement Block +- addTestSource('main(args) {for (^ foo in args) {}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('String'); +- } +- +- test_ForEachStatement_loopVariable_type2() async { +- // DeclaredIdentifier ForEachStatement Block +- addTestSource('main(args) {for (S^ foo in args) {}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('args'); +- assertNotSuggested('foo'); +- assertNotSuggested('String'); +- } +- +- test_FormalParameterList() async { +- // FormalParameterList MethodDeclaration +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {a(^) { }}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('String'); +- assertNotSuggested('identical'); +- assertNotSuggested('bar'); +- } +- +- test_ForStatement_body() async { +- // Block ForStatement +- addTestSource('main(args) {for (int i; i < 10; ++i) {^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('i'); +- assertNotSuggested('Object'); +- } +- +- test_ForStatement_condition() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; i^)}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- } +- +- test_ForStatement_initializer() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {List a; for (^)}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('int'); +- } +- +- test_ForStatement_updaters() async { +- // SimpleIdentifier ForStatement +- addTestSource('main() {for (int index = 0; index < 10; i^)}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- } +- +- test_ForStatement_updaters_prefix_expression() async { +- // SimpleIdentifier PrefixExpression ForStatement +- addTestSource(''' +- void bar() { } +- main() {for (int index = 0; index < 10; ++i^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('index'); +- assertNotSuggested('main'); +- assertNotSuggested('bar'); +- } +- +- test_FunctionDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- /* */ ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment2() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- /** */ ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionDeclaration_returnType_afterComment3() async { +- // FunctionDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- /// some dartdoc +- class C2 { } +- ^ zoo(z) { } String name;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_FunctionExpression_body_function() async { +- // Block BlockFunctionBody FunctionExpression +- addTestSource(''' +- void bar() { } +- String foo(List args) {x.then((R b) {^}'''); +- await computeSuggestions(); +- +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('args'); +- assertNotSuggested('b'); +- assertNotSuggested('Object'); +- } +- +- test_generic_field() async { +- addTestSource(''' +-class C { +- T t; +-} +-void f(C c) { +- c.^ +-} +-'''); +- await computeSuggestions(); +- assertSuggestField('t', 'int'); +- } +- +- test_generic_getter() async { +- addTestSource(''' +-class C { +- T get t => null; +-} +-void f(C c) { +- c.^ +-} +-'''); +- await computeSuggestions(); +- assertSuggestGetter('t', 'int'); +- } +- +- test_generic_method() async { +- addTestSource(''' +-class C { +- T m(T t) {} +-} +-void f(C c) { +- c.^ +-} +-'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int'); +- expect(suggestion.parameterTypes[0], 'int'); +- expect(suggestion.element.returnType, 'int'); +- expect(suggestion.element.parameters, '(int t)'); +- } +- +- test_generic_setter() async { +- addTestSource(''' +-class C { +- set t(T value) {} +-} +-void f(C c) { +- c.^ +-} +-'''); +- await computeSuggestions(); +- // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int' +- // as a parmeter to it, and it will check the appropriate field in +- // the suggestion object. +- CompletionSuggestion suggestion = assertSuggestSetter('t'); +- expect(suggestion.element.parameters, '(int value)'); +- } +- +- test_IfStatement() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (true) ^}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_condition() async { +- // SimpleIdentifier IfStatement Block BlockFunctionBody +- addTestSource(''' +- class A {int x; int y() => 0;} +- main(){var a; if (^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_IfStatement_empty() async { +- // SimpleIdentifier IfStatement +- addTestSource(''' +- class A {var b; X _c; foo() {A a; if (^) something}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_IfStatement_invocation() async { +- // SimpleIdentifier PrefixIdentifier IfStatement +- addTestSource(''' +- main() {var a; if (a.^) something}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestMethod('toString', 'Object', 'String'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_ImportDirective_dart() async { +- // SimpleStringLiteral ImportDirective +- addTestSource(''' +- import "dart^"; +- main() {}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_IndexExpression() async { +- // ExpressionStatement Block +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} f[^]}}'''); +- await computeSuggestions(); +- assertNotSuggested('x'); +- assertNotSuggested('f'); +- assertNotSuggested('foo'); +- assertNotSuggested('C'); +- assertNotSuggested('F2'); +- assertNotSuggested('T2'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_IndexExpression2() async { +- // SimpleIdentifier IndexExpression ExpressionStatement Block +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- class B {int x;} +- class C {foo(){var f; {var x;} f[T^]}}'''); +- await computeSuggestions(); +- // top level results are partially filtered based on first char +- assertNotSuggested('T2'); +- // TODO (danrubel) getter is being suggested instead of top level var +- //assertSuggestImportedTopLevelVar('T1', 'int'); +- } +- +- test_InstanceCreationExpression_imported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- class A {A(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- import "dart:async"; +- int T2; +- F2() { } +- class B {B(this.x, [String boo]) { } int x;} +- class C {foo(){var f; {var x;} new ^}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('Future'); +- assertNotSuggested('A'); +- assertNotSuggested('B'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('foo'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- } +- +- test_InstanceCreationExpression_unimported() async { +- // SimpleIdentifier TypeName ConstructorName InstanceCreationExpression +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){new F^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('Future'); +- assertNotSuggested('Foo'); +- } +- +- test_InterpolationExpression() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- main() {String name; print("hello \$^");}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- // TODO(danrubel) should return top level var rather than getter +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_InterpolationExpression_block() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- main() {String name; print("hello \${^}");}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_InterpolationExpression_block2() async { +- // SimpleIdentifier InterpolationExpression StringInterpolation +- addTestSource('main() {String name; print("hello \${n^}");}'); +- await computeSuggestions(); +- assertNotSuggested('name'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- } +- +- test_InterpolationExpression_prefix_selector() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${name.^}");}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestGetter('length', 'int'); +- assertNotSuggested('name'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_InterpolationExpression_prefix_selector2() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \$name.^");}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_InterpolationExpression_prefix_target() async { +- // SimpleIdentifier PrefixedIdentifier InterpolationExpression +- addTestSource('main() {String name; print("hello \${nam^e.length}");}'); +- await computeSuggestions(); +- assertNotSuggested('name'); +- // top level results are partially filtered +- //assertNotSuggested('Object'); +- assertNotSuggested('length'); +- } +- +- test_IsExpression() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addSource('/testB.dart', ''' +- lib B; +- foo() { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- class Y {Y.c(); Y._d(); z() {}} +- main() {var x; if (x is ^) { }}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('x'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- } +- +- test_IsExpression_target() async { +- // IfStatement Block BlockFunctionBody +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {int x; int y() => 0;} +- main(){var a; if (^ is A)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +- class A {int x; int y() => 0;} +- main(){var a; if (a is ^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_IsExpression_type_partial() async { +- // SimpleIdentifier TypeName IsExpression IfStatement +- addTestSource(''' +- class A {int x; int y() => 0;} +- main(){var a; if (a is Obj^)}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('a'); +- assertNotSuggested('main'); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- } +- +- test_keyword() async { +- addTestSource('class C { static C get instance => null; } main() {C.in^}'); +- await computeSuggestions(); +- // Suggested by StaticMemberContributor +- assertNotSuggested('instance'); +- } +- +- test_keyword2() async { +- addSource('/testB.dart', ''' +- lib B; +- int newT1; +- int T1; +- nowIsIt() { } +- class X {factory X.c(); factory X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- String newer() {} +- var m; +- main() {new^ X.c();}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('c'); +- assertNotSuggested('_d'); +- // Imported suggestion are filtered by 1st character +- assertNotSuggested('nowIsIt'); +- assertNotSuggested('T1'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- assertNotSuggested('newer'); +- } +- +- test_libraryPrefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('import "dart:async" as bar; foo() {bar.^}'); +- await computeSuggestions(); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('Future'); +- assertNotSuggested('loadLibrary'); +- } +- +- test_libraryPrefix2() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}'); +- await computeSuggestions(); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('Future'); +- } +- +- test_libraryPrefix3() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}'); +- await computeSuggestions(); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('Future'); +- assertNotSuggested('Future.delayed'); +- } +- +- test_libraryPrefix_deferred() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('import "dart:async" deferred as bar; foo() {bar.^}'); +- await computeSuggestions(); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('Future'); +- assertNotSuggested('loadLibrary'); +- } +- +- test_libraryPrefix_with_exports() async { +- addSource('/libA.dart', 'library libA; class A { }'); +- addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }'); +- addTestSource('import "libB.dart" as foo; main() {foo.^} class C { }'); +- await computeSuggestions(); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('B'); +- assertNotSuggested('A'); +- } +- +- test_Literal_list() async { +- // ']' ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([^]);}'); +- await computeSuggestions(); +- assertNotSuggested('Some'); +- assertNotSuggested('String'); +- } +- +- test_Literal_list2() async { +- // SimpleIdentifier ListLiteral ArgumentList MethodInvocation +- addTestSource('main() {var Some; print([S^]);}'); +- await computeSuggestions(); +- assertNotSuggested('Some'); +- assertNotSuggested('String'); +- } +- +- test_Literal_string() async { +- // SimpleStringLiteral ExpressionStatement Block +- addTestSource('class A {a() {"hel^lo"}}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_local() async { +- addTestSource('foo() {String x = "bar"; x.^}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_local_is() async { +- addTestSource('foo() {var x; if (x is String) x.^}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_local_propogatedType() async { +- addTestSource('foo() {var x = "bar"; x.^}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_localVariableDeclarationName() async { +- addTestSource('main() {String m^}'); +- await computeSuggestions(); +- assertNotSuggested('main'); +- assertNotSuggested('min'); +- } +- +- test_MapLiteralEntry() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- foo = {^'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- } +- +- test_MapLiteralEntry1() async { +- // MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- foo = {T^'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('T2'); +- } +- +- test_MapLiteralEntry2() async { +- // SimpleIdentifier MapLiteralEntry MapLiteral VariableDeclaration +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { } +- foo = {7:T^};'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('T2'); +- } +- +- test_method_parameters_mixed_required_and_named() async { +- addTestSource(''' +-class C { +- void m(x, {int y}) {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_mixed_required_and_positional() async { +- addTestSource(''' +-class C { +- void m(x, [int y]) {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 1); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_named() async { +- addTestSource(''' +-class C { +- void m({x, int y}) {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, true); +- } +- +- test_method_parameters_none() async { +- addTestSource(''' +-class C { +- void m() {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void'); +- expect(suggestion.parameterNames, isEmpty); +- expect(suggestion.parameterTypes, isEmpty); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_positional() async { +- addTestSource(''' +-class C { +- void m([x, int y]) {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 0); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_method_parameters_required() async { +- addTestSource(''' +-class C { +- void m(x, int y) {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void'); +- expect(suggestion.parameterNames, hasLength(2)); +- expect(suggestion.parameterNames[0], 'x'); +- expect(suggestion.parameterTypes[0], 'dynamic'); +- expect(suggestion.parameterNames[1], 'y'); +- expect(suggestion.parameterTypes[1], 'int'); +- expect(suggestion.requiredParameterCount, 2); +- expect(suggestion.hasNamedParameters, false); +- } +- +- test_MethodDeclaration_body_getters() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- } +- +- test_MethodDeclaration_body_static() async { +- // Block BlockFunctionBody MethodDeclaration +- addSource('/testC.dart', ''' +- class C { +- c1() {} +- var c2; +- static c3() {} +- static var c4;}'''); +- addTestSource(''' +- import "testC.dart"; +- class B extends C { +- b1() {} +- var b2; +- static b3() {} +- static var b4;} +- class A extends B { +- a1() {} +- var a2; +- static a3() {} +- static var a4; +- static a() {^}}'''); +- await computeSuggestions(); +- assertNotSuggested('a1'); +- assertNotSuggested('a2'); +- assertNotSuggested('a3'); +- assertNotSuggested('a4'); +- assertNotSuggested('b1'); +- assertNotSuggested('b2'); +- assertNotSuggested('b3'); +- assertNotSuggested('b4'); +- assertNotSuggested('c1'); +- assertNotSuggested('c2'); +- assertNotSuggested('c3'); +- assertNotSuggested('c4'); +- } +- +- test_MethodDeclaration_members() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('_a'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('bool'); +- } +- +- test_MethodDeclaration_parameters_named() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('b'); +- assertNotSuggested('int'); +- assertNotSuggested('_'); +- } +- +- test_MethodDeclaration_parameters_positional() async { +- // Block BlockFunctionBody MethodDeclaration +- addTestSource(''' +- foo() { } +- void bar() { } +- class A {Z a(X x, [int y=1]) {^}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('a'); +- assertNotSuggested('x'); +- assertNotSuggested('y'); +- assertNotSuggested('String'); +- } +- +- test_MethodDeclaration_returnType() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 {^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment() async { +- // ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 {/* */ ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment2() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 {/** */ ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodDeclaration_returnType_afterComment3() async { +- // MethodDeclaration ClassDeclaration CompilationUnit +- addSource('/testA.dart', ''' +- int T1; +- F1() { } +- typedef D1(); +- class C1 {C1(this.x) { } int x;}'''); +- addTestSource(''' +- import "testA.dart"; +- int T2; +- F2() { } +- typedef D2(); +- class C2 { +- /// some dartdoc +- ^ zoo(z) { } String name; }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('T1'); +- assertNotSuggested('F1'); +- assertNotSuggested('D1'); +- assertNotSuggested('C1'); +- assertNotSuggested('T2'); +- assertNotSuggested('F2'); +- assertNotSuggested('D2'); +- assertNotSuggested('C2'); +- assertNotSuggested('name'); +- } +- +- test_MethodInvocation_no_semicolon() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(r''' +- main() { } +- class I {X get f => new A();get _g => new A(); F $p; void $q(){}} +- class A implements I { +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {x.^ m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestGetter('f', 'X'); +- assertSuggestGetter('_g', null); +- assertSuggestField(r'$p', 'dynamic', relevance: DART_RELEVANCE_LOW); +- assertSuggestMethod(r'$q', 'I', 'void', relevance: DART_RELEVANCE_LOW); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_new_instance() async { +- addTestSource('import "dart:math"; class A {x() {new Random().^}}'); +- await computeSuggestions(); +- assertSuggestMethod('nextBool', 'Random', 'bool'); +- assertSuggestMethod('nextDouble', 'Random', 'double'); +- assertSuggestMethod('nextInt', 'Random', 'int'); +- assertNotSuggested('Random'); +- assertNotSuggested('Object'); +- assertNotSuggested('A'); +- } +- +- test_no_parameters_field() async { +- addTestSource(''' +-class C { +- int x; +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestField('x', 'int'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_no_parameters_getter() async { +- addTestSource(''' +-class C { +- int get x => null; +-} +-void main() {int y = new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestGetter('x', 'int'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_no_parameters_setter() async { +- addTestSource(''' +-class C { +- set x(int value) {}; +-} +-void main() {int y = new C().^}'''); +- await computeSuggestions(); +- CompletionSuggestion suggestion = assertSuggestSetter('x'); +- assertHasNoParameterInfo(suggestion); +- } +- +- test_only_instance() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addTestSource(''' +-class C { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {new C().^}'''); +- await computeSuggestions(); +- assertSuggestField('f1', 'int'); +- assertNotSuggested('f2'); +- assertSuggestMethod('m1', 'C', null); +- assertNotSuggested('m2'); +- } +- +- test_only_instance2() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource(''' +-class C { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {new C().^ print("something");}'''); +- await computeSuggestions(); +- assertSuggestField('f1', 'int'); +- assertNotSuggested('f2'); +- assertSuggestMethod('m1', 'C', null); +- assertNotSuggested('m2'); +- } +- +- test_only_static() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +-class C { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C.^}'''); +- await computeSuggestions(); +- assertNotSuggested('f1'); +- // Suggested by StaticMemberContributor +- assertNotSuggested('f2'); +- assertNotSuggested('m1'); +- assertNotSuggested('m2'); +- } +- +- test_only_static2() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource(''' +-class C { +- int f1; +- static int f2; +- m1() {} +- static m2() {} +-} +-void main() {C.^ print("something");}'''); +- await computeSuggestions(); +- assertNotSuggested('f1'); +- // Suggested by StaticMemberContributor +- assertNotSuggested('f2'); +- assertNotSuggested('m1'); +- assertNotSuggested('m2'); +- } +- +- test_param() async { +- addTestSource('foo(String x) {x.^}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_param_is() async { +- addTestSource('foo(x) {if (x is String) x.^}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_parameterName_excludeTypes() async { +- addTestSource('m(int ^) {}'); +- await computeSuggestions(); +- assertNotSuggested('int'); +- assertNotSuggested('bool'); +- } +- +- test_partFile_TypeName() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- library libA; +- import "testB.dart"; +- part "$testFile"; +- class A { } +- var m;'''); +- addTestSource(''' +- part of libA; +- class B { factory B.bar(int x) => null; } +- main() {new ^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('B.bar'); +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('A'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_partFile_TypeName2() async { +- // SimpleIdentifier TypeName ConstructorName +- addSource('/testB.dart', ''' +- lib B; +- int T1; +- F1() { } +- class X {X.c(); X._d(); z() {}}'''); +- addSource('/testA.dart', ''' +- part of libA; +- class B { }'''); +- addTestSource(''' +- library libA; +- import "testB.dart"; +- part "/testA.dart"; +- class A { A({String boo: 'hoo'}) { } } +- main() {new ^} +- var m;'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('A'); +- assertNotSuggested('Object'); +- assertNotSuggested('X.c'); +- assertNotSuggested('X._d'); +- assertNotSuggested('B'); +- assertNotSuggested('F1'); +- assertNotSuggested('T1'); +- assertNotSuggested('_d'); +- assertNotSuggested('z'); +- assertNotSuggested('m'); +- } +- +- test_PrefixedIdentifier_class_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block +- addSource('/testB.dart', ''' +- lib B; +- class I { +- static const scI = 'boo'; +- X get f => new A(); +- get _g => new A();} +- class B implements I { +- static const int scB = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- addTestSource(''' +- import "testB.dart"; +- class A extends B { +- static const String scA = 'foo'; +- w() { }} +- main() {A.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by StaticMemberContributor +- assertNotSuggested('scA'); +- assertNotSuggested('scB'); +- assertNotSuggested('scI'); +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('w'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_imported() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- static const int sc = 12; +- @deprecated var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- addTestSource(''' +- import "testB.dart"; +- main() {A a; a.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertSuggestField('b', null, isDeprecated: true); +- assertNotSuggested('_c'); +- assertSuggestGetter('d', 'X'); +- assertNotSuggested('_e'); +- assertSuggestGetter('f', 'X'); +- assertNotSuggested('_g'); +- assertSuggestSetter('s1'); +- assertNotSuggested('_s2'); +- assertSuggestMethod('m', 'A', null); +- assertNotSuggested('_n'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_class_local() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource(''' +- main() {A a; a.^} +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- static const int sc = 12; +- var b; X _c; +- X get d => new A();get _e => new A(); +- set s1(I x) {} set _s2(I x) {} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('sc'); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertSuggestGetter('d', 'X'); +- assertSuggestGetter('_e', null); +- assertSuggestGetter('f', 'X'); +- assertSuggestGetter('_g', null); +- assertSuggestSetter('s1'); +- assertSuggestSetter('_s2'); +- assertSuggestMethod('m', 'A', null); +- assertSuggestMethod('_n', 'A', 'I'); +- assertNotSuggested('a'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_library() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "testB.dart" as b; +- var T2; +- class A { } +- main() {b.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "testB.dart" as b; +- var T2; +- class A { } +- foo(b.^ f) {}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_library_typesOnly2() async { +- // SimpleIdentifier PrefixedIdentifier TypeName +- addSource('/testB.dart', ''' +- lib B; +- var T1; +- class X { } +- class Y { }'''); +- addTestSource(''' +- import "testB.dart" as b; +- var T2; +- class A { } +- foo(b.^) {}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Suggested by LibraryMemberContributor +- assertNotSuggested('X'); +- assertNotSuggested('Y'); +- assertNotSuggested('T1'); +- assertNotSuggested('T2'); +- assertNotSuggested('Object'); +- assertNotSuggested('b'); +- assertNotSuggested('A'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_parameter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testB.dart', ''' +- lib B; +- class _W {M y; var _z;} +- class X extends _W {} +- class M{}'''); +- addTestSource(''' +- import "testB.dart"; +- foo(X x) {x.^}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('y', 'M'); +- assertNotSuggested('_z'); +- assertNotSuggested('=='); +- } +- +- test_PrefixedIdentifier_prefix() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addSource('/testA.dart', ''' +- class A {static int bar = 10;} +- _B() {}'''); +- addTestSource(''' +- import "testA.dart"; +- class X {foo(){A^.bar}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('foo'); +- assertNotSuggested('bar'); +- assertNotSuggested('_B'); +- } +- +- test_PrefixedIdentifier_propertyAccess() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestGetter('isEmpty', 'bool'); +- assertSuggestMethod('compareTo', 'Comparable', 'int'); +- } +- +- test_PrefixedIdentifier_propertyAccess_newStmt() async { +- // PrefixedIdentifier ExpressionStatement Block BlockFunctionBody +- addTestSource('class A {String x; int get foo {x.^ int y = 0;}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestGetter('isEmpty', 'bool'); +- assertSuggestMethod('compareTo', 'Comparable', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_const() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('const String g = "hello"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_const_untyped() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('const g = "hello"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestMethod('toString', 'Object', 'String'); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_field() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g; f() {g.^ int y = 0;}}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_function() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g() => "one"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('typedef String g(); f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_getter() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String get g => "one"; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_typed() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {String g; g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_local_untyped() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f() {var g = "hello"; g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_method() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('class A {f(String g) {g.^ int y = 0;}}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_param2() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('f(String g) {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PrefixedIdentifier_trailingStmt_topLevelVar() async { +- // SimpleIdentifier PrefixedIdentifier ExpressionStatement +- addTestSource('String g; f() {g.^ int y = 0;}'); +- await computeSuggestions(); +- assertSuggestGetter('length', 'int'); +- } +- +- test_PropertyAccess_expression() async { +- // SimpleIdentifier MethodInvocation PropertyAccess ExpressionStatement +- addTestSource('class A {a() {"hello".to^String().length}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 8); +- assertSuggestGetter('length', 'int'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_PropertyAccess_noTarget() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('class C {foo(){.^}}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_noTarget2() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement +- addSource('/testAB.dart', 'class Foo { }'); +- addTestSource('main() {.^}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_PropertyAccess_selector() async { +- // SimpleIdentifier PropertyAccess ExpressionStatement Block +- addTestSource('class A {a() {"hello".length.^}}'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestGetter('isEven', 'bool'); +- assertNotSuggested('A'); +- assertNotSuggested('a'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_shadowing_field_over_field() => +- check_shadowing('int x;', 'int x;', true); +- +- test_shadowing_field_over_getter() => +- check_shadowing('int x;', 'int get x => null;', true); +- +- test_shadowing_field_over_method() => +- check_shadowing('int x;', 'void x() {}', true); +- +- test_shadowing_field_over_setter() => +- check_shadowing('int x;', 'set x(int value) {}', true); +- +- test_shadowing_getter_over_field() => +- check_shadowing('int get x => null;', 'int x;', false); +- +- test_shadowing_getter_over_getter() => +- check_shadowing('int get x => null;', 'int get x => null;', true); +- +- test_shadowing_getter_over_method() => +- check_shadowing('int get x => null;', 'void x() {}', true); +- +- test_shadowing_getter_over_setter() => +- check_shadowing('int get x => null;', 'set x(int value) {}', false); +- +- test_shadowing_method_over_field() => +- check_shadowing('void x() {}', 'int x;', true); +- +- test_shadowing_method_over_getter() => +- check_shadowing('void x() {}', 'int get x => null;', true); +- +- test_shadowing_method_over_method() => +- check_shadowing('void x() {}', 'void x() {}', true); +- +- test_shadowing_method_over_setter() => +- check_shadowing('void x() {}', 'set x(int value) {}', true); +- +- test_shadowing_mixin_order() async { +- addTestSource(''' +-class Base { +-} +-class Mixin1 { +- void f() {} +-} +-class Mixin2 { +- void f() {} +-} +-class Derived extends Base with Mixin1, Mixin2 { +-} +-void test(Derived d) { +- d.^ +-} +-'''); +- await computeSuggestions(); +- // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in +- // reverse order. The correct order is that Derived inherits from +- // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1", +- // which inherits from "Base". So the definition of f in Mixin2 should +- // shadow the definition in Mixin1. +- assertSuggestMethod('f', 'Mixin2', 'void'); +- } +- +- test_shadowing_mixin_over_superclass() async { +- addTestSource(''' +-class Base { +- void f() {} +-} +-class Mixin { +- void f() {} +-} +-class Derived extends Base with Mixin { +-} +-void test(Derived d) { +- d.^ +-} +-'''); +- await computeSuggestions(); +- assertSuggestMethod('f', 'Mixin', 'void'); +- } +- +- test_shadowing_setter_over_field() => +- check_shadowing('set x(int value) {}', 'int x;', false); +- +- test_shadowing_setter_over_getter() => +- check_shadowing('set x(int value) {}', 'int get x => null;', false); +- +- test_shadowing_setter_over_method() => +- check_shadowing('set x(int value) {}', 'void x() {}', true); +- +- test_shadowing_setter_over_setter() => +- check_shadowing('set x(int value) {}', 'set x(int value) {}', true); +- +- test_shadowing_superclass_over_interface() async { +- addTestSource(''' +-class Base { +- void f() {} +-} +-class Interface { +- void f() {} +-} +-class Derived extends Base implements Interface { +-} +-void test(Derived d) { +- d.^ +-} +-'''); +- await computeSuggestions(); +- assertSuggestMethod('f', 'Base', 'void'); +- } +- +- test_super() async { +- // SimpleIdentifier MethodInvocation ExpressionStatement +- addTestSource(''' +-class C3 { +- int fi3; +- static int fs3; +- m() {} +- mi3() {} +- static ms3() {} +-} +-class C2 { +- int fi2; +- static int fs2; +- m() {} +- mi2() {} +- static ms2() {} +-} +-class C1 extends C2 implements C3 { +- int fi1; +- static int fs1; +- m() {super.^} +- mi1() {} +- static ms1() {} +-}'''); +- await computeSuggestions(); +- assertNotSuggested('fi1'); +- assertNotSuggested('fs1'); +- assertNotSuggested('mi1'); +- assertNotSuggested('ms1'); +- assertSuggestField('fi2', 'int'); +- assertNotSuggested('fs2'); +- assertSuggestMethod('mi2', 'C2', null); +- assertNotSuggested('ms2'); +- assertSuggestMethod('m', 'C2', null, relevance: DART_RELEVANCE_HIGH); +- assertNotSuggested('fi3'); +- assertNotSuggested('fs3'); +- assertNotSuggested('mi3'); +- assertNotSuggested('ms3'); +- } +- +- test_SwitchStatement_c() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {c^}}}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_SwitchStatement_case() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}'); +- await computeSuggestions(); +- assertNotSuggested('A'); +- assertNotSuggested('g'); +- assertNotSuggested('t'); +- assertNotSuggested('String'); +- } +- +- test_SwitchStatement_empty() async { +- // SwitchStatement Block BlockFunctionBody MethodDeclaration +- addTestSource('class A {String g(int x) {switch(x) {^}}}'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_ThisExpression_block() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A() {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {this.^ m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertSuggestGetter('d', 'X'); +- assertSuggestGetter('_e', null); +- assertSuggestGetter('f', 'X'); +- assertSuggestGetter('_g', null); +- assertSuggestMethod('m', 'A', null); +- assertSuggestMethod('_n', 'A', 'I'); +- assertSuggestSetter('s1'); +- assertSuggestSetter('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor() async { +- // MethodInvocation ExpressionStatement Block +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A() {this.^} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestField('b', null); +- assertSuggestField('_c', 'X'); +- assertSuggestGetter('d', 'X'); +- assertSuggestGetter('_e', null); +- assertSuggestGetter('f', 'X'); +- assertSuggestGetter('_g', null); +- assertSuggestMethod('m', 'A', null); +- assertSuggestMethod('_n', 'A', 'I'); +- assertSuggestSetter('s1'); +- assertSuggestSetter('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.^) {} +- A.z() {} +- var b; X _c; static sb; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('sb'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param2() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.b^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param3() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.^b) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('b'); +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_ThisExpression_constructor_param4() async { +- // SimpleIdentifier FieldFormalParameter FormalParameterList +- addTestSource(''' +- main() { } +- class I {X get f => new A();get _g => new A();} +- class A implements I { +- A(this.b, this.^) {} +- A.z() {} +- var b; X _c; +- X get d => new A();get _e => new A(); +- // no semicolon between completion point and next statement +- set s1(I x) {} set _s2(I x) {m(null);} +- m(X x) {} I _n(X x) {}} +- class X{}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('b'); +- // Contributed by FieldFormalConstructorContributor +- assertNotSuggested('_c'); +- assertNotSuggested('d'); +- assertNotSuggested('_e'); +- assertNotSuggested('f'); +- assertNotSuggested('_g'); +- assertNotSuggested('m'); +- assertNotSuggested('_n'); +- assertNotSuggested('s1'); +- assertNotSuggested('_s2'); +- assertNotSuggested('z'); +- assertNotSuggested('I'); +- assertNotSuggested('A'); +- assertNotSuggested('X'); +- assertNotSuggested('Object'); +- assertNotSuggested('=='); +- } +- +- test_TopLevelVariableDeclaration_typed_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} B ^'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_TopLevelVariableDeclaration_untyped_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // TopLevelVariableDeclaration +- addTestSource('class A {} var ^'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_TypeArgumentList() async { +- // SimpleIdentifier BinaryExpression ExpressionStatement +- addSource('/testA.dart', ''' +- class C1 {int x;} +- F1() => 0; +- typedef String T1(int blat);'''); +- addTestSource(''' +- import "testA.dart";' +- class C2 {int x;} +- F2() => 0; +- typedef int T2(int blat); +- class C {} +- main() { C<^> c; }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('Object'); +- assertNotSuggested('C1'); +- assertNotSuggested('T1'); +- assertNotSuggested('C2'); +- assertNotSuggested('T2'); +- assertNotSuggested('F1'); +- assertNotSuggested('F2'); +- } +- +- test_TypeArgumentList2() async { +- // TypeName TypeArgumentList TypeName +- addSource('/testA.dart', ''' +- class C1 {int x;} +- F1() => 0; +- typedef String T1(int blat);'''); +- addTestSource(''' +- import "testA.dart";' +- class C2 {int x;} +- F2() => 0; +- typedef int T2(int blat); +- class C {} +- main() { C c; }'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertNotSuggested('C1'); +- assertNotSuggested('C2'); +- } +- +- test_VariableDeclaration_name() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement Block +- addSource('/testB.dart', ''' +- lib B; +- foo() { } +- class _B { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- class Y {Y.c(); Y._d(); z() {}} +- main() {var ^}'''); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_VariableDeclarationList_final() async { +- // VariableDeclarationList VariableDeclarationStatement Block +- addTestSource('main() {final ^} class C { }'); +- await computeSuggestions(); +- assertNotSuggested('Object'); +- assertNotSuggested('C'); +- assertNotSuggested('=='); +- } +- +- test_VariableDeclarationStatement_RHS() async { +- // SimpleIdentifier VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +- lib B; +- foo() { } +- class _B { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- class Y {Y.c(); Y._d(); z() {}} +- class C {bar(){var f; {var x;} var e = ^}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('_B'); +- assertNotSuggested('Y'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +- +- test_VariableDeclarationStatement_RHS_missing_semicolon() async { +- // VariableDeclaration VariableDeclarationList +- // VariableDeclarationStatement +- addSource('/testB.dart', ''' +- lib B; +- foo1() { } +- void bar1() { } +- class _B { } +- class X {X.c(); X._d(); z() {}}'''); +- addTestSource(''' +- import "testB.dart"; +- foo2() { } +- void bar2() { } +- class Y {Y.c(); Y._d(); z() {}} +- class C {bar(){var f; {var x;} var e = ^ var g}}'''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('X'); +- assertNotSuggested('foo1'); +- assertNotSuggested('bar1'); +- assertNotSuggested('foo2'); +- assertNotSuggested('bar2'); +- assertNotSuggested('_B'); +- assertNotSuggested('Y'); +- assertNotSuggested('C'); +- assertNotSuggested('f'); +- assertNotSuggested('x'); +- assertNotSuggested('e'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart +deleted file mode 100644 +index 008498450d6..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart ++++ /dev/null +@@ -1,682 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:path/path.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(UriContributorTest); +- defineReflectiveTests(UriContributorWindowsTest); +- }); +-} +- +-@reflectiveTest +-class UriContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new UriContributor(); +- } +- +- test_after_import() async { +- addTestSource('import "p"^'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_after_import_raw() async { +- addTestSource('import r"p"^'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_before_import() async { +- addTestSource('import ^"p"'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_before_import_raw() async { +- addTestSource('import ^r"p"'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_before_import_raw2() async { +- addTestSource('import r^"p"'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_export_package2() async { +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('export "package:foo/baz/^" import'); +- await computeSuggestions(); +- assertSuggest('package:foo/baz/too.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_export_package2_off() async { +- try { +- UriContributor.suggestFilePaths = false; +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('export "package:foo/baz/^" import'); +- await computeSuggestions(); +- assertNotSuggested('package:foo/baz/too.dart'); +- } finally { +- UriContributor.suggestFilePaths = true; +- } +- } +- +- test_import() async { +- addTestSource('import "^"'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import2() async { +- addTestSource('import "^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import3() async { +- addTestSource('import "^ import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 7); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_dart() async { +- addTestSource('import "d^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('dart:core', +- csKind: CompletionSuggestionKind.IMPORT, relevance: DART_RELEVANCE_LOW); +- assertNotSuggested('dart:_internal'); +- assertSuggest('dart:async', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('dart:math', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_dart2() async { +- addTestSource('import "dart:async"; import "d^"'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('dart:core', +- csKind: CompletionSuggestionKind.IMPORT, relevance: DART_RELEVANCE_LOW); +- assertNotSuggested('dart:_internal'); +- assertSuggest('dart:async', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('dart:math', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_file() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('import "^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file2() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('import "..^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 2); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file2_off() async { +- try { +- UriContributor.suggestFilePaths = false; +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('import "..^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 2); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } finally { +- UriContributor.suggestFilePaths = true; +- } +- } +- +- test_import_file_child() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('import "foo/^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 4); +- expect(replacementLength, 4); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file_outside_lib() async { +- testFile = '/proj/lib/completion.dart'; +- addSource('/proj/lib/other.dart', 'library other;'); +- addSource('/proj/lib/foo/bar.dart', 'library bar;'); +- addSource('/proj/blat.dart', 'library blat;'); +- addSource('/proj/bin/boo.dart', 'library boo;'); +- addTestSource('import "../^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../bin'); +- assertNotSuggested('../bin/'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file_parent() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addSource('/proj2/boo.dart', 'library boo;'); +- addTestSource('import "../^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('../proj2/', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_file_parent2() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('import "../b^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 4); +- expect(replacementLength, 4); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_package() async { +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('import "p^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:foo/foo.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:foo/baz/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('package:foo/baz/too.dart'); +- assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:bar/bar.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_package2() async { +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('import "package:foo/baz/^" import'); +- await computeSuggestions(); +- assertSuggest('package:foo/baz/too.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_package2_off() async { +- try { +- UriContributor.suggestFilePaths = false; +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('import "package:foo/baz/^" import'); +- await computeSuggestions(); +- assertNotSuggested('package:foo/baz/too.dart'); +- } finally { +- UriContributor.suggestFilePaths = true; +- } +- } +- +- test_import_package2_raw() async { +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('import r"package:foo/baz/^" import'); +- await computeSuggestions(); +- assertSuggest('package:foo/baz/too.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_package2_with_trailing() async { +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('import "package:foo/baz/^.dart" import'); +- await computeSuggestions(); +- assertSuggest('package:foo/baz/too.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- expect(replacementOffset, completionOffset - 16); +- expect(replacementLength, 5 + 16); +- } +- +- test_import_package_missing_lib() async { +- var pkgSrc = addPackageSource('bar', 'bar.dart', 'library bar;'); +- provider.deleteFolder(dirname(pkgSrc.fullName)); +- addTestSource('import "p^" class'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('package:bar/bar.dart'); +- } +- +- test_import_package_raw() async { +- addPackageSource('foo', 'foo.dart', 'library foo;'); +- addPackageSource('foo', 'baz/too.dart', 'library too;'); +- addPackageSource('bar', 'bar.dart', 'library bar;'); +- addTestSource('import r"p^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:foo/foo.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:foo/baz/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('package:foo/baz/too.dart'); +- assertSuggest('package:bar/', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:bar/bar.dart', +- csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_raw() async { +- addTestSource('import r"^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_without_any_quotes() async { +- addTestSource('import ^ import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_import_without_any_quotes_eof() async { +- addTestSource('import ^'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNoSuggestions(); +- } +- +- test_import_without_closing_quote_eof() async { +- addTestSource('import "^'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_without_closing_quote_eof2() async { +- addTestSource('import "^d'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 1); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_without_closing_quote_eof3() async { +- addTestSource('import "d^'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_without_closing_quote_eof4() async { +- addTestSource('import "d^"'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 1); +- expect(replacementLength, 1); +- assertSuggest('dart:', csKind: CompletionSuggestionKind.IMPORT); +- assertSuggest('package:', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_outside_import() async { +- addTestSource('import ^"d" import'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_outside_import2() async { +- addTestSource('import "d"^ import'); +- await computeSuggestions(); +- assertNoSuggestions(); +- } +- +- test_part_file() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('library x; part "^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_part_file2() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('library x; part "..^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 2); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_part_file_child() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('library x; part "foo/^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 4); +- expect(replacementLength, 4); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('../blat.dart'); +- } +- +- test_part_file_parent() async { +- testFile = '/proj/completion.dart'; +- addSource('/proj/other.dart', 'library other;'); +- addSource('/proj/foo/bar.dart', 'library bar;'); +- addSource('/blat.dart', 'library blat;'); +- addTestSource('library x; part "../^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT); +- } +-} +- +-@reflectiveTest +-class UriContributorWindowsTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new UriContributor(); +- } +- +- @override +- void setupResourceProvider() { +- provider = new _TestWinResourceProvider(); +- } +- +- test_import_file() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('import "^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file2() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('import "..^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 2); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file_child() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('import "foo/^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 4); +- expect(replacementLength, 4); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('../blat.dart'); +- } +- +- test_import_file_parent() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('import "../^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_import_file_parent2() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('import "../b^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 4); +- expect(replacementLength, 4); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT); +- } +- +- test_part_file() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('library x; part "^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_part_file2() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('library x; part "..^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 2); +- expect(replacementLength, 2); +- assertNotSuggested('completion.dart'); +- assertSuggest('other.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo'); +- assertSuggest('foo/', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('foo/bar.dart'); +- assertNotSuggested('../blat.dart'); +- } +- +- test_part_file_child() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('library x; part "foo/^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 4); +- expect(replacementLength, 4); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertSuggest('foo/bar.dart', csKind: CompletionSuggestionKind.IMPORT); +- assertNotSuggested('../blat.dart'); +- } +- +- test_part_file_parent() async { +- testFile = '\\proj\\completion.dart'; +- addSource('\\proj\\other.dart', 'library other;'); +- addSource('\\proj\\foo\\bar.dart', 'library bar;'); +- addSource('\\blat.dart', 'library blat;'); +- addTestSource('library x; part "../^" import'); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertNotSuggested('completion.dart'); +- assertNotSuggested('other.dart'); +- assertNotSuggested('foo'); +- assertNotSuggested('foo/'); +- assertNotSuggested('foo/bar.dart'); +- assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT); +- } +-} +- +-class _TestWinResourceProvider extends MemoryResourceProvider { +- @override +- Context get pathContext => windows; +-} +diff --git a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart +deleted file mode 100644 +index f1f2c23828e..00000000000 +--- a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart ++++ /dev/null +@@ -1,244 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'; +-import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion_contributor_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(VariableNameContributorTest); +- }); +-} +- +-@reflectiveTest +-class VariableNameContributorTest extends DartCompletionContributorTest { +- @override +- DartCompletionContributor createContributor() { +- return new VariableNameContributor(); +- } +- +- test_ExpressionStatement_dont_suggest_type() async { +- addTestSource(''' +- f() { a ^ } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- } +- +- test_ExpressionStatement_dont_suggest_type_semicolon() async { +- addTestSource(''' +- f() { a ^; } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- } +- +- test_ExpressionStatement_long() async { +- addTestSource(''' +- f() { AbstractCrazyNonsenseClassName ^ } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_ExpressionStatement_long_semicolon() async { +- addTestSource(''' +- f() { AbstractCrazyNonsenseClassName ^; } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_ExpressionStatement_prefixed() async { +- addTestSource(''' +- f() { prefix.AbstractCrazyNonsenseClassName ^ } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_ExpressionStatement_prefixed_semicolon() async { +- addTestSource(''' +- f() { prefix.AbstractCrazyNonsenseClassName ^; } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_ExpressionStatement_short() async { +- addTestSource(''' +- f() { A ^ } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('a'); +- } +- +- test_ExpressionStatement_short_semicolon() async { +- addTestSource(''' +- f() { A ^; } +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('a'); +- } +- +- test_TopLevelVariableDeclaration_dont_suggest_type() async { +- addTestSource(''' +- a ^ +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- } +- +- test_TopLevelVariableDeclaration_dont_suggest_type_semicolon() async { +- addTestSource(''' +- a ^; +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertNotSuggested('a'); +- } +- +- test_TopLevelVariableDeclaration_long() async { +- addTestSource(''' +- AbstractCrazyNonsenseClassName ^ +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_TopLevelVariableDeclaration_long_semicolon() async { +- addTestSource(''' +- AbstractCrazyNonsenseClassName ^; +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_TopLevelVariableDeclaration_partial() async { +- addTestSource(''' +- AbstractCrazyNonsenseClassName abs^ +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_TopLevelVariableDeclaration_partial_semicolon() async { +- addTestSource(''' +- AbstractCrazyNonsenseClassName abs^ +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset - 3); +- expect(replacementLength, 3); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_TopLevelVariableDeclaration_prefixed() async { +- addTestSource(''' +- prefix.AbstractCrazyNonsenseClassName ^ +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_TopLevelVariableDeclaration_prefixed_semicolon() async { +- addTestSource(''' +- prefix.AbstractCrazyNonsenseClassName ^; +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('abstractCrazyNonsenseClassName'); +- assertSuggestName('crazyNonsenseClassName'); +- assertSuggestName('nonsenseClassName'); +- assertSuggestName('className'); +- assertSuggestName('name'); +- } +- +- test_TopLevelVariableDeclaration_short() async { +- addTestSource(''' +- A ^ +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('a'); +- } +- +- test_TopLevelVariableDeclaration_short_semicolon() async { +- addTestSource(''' +- A ^; +- '''); +- await computeSuggestions(); +- expect(replacementOffset, completionOffset); +- expect(replacementLength, 0); +- assertSuggestName('a'); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart +deleted file mode 100644 +index 244b2b270e5..00000000000 +--- a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart ++++ /dev/null +@@ -1,709 +0,0 @@ +-// 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 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/services/completion/postfix/postfix_completion.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(_AssertTest); +- defineReflectiveTests(_ForTest); +- defineReflectiveTests(_NegateTest); +- defineReflectiveTests(_IfTest); +- defineReflectiveTests(_NotNullTest); +- defineReflectiveTests(_ParenTest); +- defineReflectiveTests(_ReturnTest); +- defineReflectiveTests(_SwitchTest); +- defineReflectiveTests(_TryTest); +- defineReflectiveTests(_WhileTest); +- }); +-} +- +-class PostfixCompletionTest extends AbstractSingleUnitTest { +- SourceChange change; +- +- void _assertHasChange(String message, String expectedCode, [Function cmp]) { +- if (change.message == message) { +- if (!change.edits.isEmpty) { +- String resultCode = +- SourceEdit.applySequence(testCode, change.edits[0].edits); +- expect(resultCode, expectedCode.replaceAll('/*caret*/', '')); +- if (cmp != null) { +- int offset = cmp(resultCode); +- expect(change.selection.offset, offset); +- } +- } else { +- if (cmp != null) { +- int offset = cmp(testCode); +- expect(change.selection.offset, offset); +- } +- } +- return; +- } +- fail("Expected to find |$message| but got: " + change.message); +- } +- +- _computeCompletion(int offset, String key) async { +- driver.changeFile(testFile); +- AnalysisResult result = await driver.getResult(testFile); +- PostfixCompletionContext context = new PostfixCompletionContext( +- testFile, +- result.lineInfo, +- offset, +- key, +- result.driver, +- testUnit, +- testUnitElement, +- result.errors); +- PostfixCompletionProcessor processor = +- new PostfixCompletionProcessor(context); +- bool isApplicable = await processor.isApplicable(); +- if (!isApplicable) { +- fail("Postfix completion not applicable at given location"); +- } +- PostfixCompletion completion = await processor.compute(); +- change = completion.change; +- } +- +- _prepareCompletion(String key, String sourceCode) async { +- testCode = sourceCode.replaceAll('////', ''); +- int offset = findOffset(key); +- testCode = testCode.replaceFirst(key, '', offset); +- await _prepareCompletionAt(offset, key, testCode); +- } +- +- _prepareCompletionAt(int offset, String key, String sourceCode) async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(sourceCode); +- await _computeCompletion(offset, key); +- } +-} +- +-@reflectiveTest +-class _AssertTest extends PostfixCompletionTest { +- test_assert() async { +- await _prepareCompletion('.assert', ''' +-f(bool expr) { +- expr.assert +-} +-'''); +- _assertHasChange('Expand .assert', ''' +-f(bool expr) { +- assert(expr); +-} +-'''); +- } +- +- test_assertFunc() async { +- await _prepareCompletion('.assert', ''' +-f() { +- () => true.assert +-} +-'''); +- _assertHasChange('Expand .assert', ''' +-f() { +- assert(() => true); +-} +-'''); +- } +- +- @failingTest +- test_assertFunc_invalid() async { +- await _prepareCompletion('.assert', ''' +-f() { +- () => null.assert +-} +-'''); +- } +- +- test_assertFuncCmp() async { +- await _prepareCompletion('.assert', ''' +-f(int x, int y) { +- () => x + 3 > y + 4.assert +-} +-'''); +- _assertHasChange('Expand .assert', ''' +-f(int x, int y) { +- assert(() => x + 3 > y + 4); +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _ForTest extends PostfixCompletionTest { +- @failingTest +- test_for_invalid() async { +- await _prepareCompletion('.for', ''' +-f() { +- {}.for +-} +-'''); +- } +- +- test_forEmptyDynamic() async { +- await _prepareCompletion('.for', ''' +-f() { +- [].for +-} +-'''); +- _assertHasChange('Expand .for', ''' +-f() { +- for (var value in []) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_forEmptyString() async { +- await _prepareCompletion('.for', ''' +-f() { +- [].for +-} +-'''); +- _assertHasChange('Expand .for', ''' +-f() { +- for (var value in []) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_fori() async { +- await _prepareCompletion('.fori', ''' +-f() { +- 100.fori +-} +-'''); +- _assertHasChange('Expand .fori', ''' +-f() { +- for (int i = 0; i < 100; i++) { +- /*caret*/ +- } +-} +-'''); +- } +- +- @failingTest +- test_fori_invalid() async { +- await _prepareCompletion('.fori', ''' +-f() { +- [].fori +-} +-'''); +- } +- +- test_forIntList() async { +- await _prepareCompletion('.for', ''' +-f() { +- [1,2,3].for +-} +-'''); +- _assertHasChange('Expand .for', ''' +-f() { +- for (var value in [1,2,3]) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_foriVar() async { +- await _prepareCompletion('.fori', ''' +-f() { +- var n = 100; +- n.fori +-} +-'''); +- _assertHasChange('Expand .fori', ''' +-f() { +- var n = 100; +- for (int i = 0; i < n; i++) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_iterList() async { +- await _prepareCompletion('.iter', ''' +-f() { +- [1,2,3].iter +-} +-'''); +- _assertHasChange('Expand .iter', ''' +-f() { +- for (var value in [1,2,3]) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_iterName() async { +- await _prepareCompletion('.iter', ''' +-f() { +- var value = [1,2,3]; +- value.iter +-} +-'''); +- _assertHasChange('Expand .iter', ''' +-f() { +- var value = [1,2,3]; +- for (var value1 in value) { +- /*caret*/ +- } +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _IfTest extends PostfixCompletionTest { +- test_Else() async { +- await _prepareCompletion('.else', ''' +-f(bool val) { +- val.else +-} +-'''); +- _assertHasChange('Expand .else', ''' +-f(bool val) { +- if (!val) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_if() async { +- await _prepareCompletion('.if', ''' +-f() { +- 3 < 4.if +-} +-'''); +- _assertHasChange('Expand .if', ''' +-f() { +- if (3 < 4) { +- /*caret*/ +- } +-} +-'''); +- } +- +- @failingTest +- test_if_invalid() async { +- await _prepareCompletion('.if', ''' +-f(List expr) { +- expr.if +-} +-'''); +- } +- +- test_ifDynamic() async { +- await _prepareCompletion('.if', ''' +-f(expr) { +- expr.if +-} +-'''); +- _assertHasChange('Expand .if', ''' +-f(expr) { +- if (expr) { +- /*caret*/ +- } +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _NegateTest extends PostfixCompletionTest { +- test_negate() async { +- await _prepareCompletion('.not', ''' +-f(expr) { +- if (expr.not) +-} +-'''); +- _assertHasChange('Expand .not', ''' +-f(expr) { +- if (!expr) +-} +-'''); +- } +- +- @failingTest +- test_negate_invalid() async { +- await _prepareCompletion('.not', ''' +-f(int expr) { +- if (expr.not) +-} +-'''); +- } +- +- test_negateCascade() async { +- await _prepareCompletion('.not', ''' +-f(expr) { +- if (expr..a..b..c.not) +-} +-'''); +- _assertHasChange('Expand .not', ''' +-f(expr) { +- if (!expr..a..b..c) +-} +-'''); +- } +- +- test_negateExpr() async { +- await _prepareCompletion('.not', ''' +-f(int i, int j) { +- if (i + 3 < j - 4.not) +-} +-'''); +- _assertHasChange('Expand .not', ''' +-f(int i, int j) { +- if (i + 3 >= j - 4) +-} +-'''); +- } +- +- test_negateProperty() async { +- await _prepareCompletion('.not', ''' +-f(expr) { +- if (expr.a.b.c.not) +-} +-'''); +- _assertHasChange('Expand .not', ''' +-f(expr) { +- if (!expr.a.b.c) +-} +-'''); +- } +- +- test_notFalse() async { +- await _prepareCompletion('!', ''' +-f() { +- if (false!) +-} +-'''); +- _assertHasChange('Expand !', ''' +-f() { +- if (true) +-} +-'''); +- } +- +- test_notFunc() async { +- await _prepareCompletion('.not', ''' +-bool f() { +- if (f().not) +-} +-'''); +- _assertHasChange('Expand .not', ''' +-bool f() { +- if (!f()) +-} +-'''); +- } +- +- test_notTrue() async { +- await _prepareCompletion('.not', ''' +-f() { +- if (true.not) +-} +-'''); +- _assertHasChange('Expand .not', ''' +-f() { +- if (false) +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _NotNullTest extends PostfixCompletionTest { +- test_nn() async { +- await _prepareCompletion('.nn', ''' +-f(expr) { +- var list = [1,2,3]; +- list.nn +-} +-'''); +- _assertHasChange('Expand .nn', ''' +-f(expr) { +- var list = [1,2,3]; +- if (list != null) { +- /*caret*/ +- } +-} +-'''); +- } +- +- @failingTest +- test_nn_invalid() async { +- await _prepareCompletion('.nn', ''' +-f(expr) { +- var list = [1,2,3]; +-}.nn +-'''); +- } +- +- test_nnDynamic() async { +- await _prepareCompletion('.nn', ''' +-f(expr) { +- expr.nn +-} +-'''); +- _assertHasChange('Expand .nn', ''' +-f(expr) { +- if (expr != null) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_notnull() async { +- await _prepareCompletion('.notnull', ''' +-f(expr) { +- var list = [1,2,3]; +- list.notnull +-} +-'''); +- _assertHasChange('Expand .notnull', ''' +-f(expr) { +- var list = [1,2,3]; +- if (list != null) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_null() async { +- await _prepareCompletion('.null', ''' +-f(expr) { +- var list = [1,2,3]; +- list.null +-} +-'''); +- _assertHasChange('Expand .null', ''' +-f(expr) { +- var list = [1,2,3]; +- if (list == null) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_nullnn() async { +- await _prepareCompletion('.nn', ''' +-f() { +- null.nn +-} +-'''); +- _assertHasChange('Expand .nn', ''' +-f() { +- if (false) { +- /*caret*/ +- } +-} +-'''); +- } +- +- test_nullnull() async { +- await _prepareCompletion('.null', ''' +-f() { +- null.null +-} +-'''); +- _assertHasChange('Expand .null', ''' +-f() { +- if (true) { +- /*caret*/ +- } +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _ParenTest extends PostfixCompletionTest { +- test_paren() async { +- await _prepareCompletion('.par', ''' +-f(expr) { +- expr.par +-} +-'''); +- _assertHasChange('Expand .par', ''' +-f(expr) { +- (expr) +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _ReturnTest extends PostfixCompletionTest { +- test_return() async { +- await _prepareCompletion('.return', ''' +-f(expr) { +- expr.return +-} +-'''); +- _assertHasChange('Expand .return', ''' +-f(expr) { +- return expr; +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _SwitchTest extends PostfixCompletionTest { +- test_return() async { +- await _prepareCompletion('.switch', ''' +-f(expr) { +- expr.switch +-} +-'''); +- _assertHasChange('Expand .switch', ''' +-f(expr) { +- switch (expr) { +- /*caret*/ +- } +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _TryTest extends PostfixCompletionTest { +- test_try() async { +- await _prepareCompletion('.try', ''' +-f() { +- var x = 1.try +-} +-'''); +- _assertHasChange('Expand .try', ''' +-f() { +- try { +- var x = 1/*caret*/ +- } catch (e, s) { +- print(s); +- } +-} +-'''); +- } +- +- @failingTest +- test_try_invalid() async { +- // The semicolon is fine; this fails because of the do-statement. +- await _prepareCompletion('.try', ''' +-f() { +- do {} while (true);.try +-} +-'''); +- } +- +- test_tryMultiline() async { +- await _prepareCompletion('.try', ''' +-f(arg) { +- arg +- ..first +- ..second +- ..third +- ..fourth.try +-} +-'''); +- _assertHasChange('Expand .try', ''' +-f(arg) { +- try { +- arg +- ..first +- ..second +- ..third +- ..fourth/*caret*/ +- } catch (e, s) { +- print(s); +- } +-} +-'''); +- } +- +- test_tryon() async { +- await _prepareCompletion('.tryon', ''' +-f() { +- var x = 1.tryon +-} +-'''); +- _assertHasChange('Expand .tryon', ''' +-f() { +- try { +- var x = 1/*caret*/ +- } on Exception catch (e, s) { +- print(s); +- } +-} +-'''); +- } +- +- test_tryonThrowStatement() async { +- await _prepareCompletion('.tryon', ''' +-f() { +- throw 'error';.tryon +-} +-'''); +- _assertHasChange('Expand .tryon', ''' +-f() { +- try { +- throw 'error';/*caret*/ +- } on String catch (e, s) { +- print(s); +- } +-} +-'''); +- } +- +- test_tryonThrowString() async { +- await _prepareCompletion('.tryon', ''' +-f() { +- throw 'error'.tryon +-} +-'''); +- _assertHasChange('Expand .tryon', ''' +-f() { +- try { +- throw 'error'/*caret*/ +- } on String catch (e, s) { +- print(s); +- } +-} +-'''); +- } +-} +- +-@reflectiveTest +-class _WhileTest extends PostfixCompletionTest { +- test_while() async { +- await _prepareCompletion('.while', ''' +-f(expr) { +- expr.while +-} +-'''); +- _assertHasChange('Expand .while', ''' +-f(expr) { +- while (expr) { +- /*caret*/ +- } +-} +-'''); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/postfix/test_all.dart b/pkg/analysis_server/test/services/completion/postfix/test_all.dart +deleted file mode 100644 +index a2a43c5fecd..00000000000 +--- a/pkg/analysis_server/test/services/completion/postfix/test_all.dart ++++ /dev/null +@@ -1,13 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'postfix_completion_test.dart' as postfix_completion_test; +- +-main() { +- defineReflectiveSuite(() { +- postfix_completion_test.main(); +- }, name: 'postfix'); +-} +diff --git a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart +deleted file mode 100644 +index c3ddced2138..00000000000 +--- a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart ++++ /dev/null +@@ -1,1912 +0,0 @@ +-// 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 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analysis_server/src/services/completion/statement/statement_completion.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(_DeclarationCompletionTest); +- defineReflectiveTests(_ControlFlowCompletionTest); +- defineReflectiveTests(_DoCompletionTest); +- defineReflectiveTests(_ExpressionCompletionTest); +- defineReflectiveTests(_ForCompletionTest); +- defineReflectiveTests(_ForEachCompletionTest); +- defineReflectiveTests(_IfCompletionTest); +- defineReflectiveTests(_SimpleCompletionTest); +- defineReflectiveTests(_SwitchCompletionTest); +- defineReflectiveTests(_TryCompletionTest); +- defineReflectiveTests(_WhileCompletionTest); +- }); +-} +- +-class StatementCompletionTest extends AbstractSingleUnitTest { +- SourceChange change; +- +- int _after(String source, String match) => +- source.indexOf(match) + match.length; +- +- int _afterLast(String source, String match) => +- source.lastIndexOf(match) + match.length; +- +- void _assertHasChange(String message, String expectedCode, [Function cmp]) { +- if (change.message == message) { +- if (!change.edits.isEmpty) { +- String resultCode = +- SourceEdit.applySequence(testCode, change.edits[0].edits); +- expect(resultCode, expectedCode.replaceAll('////', '')); +- if (cmp != null) { +- int offset = cmp(resultCode); +- expect(change.selection.offset, offset); +- } +- } else { +- expect(testCode, expectedCode.replaceAll('////', '')); +- if (cmp != null) { +- int offset = cmp(testCode); +- expect(change.selection.offset, offset); +- } +- } +- return; +- } +- fail("Expected to find |$message| but got: " + change.message); +- } +- +- _computeCompletion(int offset) async { +- driver.changeFile(testFile); +- AnalysisResult result = await driver.getResult(testFile); +- StatementCompletionContext context = new StatementCompletionContext( +- testFile, +- result.lineInfo, +- offset, +- testUnit, +- testUnitElement, +- result.errors); +- StatementCompletionProcessor processor = +- new StatementCompletionProcessor(context); +- StatementCompletion completion = await processor.compute(); +- change = completion.change; +- } +- +- _prepareCompletion(String search, String sourceCode, +- {bool atStart: false, bool atEnd: false, int delta: 0}) async { +- testCode = sourceCode.replaceAll('////', ''); +- int offset = findOffset(search); +- if (atStart) { +- delta = 0; +- } else if (atEnd) { +- delta = search.length; +- } +- await _prepareCompletionAt(offset + delta, testCode); +- } +- +- _prepareCompletionAt(int offset, String sourceCode) async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(sourceCode); +- await _computeCompletion(offset); +- } +-} +- +-@reflectiveTest +-class _ControlFlowCompletionTest extends StatementCompletionTest { +- test_doReturnExprLineComment() async { +- await _prepareCompletion( +- 'return 3', +- ''' +-ex(e) { +- do { +- return 3// +- } while (true); +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- do { +- return 3;// +- } while (true); +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_doReturnUnterminated() async { +- await _prepareCompletion( +- 'return', +- ''' +-ex(e) { +- do { +- return +- } while (true); +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- do { +- return; +- } while (true); +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_forEachReturn() async { +- await _prepareCompletion( +- 'return;', +- ''' +-ex(e) { +- for (var x in e) { +- return; +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- for (var x in e) { +- return; +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_forThrowUnterminated() async { +- await _prepareCompletion( +- 'throw e', +- ''' +-ex(e) { +- for (int i = 0; i < 3; i++) { +- throw e +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- for (int i = 0; i < 3; i++) { +- throw e; +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_ifNoBlock() async { +- await _prepareCompletion( +- 'return', +- ''' +-ex(e) { +- if (true) return 0 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-ex(e) { +- if (true) return 0; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_ifThrow() async { +- await _prepareCompletion( +- 'throw e;', +- ''' +-ex(e) { +- if (true) { +- throw e; +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- if (true) { +- throw e; +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_ifThrowUnterminated() async { +- await _prepareCompletion( +- 'throw e', +- ''' +-ex(e) { +- if (true) { +- throw e +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- if (true) { +- throw e; +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_whileReturnExpr() async { +- await _prepareCompletion( +- '+ 4', +- ''' +-ex(e) { +- while (true) { +- return 3 + 4 +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-ex(e) { +- while (true) { +- return 3 + 4; +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _DeclarationCompletionTest extends StatementCompletionTest { +- test_classNameNoBody() async { +- await _prepareCompletion( +- 'Sample', +- ''' +-class Sample +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete class declaration', +- ''' +-class Sample { +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_extendsNoBody() async { +- await _prepareCompletion( +- 'Sample', +- ''' +-class Sample extends Object +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete class declaration', +- ''' +-class Sample extends Object { +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_functionDeclNoBody() async { +- await _prepareCompletion( +- 'source()', +- ''' +-String source() +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete function declaration', +- ''' +-String source() { +- //// +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_functionDeclNoParen() async { +- await _prepareCompletion( +- 'source(', +- ''' +-String source( +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete function declaration', +- ''' +-String source() { +- //// +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_implementsNoBody() async { +- await _prepareCompletion( +- 'Sample', +- ''' +-class Interface {} +-class Sample implements Interface +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete class declaration', +- ''' +-class Interface {} +-class Sample implements Interface { +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_methodDeclNoBody() async { +- await _prepareCompletion( +- 'source()', +- ''' +-class Sample { +- String source() +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete function declaration', +- ''' +-class Sample { +- String source() { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_methodDeclNoParen() async { +- await _prepareCompletion( +- 'source(', +- ''' +-class Sample { +- String source( +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete function declaration', +- ''' +-class Sample { +- String source() { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_variableDeclNoBody() async { +- await _prepareCompletion( +- 'source', +- ''' +-String source +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete variable declaration', +- ''' +-String source; +-//// +-''', +- (s) => _after(s, ';\n')); +- } +- +- test_withNoBody() async { +- await _prepareCompletion( +- 'Sample', +- ''' +-class M {} +-class Sample extends Object with M +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete class declaration', +- ''' +-class M {} +-class Sample extends Object with M { +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _DoCompletionTest extends StatementCompletionTest { +- test_emptyCondition() async { +- await _prepareCompletion( +- 'while ()', +- ''' +-main() { +- do { +- } while () +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete do-statement', +- ''' +-main() { +- do { +- } while (); +-} +-''', +- (s) => _after(s, 'while (')); +- } +- +- test_keywordOnly() async { +- await _prepareCompletion( +- 'do', +- ''' +-main() { +- do //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete do-statement', +- ''' +-main() { +- do { +- //// +- } while (); +-} +-''', +- (s) => _after(s, 'while (')); +- } +- +- test_keywordStatement() async { +- await _prepareCompletion( +- 'do', +- ''' +-main() { +- do //// +- return; +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete do-statement', +- ''' +-main() { +- do { +- //// +- } while (); +- return; +-} +-''', +- (s) => _after(s, 'while (')); +- } +- +- test_noBody() async { +- await _prepareCompletion( +- 'do', +- ''' +-main() { +- do; +- while +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete do-statement', +- ''' +-main() { +- do { +- //// +- } while (); +-} +-''', +- (s) => _after(s, 'while (')); +- } +- +- test_noCondition() async { +- await _prepareCompletion( +- 'while', +- ''' +-main() { +- do { +- } while +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete do-statement', +- ''' +-main() { +- do { +- } while (); +-} +-''', +- (s) => _after(s, 'while (')); +- } +- +- test_noWhile() async { +- await _prepareCompletion( +- '}', +- ''' +-main() { +- do { +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete do-statement', +- ''' +-main() { +- do { +- } while (); +-} +-''', +- (s) => _after(s, 'while (')); +- } +-} +- +-@reflectiveTest +-class _ExpressionCompletionTest extends StatementCompletionTest { +- test_listAssign() async { +- await _prepareCompletion( +- '= ', +- ''' +-main() { +- var x = [1, 2, 3 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- var x = [1, 2, 3]; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_listAssignMultiLine() async { +- // The indent of the final line is incorrect. +- await _prepareCompletion( +- '3', +- ''' +-main() { +- var x = [ +- 1, +- 2, +- 3 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- var x = [ +- 1, +- 2, +- 3, +- ]; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- @failingTest +- test_mapAssign() async { +- await _prepareCompletion( +- '3: 3', +- ''' +-main() { +- var x = {1: 1, 2: 2, 3: 3 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- var x = {1: 1, 2: 2, 3: 3}; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- @failingTest +- test_mapAssignMissingColon() async { +- await _prepareCompletion( +- '3', +- ''' +-main() { +- var x = {1: 1, 2: 2, 3 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- var x = {1: 1, 2: 2, 3: }; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_returnString() async { +- await _prepareCompletion( +- 'text', +- ''' +-main() { +- if (done()) { +- return 'text +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete control flow block', +- ''' +-main() { +- if (done()) { +- return 'text'; +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_stringAssign() async { +- await _prepareCompletion( +- '= ', +- ''' +-main() { +- var x = ' +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- var x = ''; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_stringSingle() async { +- await _prepareCompletion( +- 'text', +- ''' +-main() { +- print("text +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- print("text"); +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_stringSingleRaw() async { +- await _prepareCompletion( +- 'text', +- ''' +-main() { +- print(r"text +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- print(r"text"); +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_stringTriple() async { +- await _prepareCompletion( +- 'text', +- ''' +-main() { +- print(\'\'\'text +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- print(\'\'\'text\'\'\'); +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_stringTripleRaw() async { +- await _prepareCompletion( +- 'text', +- r""" +-main() { +- print(r'''text +-} +-""", +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- r""" +-main() { +- print(r'''text'''); +- //// +-} +-""", +- (s) => _afterLast(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _ForCompletionTest extends StatementCompletionTest { +- test_emptyCondition() async { +- await _prepareCompletion( +- '0;', +- ''' +-main() { +- for (int i = 0;) /**/ //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (int i = 0; ; ) /**/ { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_emptyConditionWithBody() async { +- await _prepareCompletion( +- '0;', +- ''' +-main() { +- for (int i = 0;) { +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (int i = 0; ; ) { +- } +-} +-''', +- (s) => _after(s, '0; ')); +- } +- +- test_emptyInitializers() async { +- // This does nothing, same as for Java. +- await _prepareCompletion( +- 'r (', +- ''' +-main() { +- for () { +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for () { +- } +-} +-''', +- (s) => _after(s, 'r (')); +- } +- +- test_emptyInitializersAfterBody() async { +- await _prepareCompletion( +- '}', +- ''' +-main() { +- for () { +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- for () { +- } +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_emptyInitializersEmptyCondition() async { +- await _prepareCompletion( +- '/**/', +- ''' +-main() { +- for (;/**/) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (; /**/; ) { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_emptyParts() async { +- await _prepareCompletion( +- ';)', +- ''' +-main() { +- for (;;) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (;;) { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_emptyUpdaters() async { +- await _prepareCompletion( +- '/**/', +- ''' +-main() { +- for (int i = 0; i < 10 /**/) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (int i = 0; i < 10 /**/; ) { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_emptyUpdatersWithBody() async { +- await _prepareCompletion( +- '/**/', +- ''' +-main() { +- for (int i = 0; i < 10 /**/) { +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (int i = 0; i < 10 /**/; ) { +- } +-} +-''', +- (s) => _after(s, '*/; ')); +- } +- +- test_keywordOnly() async { +- await _prepareCompletion( +- 'for', +- ''' +-main() { +- for +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for () { +- //// +- } +-} +-''', +- (s) => _after(s, 'for (')); +- } +- +- test_missingLeftSeparator() async { +- await _prepareCompletion( +- '= 0', +- ''' +-main() { +- for (int i = 0) { +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (int i = 0; ; ) { +- } +-} +-''', +- (s) => _after(s, '0; ')); +- } +- +- test_noError() async { +- await _prepareCompletion( +- ';)', +- ''' +-main() { +- for (;;) +- return; +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-statement', +- ''' +-main() { +- for (;;) { +- //// +- } +- return; +-} +-''', +- (s) => _after(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _ForEachCompletionTest extends StatementCompletionTest { +- test_emptyIdentifier() async { +- await _prepareCompletion( +- 'in xs)', +- ''' +-main() { +- for (in xs) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-each-statement', +- ''' +-main() { +- for ( in xs) { +- //// +- } +-} +-''', +- (s) => _after(s, 'for (')); +- } +- +- test_emptyIdentifierAndIterable() async { +- await _prepareCompletion( +- 'in)', +- ''' +-main() { +- for (in) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-each-statement', +- ''' +-main() { +- for ( in ) { +- //// +- } +-} +-''', +- (s) => _after(s, 'for (')); +- } +- +- test_emptyIterable() async { +- await _prepareCompletion( +- 'in)', +- ''' +-main() { +- for (var x in) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-each-statement', +- ''' +-main() { +- for (var x in ) { +- //// +- } +-} +-''', +- (s) => _after(s, 'in ')); +- } +- +- test_noError() async { +- await _prepareCompletion( +- '])', +- ''' +-main() { +- for (var x in [1,2]) +- return; +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete for-each-statement', +- ''' +-main() { +- for (var x in [1,2]) { +- //// +- } +- return; +-} +-''', +- (s) => _after(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _IfCompletionTest extends StatementCompletionTest { +- test_afterCondition() async { +- await _prepareCompletion( +- 'if (true) ', // Trigger completion after space. +- ''' +-main() { +- if (true) //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if (true) { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_emptyCondition() async { +- await _prepareCompletion( +- 'if ()', +- ''' +-main() { +- if () +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if () { +- //// +- } +-} +-''', +- (s) => _after(s, 'if (')); +- } +- +- test_keywordOnly() async { +- await _prepareCompletion( +- 'if', +- ''' +-main() { +- if //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if () { +- //// +- } +-} +-''', +- (s) => _after(s, 'if (')); +- } +- +- test_noError() async { +- await _prepareCompletion( +- 'if (true)', +- ''' +-main() { +- if (true) +- return; +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if (true) { +- //// +- } +- return; +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_withCondition() async { +- await _prepareCompletion( +- 'if (tr', // Trigger completion from within expression. +- ''' +-main() { +- if (true) +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if (true) { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_withElse() async { +- await _prepareCompletion( +- 'else', +- ''' +-main() { +- if () { +- } else +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if () { +- } else { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_withElse_BAD() async { +- await _prepareCompletion( +- 'if ()', +- ''' +-main() { +- if () +- else +-} +-''', +- atEnd: true); +- _assertHasChange( +- // Note: if-statement completion should not trigger. +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- if () +- else +-} +-''', +- (s) => _after(s, 'if ()')); +- } +- +- test_withElseNoThen() async { +- await _prepareCompletion( +- 'else', +- ''' +-main() { +- if () +- else +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if () +- else { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_withinEmptyCondition() async { +- await _prepareCompletion( +- 'if (', +- ''' +-main() { +- if () +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete if-statement', +- ''' +-main() { +- if () { +- //// +- } +-} +-''', +- (s) => _after(s, 'if (')); +- } +-} +- +-@reflectiveTest +-class _SimpleCompletionTest extends StatementCompletionTest { +- test_enter() async { +- await _prepareCompletion( +- 'v = 1;', +- ''' +-main() { +- int v = 1; +-} +-''', +- atEnd: true); +- _assertHasChange('Insert a newline at the end of the current line', ''' +-main() { +- int v = 1; +- //// +-} +-'''); +- } +- +- test_noCloseParen() async { +- await _prepareCompletion( +- 'ing(3', +- ''' +-main() { +- var s = 'sample'.substring(3 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- var s = 'sample'.substring(3); +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_noCloseParenWithSemicolon() async { +- String before = ''' +-main() { +- var s = 'sample'.substring(3; +-} +-'''; +- String after = ''' +-main() { +- var s = 'sample'.substring(3); +- //// +-} +-'''; +- // Check completion both before and after the semicolon. +- await _prepareCompletion('ing(3', before, atEnd: true); +- _assertHasChange('Insert a newline at the end of the current line', after, +- (s) => _afterLast(s, ' ')); +- await _prepareCompletion('ing(3;', before, atEnd: true); +- _assertHasChange('Insert a newline at the end of the current line', after, +- (s) => _afterLast(s, ' ')); +- } +- +- test_semicolonFn() async { +- await _prepareCompletion( +- '=> 3', +- ''' +-main() { +- int f() => 3 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- int f() => 3; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_semicolonFnBody() async { +- // It would be reasonable to add braces in this case. Unfortunately, +- // the incomplete line parses as two statements ['int;', 'f();'], not one. +- await _prepareCompletion( +- 'f()', +- ''' +-main() { +- int f() +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Insert a newline at the end of the current line', +- ''' +-main() { +- int f() +-} +-''', +- (s) => _afterLast(s, '()')); +- } +- +- test_semicolonFnBodyWithDef() async { +- // This ought to be the same as test_semicolonFnBody() but the definition +- // of f() removes an error and it appears to be a different case. +- // Suggestions for unifying the two are welcome. +- await _prepareCompletion( +- 'f()', +- ''' +-main() { +- int f() +-} +-f() {} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- int f(); +- //// +-} +-f() {} +-''', +- (s) => _afterLast(s, ' ')); +- } +- +- test_semicolonFnExpr() async { +- await _prepareCompletion( +- '=>', +- ''' +-main() { +- int f() => +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- int f() => ; +- //// +-} +-''', +- (s) => _afterLast(s, '=> ')); +- } +- +- test_semicolonFnSpaceExpr() async { +- await _prepareCompletion( +- '=>', +- ''' +-main() { +- int f() => //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- int f() => ; +- //// +-} +-''', +- (s) => _afterLast(s, '=> ')); +- } +- +- test_semicolonVar() async { +- await _prepareCompletion( +- 'v = 1', +- ''' +-main() { +- int v = 1 +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Add a semicolon and newline', +- ''' +-main() { +- int v = 1; +- //// +-} +-''', +- (s) => _afterLast(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _SwitchCompletionTest extends StatementCompletionTest { +- test_caseNoColon() async { +- await _prepareCompletion( +- 'label', +- ''' +-main(x) { +- switch (x) { +- case label +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete switch-statement', +- ''' +-main(x) { +- switch (x) { +- case label: //// +- } +-} +-''', +- (s) => _after(s, 'label: ')); +- } +- +- test_defaultNoColon() async { +- await _prepareCompletion( +- 'default', +- ''' +-main(x) { +- switch (x) { +- default +- } +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete switch-statement', +- ''' +-main(x) { +- switch (x) { +- default: //// +- } +-} +-''', +- (s) => _after(s, 'default: ')); +- } +- +- test_emptyCondition() async { +- await _prepareCompletion( +- 'switch', +- ''' +-main() { +- switch () +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete switch-statement', +- ''' +-main() { +- switch () { +- //// +- } +-} +-''', +- (s) => _after(s, 'switch (')); +- } +- +- test_keywordOnly() async { +- await _prepareCompletion( +- 'switch', +- ''' +-main() { +- switch//// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete switch-statement', +- ''' +-main() { +- switch () { +- //// +- } +-} +-''', +- (s) => _after(s, 'switch (')); +- } +- +- test_keywordSpace() async { +- await _prepareCompletion( +- 'switch', +- ''' +-main() { +- switch //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete switch-statement', +- ''' +-main() { +- switch () { +- //// +- } +-} +-''', +- (s) => _after(s, 'switch (')); +- } +-} +- +-@reflectiveTest +-class _TryCompletionTest extends StatementCompletionTest { +- test_catchOnly() async { +- await _prepareCompletion( +- '{} catch', +- ''' +-main() { +- try { +- } catch(e){} catch //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } catch(e){} catch () { +- //// +- } +-} +-''', +- (s) => _after(s, 'catch (')); +- } +- +- test_catchSecond() async { +- await _prepareCompletion( +- '} catch ', +- ''' +-main() { +- try { +- } catch() { +- } catch(e){} catch //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } catch() { +- } catch(e){} catch () { +- //// +- } +-} +-''', +- (s) => _afterLast(s, 'catch (')); +- } +- +- test_finallyOnly() async { +- await _prepareCompletion( +- 'finally', +- ''' +-main() { +- try { +- } finally +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } finally { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_keywordOnly() async { +- await _prepareCompletion( +- 'try', +- ''' +-main() { +- try//// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_keywordSpace() async { +- await _prepareCompletion( +- 'try', +- ''' +-main() { +- try //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +- +- test_onCatch() async { +- await _prepareCompletion( +- 'on', +- ''' +-main() { +- try { +- } on catch +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } on catch () { +- //// +- } +-} +-''', +- (s) => _after(s, 'catch (')); +- } +- +- test_onCatchComment() async { +- await _prepareCompletion( +- 'on', +- ''' +-main() { +- try { +- } on catch +- // +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } on catch () { +- //// +- } +- // +-} +-''', +- (s) => _after(s, 'catch (')); +- } +- +- test_onOnly() async { +- await _prepareCompletion( +- 'on', +- ''' +-main() { +- try { +- } on +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } on { +- //// +- } +-} +-''', +- (s) => _after(s, ' on ')); +- } +- +- test_onSpace() async { +- await _prepareCompletion( +- 'on', +- ''' +-main() { +- try { +- } on //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } on { +- //// +- } +-} +-''', +- (s) => _after(s, ' on ')); +- } +- +- test_onSpaces() async { +- await _prepareCompletion( +- 'on', +- ''' +-main() { +- try { +- } on //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } on { +- //// +- } +-} +-''', +- (s) => _after(s, ' on ')); +- } +- +- test_onType() async { +- await _prepareCompletion( +- 'on', +- ''' +-main() { +- try { +- } on Exception +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete try-statement', +- ''' +-main() { +- try { +- } on Exception { +- //// +- } +-} +-''', +- (s) => _after(s, ' ')); +- } +-} +- +-@reflectiveTest +-class _WhileCompletionTest extends StatementCompletionTest { +- /* +- The implementation of completion for while-statements is shared with +- if-statements. Here we check that the wrapper for while-statements +- functions as expected. The individual test cases are covered by the +- _IfCompletionTest tests. If the implementation changes then the same +- set of tests defined for if-statements should be duplicated here. +- */ +- test_keywordOnly() async { +- await _prepareCompletion( +- 'while', +- ''' +-main() { +- while //// +-} +-''', +- atEnd: true); +- _assertHasChange( +- 'Complete while-statement', +- ''' +-main() { +- while () { +- //// +- } +-} +-''', +- (s) => _after(s, 'while (')); +- } +-} +diff --git a/pkg/analysis_server/test/services/completion/statement/test_all.dart b/pkg/analysis_server/test/services/completion/statement/test_all.dart +deleted file mode 100644 +index f88ea5a079a..00000000000 +--- a/pkg/analysis_server/test/services/completion/statement/test_all.dart ++++ /dev/null +@@ -1,13 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'statement_completion_test.dart' as statement_completion_test; +- +-main() { +- defineReflectiveSuite(() { +- statement_completion_test.main(); +- }, name: 'statement'); +-} +diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart +deleted file mode 100644 +index e89a4e8bd5a..00000000000 +--- a/pkg/analysis_server/test/services/completion/test_all.dart ++++ /dev/null +@@ -1,17 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'dart/test_all.dart' as dart_all; +-import 'postfix/test_all.dart' as postfix_all; +-import 'statement/test_all.dart' as statement_all; +- +-main() { +- defineReflectiveSuite(() { +- dart_all.main(); +- postfix_all.main(); +- statement_all.main(); +- }, name: 'completion'); +-} +diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart +deleted file mode 100644 +index 350a11de67b..00000000000 +--- a/pkg/analysis_server/test/services/correction/assist_test.dart ++++ /dev/null +@@ -1,4443 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/plugin/edit/assist/assist_core.dart'; +-import 'package:analysis_server/plugin/edit/assist/assist_dart.dart'; +-import 'package:analysis_server/src/services/correction/assist.dart'; +-import 'package:analysis_server/src/services/correction/assist_internal.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/utilities/assist/assist.dart'; +-import 'package:plugin/manager.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +-import '../../src/utilities/flutter_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AssistProcessorTest); +- }); +-} +- +-@reflectiveTest +-class AssistProcessorTest extends AbstractSingleUnitTest { +- int offset; +- int length; +- +- Assist assist; +- SourceChange change; +- String resultCode; +- LinkedEditGroup linkedPositionGroup; +- +- /** +- * Asserts that there is an [Assist] of the given [kind] at [offset] which +- * produces the [expected] code when applied to [testCode]. +- */ +- assertHasAssist(AssistKind kind, String expected) async { +- assist = await _assertHasAssist(kind); +- change = assist.change; +- // apply to "file" +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits); +- // verify +- expect(resultCode, expected); +- } +- +- /** +- * Calls [assertHasAssist] at the offset of [offsetSearch] in [testCode]. +- */ +- assertHasAssistAt( +- String offsetSearch, AssistKind kind, String expected) async { +- offset = findOffset(offsetSearch); +- await assertHasAssist(kind, expected); +- } +- +- /** +- * Asserts that there is no [Assist] of the given [kind] at [offset]. +- */ +- assertNoAssist(AssistKind kind) async { +- List assists = await _computeAssists(); +- for (Assist assist in assists) { +- if (assist.kind == kind) { +- throw fail('Unexpected assist $kind in\n${assists.join('\n')}'); +- } +- } +- } +- +- /** +- * Calls [assertNoAssist] at the offset of [offsetSearch] in [testCode]. +- */ +- assertNoAssistAt(String offsetSearch, AssistKind kind) async { +- offset = findOffset(offsetSearch); +- await assertNoAssist(kind); +- } +- +- Position expectedPosition(String search) { +- int offset = resultCode.indexOf(search); +- return new Position(testFile, offset); +- } +- +- List expectedPositions(List patterns) { +- List positions = []; +- patterns.forEach((String search) { +- positions.add(expectedPosition(search)); +- }); +- return positions; +- } +- +- List expectedSuggestions( +- LinkedEditSuggestionKind kind, List values) { +- return values.map((value) { +- return new LinkedEditSuggestion(value, kind); +- }).toList(); +- } +- +- void processRequiredPlugins() { +- ExtensionManager manager = new ExtensionManager(); +- manager.processPlugins(AnalysisEngine.instance.requiredPlugins); +- } +- +- void setUp() { +- super.setUp(); +- offset = 0; +- length = 0; +- } +- +- test_addTypeAnnotation_BAD_privateType_closureParameter() async { +- addSource('/my_lib.dart', ''' +-library my_lib; +-class A {} +-class _B extends A {} +-foo(f(_B p)) {} +-'''); +- await resolveTestUnit(''' +-import 'my_lib.dart'; +-main() { +- foo((test) {}); +-} +- '''); +- await assertNoAssistAt('test)', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_BAD_privateType_declaredIdentifier() async { +- addSource('/my_lib.dart', ''' +-library my_lib; +-class A {} +-class _B extends A {} +-List<_B> getValues() => []; +-'''); +- await resolveTestUnit(''' +-import 'my_lib.dart'; +-class A { +- main() { +- for (var item in getValues()) { +- } +- } +-} +-'''); +- await assertNoAssistAt('var item', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_BAD_privateType_list() async { +- // This is now failing because we're suggesting "List" rather than nothing. +- // Is it really better to produce nothing? +- addSource('/my_lib.dart', ''' +-library my_lib; +-class A {} +-class _B extends A {} +-List<_B> getValues() => []; +-'''); +- await resolveTestUnit(''' +-import 'my_lib.dart'; +-main() { +- var v = getValues(); +-} +-'''); +- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-import 'my_lib.dart'; +-main() { +- List v = getValues(); +-} +-'''); +- } +- +- test_addTypeAnnotation_BAD_privateType_variable() async { +- addSource('/my_lib.dart', ''' +-library my_lib; +-class A {} +-class _B extends A {} +-_B getValue() => new _B(); +-'''); +- await resolveTestUnit(''' +-import 'my_lib.dart'; +-main() { +- var v = getValue(); +-} +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_classField_OK_final() async { +- await resolveTestUnit(''' +-class A { +- final f = 0; +-} +-'''); +- await assertHasAssistAt('final ', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class A { +- final int f = 0; +-} +-'''); +- } +- +- test_addTypeAnnotation_classField_OK_int() async { +- await resolveTestUnit(''' +-class A { +- var f = 0; +-} +-'''); +- await await assertHasAssistAt( +- 'var ', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class A { +- int f = 0; +-} +-'''); +- } +- +- test_addTypeAnnotation_declaredIdentifier_BAD_hasTypeAnnotation() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- } +-} +-'''); +- await assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_declaredIdentifier_BAD_inForEachBody() async { +- await resolveTestUnit(''' +-main(List items) { +- for (var item in items) { +- 42; +- } +-} +-'''); +- await assertNoAssistAt('42;', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_declaredIdentifier_BAD_unknownType() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main() { +- for (var item in unknownList) { +- } +-} +-'''); +- await assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_declaredIdentifier_generic_OK() async { +- await resolveTestUnit(''' +-class A { +- main(List> items) { +- for (var item in items) { +- } +- } +-} +-'''); +- await assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class A { +- main(List> items) { +- for (List item in items) { +- } +- } +-} +-'''); +- } +- +- test_addTypeAnnotation_declaredIdentifier_OK() async { +- await resolveTestUnit(''' +-main(List items) { +- for (var item in items) { +- } +-} +-'''); +- // on identifier +- await assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main(List items) { +- for (String item in items) { +- } +-} +-'''); +- // on "for" +- await assertHasAssistAt('for (', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main(List items) { +- for (String item in items) { +- } +-} +-'''); +- } +- +- test_addTypeAnnotation_declaredIdentifier_OK_addImport_dartUri() async { +- addSource('/my_lib.dart', r''' +-import 'dart:async'; +-List> getFutures() => null; +-'''); +- await resolveTestUnit(''' +-import 'my_lib.dart'; +-main() { +- for (var future in getFutures()) { +- } +-} +-'''); +- await assertHasAssistAt('future in', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-import 'dart:async'; +- +-import 'my_lib.dart'; +-main() { +- for (Future future in getFutures()) { +- } +-} +-'''); +- } +- +- test_addTypeAnnotation_declaredIdentifier_OK_final() async { +- await resolveTestUnit(''' +-main(List items) { +- for (final item in items) { +- } +-} +-'''); +- await assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main(List items) { +- for (final String item in items) { +- } +-} +-'''); +- } +- +- test_addTypeAnnotation_local_BAD_bottom() async { +- await resolveTestUnit(''' +-main() { +- var v = throw 42; +-} +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_BAD_hasTypeAnnotation() async { +- await resolveTestUnit(''' +-main() { +- int v = 42; +-} +-'''); +- await assertNoAssistAt(' = 42', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_BAD_multiple() async { +- await resolveTestUnit(''' +-main() { +- var a = 1, b = ''; +-} +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_BAD_noValue() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main() { +- var v; +-} +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_BAD_null() async { +- await resolveTestUnit(''' +-main() { +- var v = null; +-} +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_BAD_onInitializer() async { +- await resolveTestUnit(''' +-main() { +- var abc = 0; +-} +-'''); +- await assertNoAssistAt('0;', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_BAD_unknown() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main() { +- var v = unknownVar; +-} +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_local_generic_OK_literal() async { +- await resolveTestUnit(''' +-class A { +- main(List items) { +- var v = items; +- } +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class A { +- main(List items) { +- List v = items; +- } +-} +-'''); +- } +- +- test_addTypeAnnotation_local_generic_OK_local() async { +- await resolveTestUnit(''' +-class A { +- main(List items) { +- var v = items; +- } +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class A { +- main(List items) { +- List v = items; +- } +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_addImport_dartUri() async { +- addSource('/my_lib.dart', r''' +-import 'dart:async'; +-Future getFutureInt() => null; +-'''); +- await resolveTestUnit(''' +-import 'my_lib.dart'; +-main() { +- var v = getFutureInt(); +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-import 'dart:async'; +- +-import 'my_lib.dart'; +-main() { +- Future v = getFutureInt(); +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_addImport_notLibraryUnit() async { +- // prepare library +- addSource('/my_lib.dart', r''' +-import 'dart:async'; +-Future getFutureInt() => null; +-'''); +- // prepare code +- String appCode = r''' +-library my_app; +-import 'my_lib.dart'; +-part 'test.dart'; +-'''; +- testCode = r''' +-part of my_app; +-main() { +- var v = getFutureInt(); +-} +-'''; +- // add sources +- addSource('/app.dart', appCode); +- testSource = addSource('/test.dart', testCode); +- // resolve +- await resolveTestUnit(testCode); +- // prepare the assist +- offset = findOffset('v = '); +- assist = await _assertHasAssist(DartAssistKind.ADD_TYPE_ANNOTATION); +- change = assist.change; +- // verify +- { +- var testFileEdit = change.getFileEdit('/app.dart'); +- var resultCode = SourceEdit.applySequence(appCode, testFileEdit.edits); +- expect(resultCode, ''' +-library my_app; +-import 'dart:async'; +- +-import 'my_lib.dart'; +-part 'test.dart'; +-'''); +- } +- { +- var testFileEdit = change.getFileEdit('/test.dart'); +- var resultCode = SourceEdit.applySequence(testCode, testFileEdit.edits); +- expect(resultCode, ''' +-part of my_app; +-main() { +- Future v = getFutureInt(); +-} +-'''); +- } +- } +- +- test_addTypeAnnotation_local_OK_addImport_relUri() async { +- addSource('/aa/bbb/lib_a.dart', r''' +-class MyClass {} +-'''); +- addSource('/ccc/lib_b.dart', r''' +-import '../aa/bbb/lib_a.dart'; +-MyClass newMyClass() => null; +-'''); +- await resolveTestUnit(''' +-import 'ccc/lib_b.dart'; +-main() { +- var v = newMyClass(); +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-import 'aa/bbb/lib_a.dart'; +-import 'ccc/lib_b.dart'; +-main() { +- MyClass v = newMyClass(); +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_Function() async { +- await resolveTestUnit(''' +-main() { +- var v = () => 1; +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main() { +- Function v = () => 1; +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_int() async { +- await resolveTestUnit(''' +-main() { +- var v = 0; +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main() { +- int v = 0; +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_List() async { +- await resolveTestUnit(''' +-main() { +- var v = []; +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main() { +- List v = []; +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_localType() async { +- await resolveTestUnit(''' +-class C {} +-C f() => null; +-main() { +- var x = f(); +-} +-'''); +- await assertHasAssistAt('x =', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class C {} +-C f() => null; +-main() { +- C x = f(); +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_onName() async { +- await resolveTestUnit(''' +-main() { +- var abc = 0; +-} +-'''); +- await assertHasAssistAt('bc', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main() { +- int abc = 0; +-} +-'''); +- } +- +- test_addTypeAnnotation_local_OK_onVar() async { +- await resolveTestUnit(''' +-main() { +- var v = 0; +-} +-'''); +- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-main() { +- int v = 0; +-} +-'''); +- } +- +- test_addTypeAnnotation_OK_privateType_sameLibrary() async { +- await resolveTestUnit(''' +-class _A {} +-_A getValue() => new _A(); +-main() { +- var v = getValue(); +-} +-'''); +- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-class _A {} +-_A getValue() => new _A(); +-main() { +- _A v = getValue(); +-} +-'''); +- } +- +- test_addTypeAnnotation_parameter_BAD_hasExplicitType() async { +- await resolveTestUnit(''' +-foo(f(int p)) {} +-main() { +- foo((num test) {}); +-} +-'''); +- await assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_parameter_BAD_noPropagatedType() async { +- await resolveTestUnit(''' +-foo(f(p)) {} +-main() { +- foo((test) {}); +-} +-'''); +- await assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_parameter_OK() async { +- await resolveTestUnit(''' +-foo(f(int p)) {} +-main() { +- foo((test) {}); +-} +-'''); +- await assertHasAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-foo(f(int p)) {} +-main() { +- foo((int test) {}); +-} +-'''); +- } +- +- test_addTypeAnnotation_topLevelField_BAD_multiple() async { +- await resolveTestUnit(''' +-var A = 1, V = ''; +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_topLevelField_BAD_noValue() async { +- await resolveTestUnit(''' +-var V; +-'''); +- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION); +- } +- +- test_addTypeAnnotation_topLevelField_OK_int() async { +- await resolveTestUnit(''' +-var V = 0; +-'''); +- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, ''' +-int V = 0; +-'''); +- } +- +- test_assignToLocalVariable() async { +- await resolveTestUnit(''' +-main() { +- List bytes; +- readBytes(); +-} +-List readBytes() => []; +-'''); +- await assertHasAssistAt( +- 'readBytes();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE, ''' +-main() { +- List bytes; +- var readBytes = readBytes(); +-} +-List readBytes() => []; +-'''); +- _assertLinkedGroup( +- change.linkedEditGroups[0], +- ['readBytes = '], +- expectedSuggestions(LinkedEditSuggestionKind.VARIABLE, +- ['list', 'bytes2', 'readBytes'])); +- } +- +- test_assignToLocalVariable_alreadyAssignment() async { +- await resolveTestUnit(''' +-main() { +- var vvv; +- vvv = 42; +-} +-'''); +- await assertNoAssistAt('vvv =', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE); +- } +- +- test_assignToLocalVariable_inClosure() async { +- await resolveTestUnit(r''' +-main() { +- print(() { +- 12345; +- }); +-} +-'''); +- await assertHasAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE, ''' +-main() { +- print(() { +- var i = 12345; +- }); +-} +-'''); +- } +- +- test_assignToLocalVariable_invocationArgument() async { +- await resolveTestUnit(r''' +-main() { +- f(12345); +-} +-void f(p) {} +-'''); +- await assertNoAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE); +- } +- +- test_assignToLocalVariable_throw() async { +- await resolveTestUnit(''' +-main() { +- throw 42; +-} +-'''); +- await assertNoAssistAt('throw ', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE); +- } +- +- test_assignToLocalVariable_void() async { +- await resolveTestUnit(''' +-main() { +- f(); +-} +-void f() {} +-'''); +- await assertNoAssistAt('f();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE); +- } +- +- test_convertDocumentationIntoBlock_BAD_alreadyBlock() async { +- await resolveTestUnit(''' +-/** +- * AAAAAAA +- */ +-class A {} +-'''); +- await assertNoAssistAt( +- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK); +- } +- +- test_convertDocumentationIntoBlock_BAD_notDocumentation() async { +- await resolveTestUnit(''' +-// AAAA +-class A {} +-'''); +- await assertNoAssistAt( +- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK); +- } +- +- test_convertDocumentationIntoBlock_OK_noSpaceBeforeText() async { +- await resolveTestUnit(''' +-class A { +- /// AAAAA +- ///BBBBB +- /// +- /// CCCCC +- mmm() {} +-} +-'''); +- await assertHasAssistAt( +- 'AAAAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, ''' +-class A { +- /** +- * AAAAA +- *BBBBB +- * +- * CCCCC +- */ +- mmm() {} +-} +-'''); +- } +- +- test_convertDocumentationIntoBlock_OK_onReference() async { +- await resolveTestUnit(''' +-/// AAAAAAA [int] AAAAAAA +-class A {} +-'''); +- await assertHasAssistAt( +- 'nt]', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, ''' +-/** +- * AAAAAAA [int] AAAAAAA +- */ +-class A {} +-'''); +- } +- +- test_convertDocumentationIntoBlock_OK_onText() async { +- await resolveTestUnit(''' +-class A { +- /// AAAAAAA [int] AAAAAAA +- /// BBBBBBBB BBBB BBBB +- /// CCC [A] CCCCCCCCCCC +- mmm() {} +-} +-'''); +- await assertHasAssistAt( +- 'AAA [', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, ''' +-class A { +- /** +- * AAAAAAA [int] AAAAAAA +- * BBBBBBBB BBBB BBBB +- * CCC [A] CCCCCCCCCCC +- */ +- mmm() {} +-} +-'''); +- } +- +- test_convertDocumentationIntoLine_BAD_alreadyLine() async { +- await resolveTestUnit(''' +-/// AAAAAAA +-class A {} +-'''); +- await assertNoAssistAt( +- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE); +- } +- +- test_convertDocumentationIntoLine_BAD_notDocumentation() async { +- await resolveTestUnit(''' +-/* AAAA */ +-class A {} +-'''); +- await assertNoAssistAt( +- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE); +- } +- +- test_convertDocumentationIntoLine_OK_onReference() async { +- await resolveTestUnit(''' +-/** +- * AAAAAAA [int] AAAAAAA +- */ +-class A {} +-'''); +- await assertHasAssistAt( +- 'nt]', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, ''' +-/// AAAAAAA [int] AAAAAAA +-class A {} +-'''); +- } +- +- test_convertDocumentationIntoLine_OK_onText() async { +- await resolveTestUnit(''' +-class A { +- /** +- * AAAAAAA [int] AAAAAAA +- * BBBBBBBB BBBB BBBB +- * CCC [A] CCCCCCCCCCC +- */ +- mmm() {} +-} +-'''); +- await assertHasAssistAt( +- 'AAA [', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, ''' +-class A { +- /// AAAAAAA [int] AAAAAAA +- /// BBBBBBBB BBBB BBBB +- /// CCC [A] CCCCCCCCCCC +- mmm() {} +-} +-'''); +- } +- +- test_convertDocumentationIntoLine_OK_onText_hasFirstLine() async { +- await resolveTestUnit(''' +-class A { +- /** AAAAAAA [int] AAAAAAA +- * BBBBBBBB BBBB BBBB +- * CCC [A] CCCCCCCCCCC +- */ +- mmm() {} +-} +-'''); +- await assertHasAssistAt( +- 'AAA [', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, ''' +-class A { +- /// AAAAAAA [int] AAAAAAA +- /// BBBBBBBB BBBB BBBB +- /// CCC [A] CCCCCCCCCCC +- mmm() {} +-} +-'''); +- } +- +- test_convertFlutterChild_OK_multiLine() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- /*caret*/child: new Container( +- width: 200.0, +- height: 300.0, +- ), +- key: null, +- ), +-// end +- ); +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.CONVERT_FLUTTER_CHILD, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- /*caret*/children: [ +- new Container( +- width: 200.0, +- height: 300.0, +- ), +- ], +- key: null, +- ), +-// end +- ); +-} +-'''); +- } +- +- test_convertFlutterChild_OK_newlineChild() async { +- // This case could occur with deeply nested constructors, common in Flutter. +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- /*caret*/child: +- new Container( +- width: 200.0, +- height: 300.0, +- ), +- key: null, +- ), +-// end +- ); +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.CONVERT_FLUTTER_CHILD, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- /*caret*/children: [ +- new Container( +- width: 200.0, +- height: 300.0, +- ), +- ], +- key: null, +- ), +-// end +- ); +-} +-'''); +- } +- +- test_convertFlutterChild_OK_singleLine() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- /*caret*/child: new GestureDetector(), +- key: null, +- ), +-// end +- ); +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.CONVERT_FLUTTER_CHILD, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- /*caret*/children: [new GestureDetector()], +- key: null, +- ), +-// end +- ); +-} +-'''); +- } +- +- test_convertPartOfToUri_file_nonSibling() async { +- addSource('/pkg/lib/foo.dart', ''' +-library foo; +-part 'src/bar.dart'; +-'''); +- testFile = provider.convertPath('/pkg/lib/src/bar.dart'); +- await resolveTestUnit(''' +-part of foo; +-'''); +- await assertHasAssistAt('foo', DartAssistKind.CONVERT_PART_OF_TO_URI, ''' +-part of '../foo.dart'; +-'''); +- } +- +- test_convertPartOfToUri_file_sibling() async { +- addSource('/pkg/foo.dart', ''' +-library foo; +-part 'bar.dart'; +-'''); +- testFile = provider.convertPath('/pkg/bar.dart'); +- await resolveTestUnit(''' +-part of foo; +-'''); +- await assertHasAssistAt('foo', DartAssistKind.CONVERT_PART_OF_TO_URI, ''' +-part of 'foo.dart'; +-'''); +- } +- +- test_convertToBlockBody_BAD_inExpression() async { +- await resolveTestUnit(''' +-main() => 123; +-'''); +- await assertNoAssistAt('123;', DartAssistKind.CONVERT_INTO_BLOCK_BODY); +- } +- +- test_convertToBlockBody_BAD_noEnclosingFunction() async { +- await resolveTestUnit(''' +-var v = 123; +-'''); +- await assertNoAssistAt('v =', DartAssistKind.CONVERT_INTO_BLOCK_BODY); +- } +- +- test_convertToBlockBody_BAD_notExpressionBlock() async { +- await resolveTestUnit(''' +-fff() { +- return 123; +-} +-'''); +- await assertNoAssistAt('fff() {', DartAssistKind.CONVERT_INTO_BLOCK_BODY); +- } +- +- test_convertToBlockBody_OK_async() async { +- await resolveTestUnit(''' +-class A { +- mmm() async => 123; +-} +-'''); +- await assertHasAssistAt('mmm()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-class A { +- mmm() async { +- return 123; +- } +-} +-'''); +- } +- +- test_convertToBlockBody_OK_closure() async { +- await resolveTestUnit(''' +-setup(x) {} +-main() { +- setup(() => 42); +-} +-'''); +- await assertHasAssistAt( +- '() => 42', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-setup(x) {} +-main() { +- setup(() { +- return 42; +- }); +-} +-'''); +- { +- Position exitPos = change.selection; +- expect(exitPos, isNotNull); +- expect(exitPos.file, testFile); +- expect(exitPos.offset - 3, resultCode.indexOf('42;')); +- } +- } +- +- test_convertToBlockBody_OK_closure_voidExpression() async { +- await resolveTestUnit(''' +-setup(x) {} +-main() { +- setup(() => print('done')); +-} +-'''); +- await assertHasAssistAt( +- '() => print', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-setup(x) {} +-main() { +- setup(() { +- print('done'); +- }); +-} +-'''); +- { +- Position exitPos = change.selection; +- expect(exitPos, isNotNull); +- expect(exitPos.file, testFile); +- expect(exitPos.offset - 3, resultCode.indexOf("');")); +- } +- } +- +- test_convertToBlockBody_OK_constructor() async { +- await resolveTestUnit(''' +-class A { +- factory A() => null; +-} +-'''); +- await assertHasAssistAt('A()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-class A { +- factory A() { +- return null; +- } +-} +-'''); +- } +- +- test_convertToBlockBody_OK_method() async { +- await resolveTestUnit(''' +-class A { +- mmm() => 123; +-} +-'''); +- await assertHasAssistAt('mmm()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-class A { +- mmm() { +- return 123; +- } +-} +-'''); +- } +- +- test_convertToBlockBody_OK_onArrow() async { +- await resolveTestUnit(''' +-fff() => 123; +-'''); +- await assertHasAssistAt('=>', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-fff() { +- return 123; +-} +-'''); +- } +- +- test_convertToBlockBody_OK_onName() async { +- await resolveTestUnit(''' +-fff() => 123; +-'''); +- await assertHasAssistAt('fff()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, ''' +-fff() { +- return 123; +-} +-'''); +- } +- +- test_convertToExpressionBody_BAD_already() async { +- await resolveTestUnit(''' +-fff() => 42; +-'''); +- await assertNoAssistAt( +- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- test_convertToExpressionBody_BAD_inExpression() async { +- await resolveTestUnit(''' +-main() { +- return 42; +-} +-'''); +- await assertNoAssistAt('42;', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- test_convertToExpressionBody_BAD_moreThanOneStatement() async { +- await resolveTestUnit(''' +-fff() { +- var v = 42; +- return v; +-} +-'''); +- await assertNoAssistAt( +- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- test_convertToExpressionBody_BAD_noEnclosingFunction() async { +- await resolveTestUnit(''' +-var V = 42; +-'''); +- await assertNoAssistAt('V = ', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- test_convertToExpressionBody_BAD_noReturn() async { +- await resolveTestUnit(''' +-fff() { +- var v = 42; +-} +-'''); +- await assertNoAssistAt( +- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- test_convertToExpressionBody_BAD_noReturnValue() async { +- await resolveTestUnit(''' +-fff() { +- return; +-} +-'''); +- await assertNoAssistAt( +- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY); +- } +- +- test_convertToExpressionBody_OK_async() async { +- await resolveTestUnit(''' +-class A { +- mmm() async { +- return 42; +- } +-} +-'''); +- await assertHasAssistAt( +- 'mmm', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-class A { +- mmm() async => 42; +-} +-'''); +- } +- +- test_convertToExpressionBody_OK_closure() async { +- await resolveTestUnit(''' +-setup(x) {} +-main() { +- setup(() { +- return 42; +- }); +-} +-'''); +- await assertHasAssistAt( +- 'return', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-setup(x) {} +-main() { +- setup(() => 42); +-} +-'''); +- } +- +- test_convertToExpressionBody_OK_closure_voidExpression() async { +- await resolveTestUnit(''' +-setup(x) {} +-main() { +- setup((_) { +- print('test'); +- }); +-} +-'''); +- await assertHasAssistAt( +- '(_) {', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-setup(x) {} +-main() { +- setup((_) => print('test')); +-} +-'''); +- } +- +- test_convertToExpressionBody_OK_constructor() async { +- await resolveTestUnit(''' +-class A { +- factory A() { +- return null; +- } +-} +-'''); +- await assertHasAssistAt( +- 'A()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-class A { +- factory A() => null; +-} +-'''); +- } +- +- test_convertToExpressionBody_OK_function_onBlock() async { +- await resolveTestUnit(''' +-fff() { +- return 42; +-} +-'''); +- await assertHasAssistAt( +- '{', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-fff() => 42; +-'''); +- } +- +- test_convertToExpressionBody_OK_function_onName() async { +- await resolveTestUnit(''' +-fff() { +- return 42; +-} +-'''); +- await assertHasAssistAt( +- 'ff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-fff() => 42; +-'''); +- } +- +- test_convertToExpressionBody_OK_method_onBlock() async { +- await resolveTestUnit(''' +-class A { +- m() { // marker +- return 42; +- } +-} +-'''); +- await assertHasAssistAt( +- '{ // marker', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-class A { +- m() => 42; +-} +-'''); +- } +- +- test_convertToExpressionBody_OK_topFunction_onReturnStatement() async { +- await resolveTestUnit(''' +-fff() { +- return 42; +-} +-'''); +- await assertHasAssistAt( +- 'return', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, ''' +-fff() => 42; +-'''); +- } +- +- test_convertToFieldParameter_BAD_additionalUse() async { +- await resolveTestUnit(''' +-class A { +- int aaa2; +- int bbb2; +- A(int aaa) : aaa2 = aaa, bbb2 = aaa; +-} +-'''); +- await assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER); +- } +- +- test_convertToFieldParameter_BAD_notPureAssignment() async { +- await resolveTestUnit(''' +-class A { +- int aaa2; +- A(int aaa) : aaa2 = aaa * 2; +-} +-'''); +- await assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER); +- } +- +- test_convertToFieldParameter_OK_firstInitializer() async { +- await resolveTestUnit(''' +-class A { +- int aaa2; +- int bbb2; +- A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb; +-} +-'''); +- await assertHasAssistAt( +- 'aaa, ', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, ''' +-class A { +- int aaa2; +- int bbb2; +- A(this.aaa2, int bbb) : bbb2 = bbb; +-} +-'''); +- } +- +- test_convertToFieldParameter_OK_onParameterName_inInitializer() async { +- await resolveTestUnit(''' +-class A { +- int test2; +- A(int test) : test2 = test { +- } +-} +-'''); +- await assertHasAssistAt( +- 'test {', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, ''' +-class A { +- int test2; +- A(this.test2) { +- } +-} +-'''); +- } +- +- test_convertToFieldParameter_OK_onParameterName_inParameters() async { +- await resolveTestUnit(''' +-class A { +- int test; +- A(int test) : test = test { +- } +-} +-'''); +- await assertHasAssistAt( +- 'test)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, ''' +-class A { +- int test; +- A(this.test) { +- } +-} +-'''); +- } +- +- test_convertToFieldParameter_OK_secondInitializer() async { +- await resolveTestUnit(''' +-class A { +- int aaa2; +- int bbb2; +- A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb; +-} +-'''); +- await assertHasAssistAt( +- 'bbb)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, ''' +-class A { +- int aaa2; +- int bbb2; +- A(int aaa, this.bbb2) : aaa2 = aaa; +-} +-'''); +- } +- +- test_convertToFinalField_BAD_hasSetter_inThisClass() async { +- await resolveTestUnit(''' +-class A { +- int get foo => null; +- void set foo(_) {} +-} +-'''); +- await assertNoAssistAt('get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD); +- } +- +- test_convertToFinalField_BAD_notExpressionBody() async { +- await resolveTestUnit(''' +-class A { +- int get foo { +- int v = 1 + 2; +- return v + 3; +- } +-} +-'''); +- await assertNoAssistAt('get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD); +- } +- +- test_convertToFinalField_BAD_notGetter() async { +- await resolveTestUnit(''' +-class A { +- int foo() => 42; +-} +-'''); +- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD); +- } +- +- test_convertToFinalField_OK_blockBody_onlyReturnStatement() async { +- await resolveTestUnit(''' +-class A { +- int get foo { +- return 1 + 2; +- } +-} +-'''); +- await assertHasAssistAt( +- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- final int foo = 1 + 2; +-} +-'''); +- } +- +- test_convertToFinalField_OK_hasOverride() async { +- await resolveTestUnit(''' +-const myAnnotation = const Object(); +-class A { +- @myAnnotation +- int get foo => 42; +-} +-'''); +- await assertHasAssistAt( +- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-const myAnnotation = const Object(); +-class A { +- @myAnnotation +- final int foo = 42; +-} +-'''); +- } +- +- test_convertToFinalField_OK_hasSetter_inSuper() async { +- await resolveTestUnit(''' +-class A { +- void set foo(_) {} +-} +-class B extends A { +- int get foo => null; +-} +-'''); +- await assertHasAssistAt( +- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- void set foo(_) {} +-} +-class B extends A { +- final int foo; +-} +-'''); +- } +- +- test_convertToFinalField_OK_notNull() async { +- await resolveTestUnit(''' +-class A { +- int get foo => 1 + 2; +-} +-'''); +- await assertHasAssistAt( +- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- final int foo = 1 + 2; +-} +-'''); +- } +- +- test_convertToFinalField_OK_null() async { +- await resolveTestUnit(''' +-class A { +- int get foo => null; +-} +-'''); +- await assertHasAssistAt( +- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- final int foo; +-} +-'''); +- } +- +- test_convertToFinalField_OK_onName() async { +- await resolveTestUnit(''' +-class A { +- int get foo => 42; +-} +-'''); +- await assertHasAssistAt('foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- final int foo = 42; +-} +-'''); +- } +- +- test_convertToFinalField_OK_onReturnType_parameterized() async { +- await resolveTestUnit(''' +-class A { +- List get foo => null; +-} +-'''); +- await assertHasAssistAt( +- 'nt> get', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- final List foo; +-} +-'''); +- } +- +- test_convertToFinalField_OK_onReturnType_simple() async { +- await resolveTestUnit(''' +-class A { +- int get foo => 42; +-} +-'''); +- await assertHasAssistAt( +- 'int get', DartAssistKind.CONVERT_INTO_FINAL_FIELD, ''' +-class A { +- final int foo = 42; +-} +-'''); +- } +- +- test_convertToForIndex_BAD_bodyNotBlock() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) print(item); +-} +-'''); +- await assertNoAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX); +- } +- +- test_convertToForIndex_BAD_doesNotDeclareVariable() async { +- await resolveTestUnit(''' +-main(List items) { +- String item; +- for (item in items) { +- print(item); +- } +-} +-'''); +- await assertNoAssistAt('for (item', DartAssistKind.CONVERT_INTO_FOR_INDEX); +- } +- +- test_convertToForIndex_BAD_iterableIsNotVariable() async { +- await resolveTestUnit(''' +-main() { +- for (String item in ['a', 'b', 'c']) { +- print(item); +- } +-} +-'''); +- await assertNoAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX); +- } +- +- test_convertToForIndex_BAD_iterableNotList() async { +- await resolveTestUnit(''' +-main(Iterable items) { +- for (String item in items) { +- print(item); +- } +-} +-'''); +- await assertNoAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX); +- } +- +- test_convertToForIndex_BAD_usesIJK() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- print(item); +- int i, j, k; +- } +-} +-'''); +- await assertNoAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX); +- } +- +- test_convertToForIndex_OK_onDeclaredIdentifier_name() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- print(item); +- } +-} +-'''); +- await assertHasAssistAt( +- 'item in', DartAssistKind.CONVERT_INTO_FOR_INDEX, ''' +-main(List items) { +- for (int i = 0; i < items.length; i++) { +- String item = items[i]; +- print(item); +- } +-} +-'''); +- } +- +- test_convertToForIndex_OK_onDeclaredIdentifier_type() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- print(item); +- } +-} +-'''); +- await assertHasAssistAt( +- 'tring item', DartAssistKind.CONVERT_INTO_FOR_INDEX, ''' +-main(List items) { +- for (int i = 0; i < items.length; i++) { +- String item = items[i]; +- print(item); +- } +-} +-'''); +- } +- +- test_convertToForIndex_OK_onFor() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- print(item); +- } +-} +-'''); +- await assertHasAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, ''' +-main(List items) { +- for (int i = 0; i < items.length; i++) { +- String item = items[i]; +- print(item); +- } +-} +-'''); +- } +- +- test_convertToForIndex_OK_usesI() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- int i = 0; +- } +-} +-'''); +- await assertHasAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, ''' +-main(List items) { +- for (int j = 0; j < items.length; j++) { +- String item = items[j]; +- int i = 0; +- } +-} +-'''); +- } +- +- test_convertToForIndex_OK_usesIJ() async { +- await resolveTestUnit(''' +-main(List items) { +- for (String item in items) { +- print(item); +- int i = 0, j = 1; +- } +-} +-'''); +- await assertHasAssistAt( +- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, ''' +-main(List items) { +- for (int k = 0; k < items.length; k++) { +- String item = items[k]; +- print(item); +- int i = 0, j = 1; +- } +-} +-'''); +- } +- +- test_convertToGetter_BAD_noInitializer() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-class A { +- final int foo; +-} +-'''); +- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER); +- } +- +- test_convertToGetter_BAD_notFinal() async { +- await resolveTestUnit(''' +-class A { +- int foo = 1; +-} +-'''); +- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER); +- } +- +- test_convertToGetter_BAD_notSingleField() async { +- await resolveTestUnit(''' +-class A { +- final int foo = 1, bar = 2; +-} +-'''); +- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER); +- } +- +- test_convertToGetter_OK() async { +- await resolveTestUnit(''' +-const myAnnotation = const Object(); +-class A { +- @myAnnotation +- final int foo = 1 + 2; +-} +-'''); +- await assertHasAssistAt('foo =', DartAssistKind.CONVERT_INTO_GETTER, ''' +-const myAnnotation = const Object(); +-class A { +- @myAnnotation +- int get foo => 1 + 2; +-} +-'''); +- } +- +- test_convertToGetter_OK_noType() async { +- await resolveTestUnit(''' +-class A { +- final foo = 42; +-} +-'''); +- await assertHasAssistAt('foo =', DartAssistKind.CONVERT_INTO_GETTER, ''' +-class A { +- get foo => 42; +-} +-'''); +- } +- +- test_convertToIsNot_BAD_is_alreadyIsNot() async { +- await resolveTestUnit(''' +-main(p) { +- p is! String; +-} +-'''); +- await assertNoAssistAt('is!', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_is_noEnclosingParenthesis() async { +- await resolveTestUnit(''' +-main(p) { +- p is String; +-} +-'''); +- await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_is_noPrefix() async { +- await resolveTestUnit(''' +-main(p) { +- (p is String); +-} +-'''); +- await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_is_notIsExpression() async { +- await resolveTestUnit(''' +-main(p) { +- 123 + 456; +-} +-'''); +- await assertNoAssistAt('123 +', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_is_notTheNotOperator() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main(p) { +- ++(p is String); +-} +-'''); +- await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_not_alreadyIsNot() async { +- await resolveTestUnit(''' +-main(p) { +- !(p is! String); +-} +-'''); +- await assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_not_noEnclosingParenthesis() async { +- await resolveTestUnit(''' +-main(p) { +- !p; +-} +-'''); +- await assertNoAssistAt('!p', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_not_notIsExpression() async { +- await resolveTestUnit(''' +-main(p) { +- !(p == null); +-} +-'''); +- await assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_BAD_not_notTheNotOperator() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main(p) { +- ++(p is String); +-} +-'''); +- await assertNoAssistAt('++(', DartAssistKind.CONVERT_INTO_IS_NOT); +- } +- +- test_convertToIsNot_OK_childOfIs_left() async { +- await resolveTestUnit(''' +-main(p) { +- !(p is String); +-} +-'''); +- await assertHasAssistAt('p is', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- p is! String; +-} +-'''); +- } +- +- test_convertToIsNot_OK_childOfIs_right() async { +- await resolveTestUnit(''' +-main(p) { +- !(p is String); +-} +-'''); +- await assertHasAssistAt('String)', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- p is! String; +-} +-'''); +- } +- +- test_convertToIsNot_OK_is() async { +- await resolveTestUnit(''' +-main(p) { +- !(p is String); +-} +-'''); +- await assertHasAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- p is! String; +-} +-'''); +- } +- +- test_convertToIsNot_OK_is_higherPrecedencePrefix() async { +- await resolveTestUnit(''' +-main(p) { +- !!(p is String); +-} +-'''); +- await assertHasAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- !(p is! String); +-} +-'''); +- } +- +- test_convertToIsNot_OK_is_not_higherPrecedencePrefix() async { +- await resolveTestUnit(''' +-main(p) { +- !!(p is String); +-} +-'''); +- await assertHasAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- !(p is! String); +-} +-'''); +- } +- +- test_convertToIsNot_OK_not() async { +- await resolveTestUnit(''' +-main(p) { +- !(p is String); +-} +-'''); +- await assertHasAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- p is! String; +-} +-'''); +- } +- +- test_convertToIsNot_OK_parentheses() async { +- await resolveTestUnit(''' +-main(p) { +- !(p is String); +-} +-'''); +- await assertHasAssistAt('(p is', DartAssistKind.CONVERT_INTO_IS_NOT, ''' +-main(p) { +- p is! String; +-} +-'''); +- } +- +- test_convertToIsNotEmpty_BAD_noBang() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main(String str) { +- ~str.isEmpty; +-} +-'''); +- await assertNoAssistAt( +- 'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY); +- } +- +- test_convertToIsNotEmpty_BAD_noIsNotEmpty() async { +- await resolveTestUnit(''' +-class A { +- bool get isEmpty => false; +-} +-main(A a) { +- !a.isEmpty; +-} +-'''); +- await assertNoAssistAt( +- 'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY); +- } +- +- test_convertToIsNotEmpty_BAD_notInPrefixExpression() async { +- await resolveTestUnit(''' +-main(String str) { +- str.isEmpty; +-} +-'''); +- await assertNoAssistAt( +- 'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY); +- } +- +- test_convertToIsNotEmpty_BAD_notIsEmpty() async { +- await resolveTestUnit(''' +-main(int p) { +- !p.isEven; +-} +-'''); +- await assertNoAssistAt('isEven;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY); +- } +- +- test_convertToIsNotEmpty_OK_on_isEmpty() async { +- await resolveTestUnit(''' +-main(String str) { +- !str.isEmpty; +-} +-'''); +- await assertHasAssistAt( +- 'isEmpty', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, ''' +-main(String str) { +- str.isNotEmpty; +-} +-'''); +- } +- +- test_convertToIsNotEmpty_OK_on_str() async { +- await resolveTestUnit(''' +-main(String str) { +- !str.isEmpty; +-} +-'''); +- await assertHasAssistAt( +- 'str.', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, ''' +-main(String str) { +- str.isNotEmpty; +-} +-'''); +- } +- +- test_convertToIsNotEmpty_OK_propertyAccess() async { +- await resolveTestUnit(''' +-main(String str) { +- !'text'.isEmpty; +-} +-'''); +- await assertHasAssistAt( +- 'isEmpty', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, ''' +-main(String str) { +- 'text'.isNotEmpty; +-} +-'''); +- } +- +- test_convertToNormalParameter_OK_dynamic() async { +- await resolveTestUnit(''' +-class A { +- var test; +- A(this.test) { +- } +-} +-'''); +- await assertHasAssistAt( +- 'test)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, ''' +-class A { +- var test; +- A(test) : test = test { +- } +-} +-'''); +- } +- +- test_convertToNormalParameter_OK_firstInitializer() async { +- await resolveTestUnit(''' +-class A { +- int test; +- A(this.test) { +- } +-} +-'''); +- await assertHasAssistAt( +- 'test)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, ''' +-class A { +- int test; +- A(int test) : test = test { +- } +-} +-'''); +- } +- +- test_convertToNormalParameter_OK_secondInitializer() async { +- await resolveTestUnit(''' +-class A { +- double aaa; +- int bbb; +- A(this.bbb) : aaa = 1.0; +-} +-'''); +- await assertHasAssistAt( +- 'bbb)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, ''' +-class A { +- double aaa; +- int bbb; +- A(int bbb) : aaa = 1.0, bbb = bbb; +-} +-'''); +- } +- +- test_encapsulateField_BAD_alreadyPrivate() async { +- await resolveTestUnit(''' +-class A { +- int _test = 42; +-} +-main(A a) { +- print(a._test); +-} +-'''); +- await assertNoAssistAt('_test =', DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- test_encapsulateField_BAD_final() async { +- await resolveTestUnit(''' +-class A { +- final int test = 42; +-} +-'''); +- await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- test_encapsulateField_BAD_multipleFields() async { +- await resolveTestUnit(''' +-class A { +- int aaa, bbb, ccc; +-} +-main(A a) { +- print(a.bbb); +-} +-'''); +- await assertNoAssistAt('bbb, ', DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- test_encapsulateField_BAD_notOnName() async { +- await resolveTestUnit(''' +-class A { +- int test = 1 + 2 + 3; +-} +-'''); +- await assertNoAssistAt('+ 2', DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- test_encapsulateField_BAD_parseError() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-class A { +- int; // marker +-} +-main(A a) { +- print(a.test); +-} +-'''); +- await assertNoAssistAt('; // marker', DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- test_encapsulateField_BAD_static() async { +- await resolveTestUnit(''' +-class A { +- static int test = 42; +-} +-'''); +- await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD); +- } +- +- test_encapsulateField_OK_hasType() async { +- await resolveTestUnit(''' +-class A { +- int test = 42; +- A(this.test); +-} +-main(A a) { +- print(a.test); +-} +-'''); +- await assertHasAssistAt('test = 42', DartAssistKind.ENCAPSULATE_FIELD, ''' +-class A { +- int _test = 42; +- +- int get test => _test; +- +- void set test(int test) { +- _test = test; +- } +- A(this._test); +-} +-main(A a) { +- print(a.test); +-} +-'''); +- } +- +- test_encapsulateField_OK_noType() async { +- await resolveTestUnit(''' +-class A { +- var test = 42; +-} +-main(A a) { +- print(a.test); +-} +-'''); +- await assertHasAssistAt('test = 42', DartAssistKind.ENCAPSULATE_FIELD, ''' +-class A { +- var _test = 42; +- +- get test => _test; +- +- void set test(test) { +- _test = test; +- } +-} +-main(A a) { +- print(a.test); +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_BAD_extraLength() async { +- await resolveTestUnit(''' +-main() { +- 111 + 222; +-} +-'''); +- length = 3; +- await assertNoAssistAt('+ 222', DartAssistKind.EXCHANGE_OPERANDS); +- } +- +- test_exchangeBinaryExpressionArguments_BAD_onOperand() async { +- await resolveTestUnit(''' +-main() { +- 111 + 222; +-} +-'''); +- length = 3; +- await assertNoAssistAt('11 +', DartAssistKind.EXCHANGE_OPERANDS); +- } +- +- test_exchangeBinaryExpressionArguments_BAD_selectionWithBinary() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2 + 3; +-} +-'''); +- length = '1 + 2 + 3'.length; +- await assertNoAssistAt('1 + 2 + 3', DartAssistKind.EXCHANGE_OPERANDS); +- } +- +- test_exchangeBinaryExpressionArguments_OK_compare() async { +- const initialOperators = const ['<', '<=', '>', '>=']; +- const resultOperators = const ['>', '>=', '<', '<=']; +- for (int i = 0; i <= 0; i++) { +- String initialOperator = initialOperators[i]; +- String resultOperator = resultOperators[i]; +- await resolveTestUnit(''' +-bool main(int a, int b) { +- return a $initialOperator b; +-} +-'''); +- await assertHasAssistAt( +- initialOperator, DartAssistKind.EXCHANGE_OPERANDS, ''' +-bool main(int a, int b) { +- return b $resultOperator a; +-} +-'''); +- } +- } +- +- test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_1() async { +- await resolveTestUnit(''' +-main() { +- 1 * 2 * 3 + 4; +-} +-'''); +- await assertHasAssistAt('* 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 * 3 * 1 + 4; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_2() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2 - 3 + 4; +-} +-'''); +- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 + 1 - 3 + 4; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirst() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2 + 3; +-} +-'''); +- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 + 3 + 1; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSecond() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2 + 3; +-} +-'''); +- await assertHasAssistAt('+ 3', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 3 + 1 + 2; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_simple_afterOperator() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2; +-} +-'''); +- await assertHasAssistAt(' 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 + 1; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_simple_beforeOperator() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2; +-} +-'''); +- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 + 1; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_simple_fullSelection() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2; +-} +-'''); +- length = '1 + 2'.length; +- await assertHasAssistAt('1 + 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 + 1; +-} +-'''); +- } +- +- test_exchangeBinaryExpressionArguments_OK_simple_withLength() async { +- await resolveTestUnit(''' +-main() { +- 1 + 2; +-} +-'''); +- length = 2; +- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, ''' +-main() { +- 2 + 1; +-} +-'''); +- } +- +- test_importAddShow_BAD_hasShow() async { +- await resolveTestUnit(''' +-import 'dart:math' show PI; +-main() { +- PI; +-} +-'''); +- await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW); +- } +- +- test_importAddShow_BAD_unresolvedUri() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-import '/no/such/lib.dart'; +-'''); +- await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW); +- } +- +- test_importAddShow_BAD_unused() async { +- await resolveTestUnit(''' +-import 'dart:math'; +-'''); +- await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW); +- } +- +- test_importAddShow_OK_hasUnresolvedIdentifier() async { +- await resolveTestUnit(''' +-import 'dart:math'; +-main(x) { +- PI; +- return x.foo(); +-} +-'''); +- await assertHasAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW, ''' +-import 'dart:math' show PI; +-main(x) { +- PI; +- return x.foo(); +-} +-'''); +- } +- +- test_importAddShow_OK_onDirective() async { +- await resolveTestUnit(''' +-import 'dart:math'; +-main() { +- PI; +- E; +- max(1, 2); +-} +-'''); +- await assertHasAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW, ''' +-import 'dart:math' show E, PI, max; +-main() { +- PI; +- E; +- max(1, 2); +-} +-'''); +- } +- +- test_importAddShow_OK_onUri() async { +- await resolveTestUnit(''' +-import 'dart:math'; +-main() { +- PI; +- E; +- max(1, 2); +-} +-'''); +- await assertHasAssistAt('art:math', DartAssistKind.IMPORT_ADD_SHOW, ''' +-import 'dart:math' show E, PI, max; +-main() { +- PI; +- E; +- max(1, 2); +-} +-'''); +- } +- +- test_introduceLocalTestedType_BAD_notBlock() async { +- await resolveTestUnit(''' +-main(p) { +- if (p is String) +- print('not a block'); +-} +-'''); +- await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE); +- } +- +- test_introduceLocalTestedType_BAD_notIsExpression() async { +- await resolveTestUnit(''' +-main(p) { +- if (p == null) { +- } +-} +-'''); +- await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE); +- } +- +- test_introduceLocalTestedType_BAD_notStatement() async { +- await resolveTestUnit(''' +-class C { +- bool b; +- C(v) : b = v is int; +-}'''); +- await assertNoAssistAt('is int', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE); +- } +- +- test_introduceLocalTestedType_OK_if_is() async { +- await resolveTestUnit(''' +-class MyTypeName {} +-main(p) { +- if (p is MyTypeName) { +- } +- p = null; +-} +-'''); +- String expected = ''' +-class MyTypeName {} +-main(p) { +- if (p is MyTypeName) { +- MyTypeName myTypeName = p; +- } +- p = null; +-} +-'''; +- await assertHasAssistAt( +- 'is MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); +- _assertLinkedGroup( +- change.linkedEditGroups[0], +- ['myTypeName = '], +- expectedSuggestions(LinkedEditSuggestionKind.VARIABLE, +- ['myTypeName', 'typeName', 'name'])); +- // another good location +- await assertHasAssistAt( +- 'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); +- } +- +- test_introduceLocalTestedType_OK_if_isNot() async { +- await resolveTestUnit(''' +-class MyTypeName {} +-main(p) { +- if (p is! MyTypeName) { +- return; +- } +-} +-'''); +- String expected = ''' +-class MyTypeName {} +-main(p) { +- if (p is! MyTypeName) { +- return; +- } +- MyTypeName myTypeName = p; +-} +-'''; +- await assertHasAssistAt( +- 'is! MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); +- _assertLinkedGroup( +- change.linkedEditGroups[0], +- ['myTypeName = '], +- expectedSuggestions(LinkedEditSuggestionKind.VARIABLE, +- ['myTypeName', 'typeName', 'name'])); +- // another good location +- await assertHasAssistAt( +- 'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); +- } +- +- test_introduceLocalTestedType_OK_while() async { +- await resolveTestUnit(''' +-main(p) { +- while (p is String) { +- } +- p = null; +-} +-'''); +- String expected = ''' +-main(p) { +- while (p is String) { +- String s = p; +- } +- p = null; +-} +-'''; +- await assertHasAssistAt( +- 'is String', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); +- await assertHasAssistAt( +- 'while (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); +- } +- +- test_invalidSelection() async { +- await resolveTestUnit(''); +- offset = -1; +- length = 0; +- List assists = await _computeAssists(); +- expect(assists, isEmpty); +- } +- +- test_invertIfStatement_blocks() async { +- await resolveTestUnit(''' +-main() { +- if (true) { +- 0; +- } else { +- 1; +- } +-} +-'''); +- await assertHasAssistAt('if (', DartAssistKind.INVERT_IF_STATEMENT, ''' +-main() { +- if (false) { +- 1; +- } else { +- 0; +- } +-} +-'''); +- } +- +- test_invertIfStatement_statements() async { +- await resolveTestUnit(''' +-main() { +- if (true) +- 0; +- else +- 1; +-} +-'''); +- await assertHasAssistAt('if (', DartAssistKind.INVERT_IF_STATEMENT, ''' +-main() { +- if (false) +- 1; +- else +- 0; +-} +-'''); +- } +- +- test_joinIfStatementInner_BAD_innerNotIf() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- print(0); +- } +-} +-'''); +- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- test_joinIfStatementInner_BAD_innerWithElse() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } else { +- print(1); +- } +- } +-} +-'''); +- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- test_joinIfStatementInner_BAD_statementAfterInner() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(2); +- } +- print(1); +- } +-} +-'''); +- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- test_joinIfStatementInner_BAD_statementBeforeInner() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- print(1); +- if (2 == 2) { +- print(2); +- } +- } +-} +-'''); +- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- test_joinIfStatementInner_BAD_targetNotIf() async { +- await resolveTestUnit(''' +-main() { +- print(0); +-} +-'''); +- await assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- test_joinIfStatementInner_BAD_targetWithElse() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } +- } else { +- print(1); +- } +-} +-'''); +- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER); +- } +- +- test_joinIfStatementInner_OK_conditionAndOr() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2 || 3 == 3) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (1 == 1 && (2 == 2 || 3 == 3)) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementInner_OK_conditionInvocation() async { +- await resolveTestUnit(''' +-main() { +- if (isCheck()) { +- if (2 == 2) { +- print(0); +- } +- } +-} +-bool isCheck() => false; +-'''); +- await assertHasAssistAt( +- 'if (isCheck', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (isCheck() && 2 == 2) { +- print(0); +- } +-} +-bool isCheck() => false; +-'''); +- } +- +- test_joinIfStatementInner_OK_conditionOrAnd() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1 || 2 == 2) { +- if (3 == 3) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if ((1 == 1 || 2 == 2) && 3 == 3) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementInner_OK_onCondition() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementInner_OK_simpleConditions_block_block() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementInner_OK_simpleConditions_block_single() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) +- print(0); +- } +-} +-'''); +- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementInner_OK_simpleConditions_single_blockMulti() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(1); +- print(2); +- print(3); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(1); +- print(2); +- print(3); +- } +-} +-'''); +- } +- +- test_joinIfStatementInner_OK_simpleConditions_single_blockOne() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) +- if (2 == 2) { +- print(0); +- } +-} +-'''); +- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_BAD_outerNotIf() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- print(0); +- } +-} +-'''); +- await assertNoAssistAt('if (1 == 1', DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- test_joinIfStatementOuter_BAD_outerWithElse() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } +- } else { +- print(1); +- } +-} +-'''); +- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- test_joinIfStatementOuter_BAD_statementAfterInner() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(2); +- } +- print(1); +- } +-} +-'''); +- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- test_joinIfStatementOuter_BAD_statementBeforeInner() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- print(1); +- if (2 == 2) { +- print(2); +- } +- } +-} +-'''); +- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- test_joinIfStatementOuter_BAD_targetNotIf() async { +- await resolveTestUnit(''' +-main() { +- print(0); +-} +-'''); +- await assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- test_joinIfStatementOuter_BAD_targetWithElse() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } else { +- print(1); +- } +- } +-} +-'''); +- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER); +- } +- +- test_joinIfStatementOuter_OK_conditionAndOr() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2 || 3 == 3) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (2 ==', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && (2 == 2 || 3 == 3)) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_OK_conditionInvocation() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (isCheck()) { +- print(0); +- } +- } +-} +-bool isCheck() => false; +-'''); +- await assertHasAssistAt( +- 'if (isCheck', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && isCheck()) { +- print(0); +- } +-} +-bool isCheck() => false; +-'''); +- } +- +- test_joinIfStatementOuter_OK_conditionOrAnd() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1 || 2 == 2) { +- if (3 == 3) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (3 == 3', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if ((1 == 1 || 2 == 2) && 3 == 3) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_OK_onCondition() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_OK_simpleConditions_block_block() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(0); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_OK_simpleConditions_block_single() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) +- print(0); +- } +-} +-'''); +- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_OK_simpleConditions_single_blockMulti() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) { +- if (2 == 2) { +- print(1); +- print(2); +- print(3); +- } +- } +-} +-'''); +- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(1); +- print(2); +- print(3); +- } +-} +-'''); +- } +- +- test_joinIfStatementOuter_OK_simpleConditions_single_blockOne() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1) +- if (2 == 2) { +- print(0); +- } +-} +-'''); +- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, ''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +-} +-'''); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_hasInitializer() async { +- await resolveTestUnit(''' +-main() { +- var v = 1; +- v = 2; +-} +-'''); +- await assertNoAssistAt('v = 2', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notAdjacent() async { +- await resolveTestUnit(''' +-main() { +- var v; +- var bar; +- v = 1; +-} +-'''); +- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notAssignment() async { +- await resolveTestUnit(''' +-main() { +- var v; +- v += 1; +-} +-'''); +- await assertNoAssistAt('v += 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notDeclaration() async { +- await resolveTestUnit(''' +-main(var v) { +- v = 1; +-} +-'''); +- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notLeftArgument() async { +- await resolveTestUnit(''' +-main() { +- var v; +- 1 + v; // marker +-} +-'''); +- await assertNoAssistAt( +- 'v; // marker', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notOneVariable() async { +- await resolveTestUnit(''' +-main() { +- var v, v2; +- v = 1; +-} +-'''); +- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notResolved() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-main() { +- var v; +- x = 1; +-} +-'''); +- await assertNoAssistAt('x = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_BAD_notSameBlock() async { +- await resolveTestUnit(''' +-main() { +- var v; +- { +- v = 1; +- } +-} +-'''); +- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onAssignment_OK() async { +- await resolveTestUnit(''' +-main() { +- var v; +- v = 1; +-} +-'''); +- await assertHasAssistAt('v =', DartAssistKind.JOIN_VARIABLE_DECLARATION, ''' +-main() { +- var v = 1; +-} +-'''); +- } +- +- test_joinVariableDeclaration_onDeclaration_BAD_hasInitializer() async { +- await resolveTestUnit(''' +-main() { +- var v = 1; +- v = 2; +-} +-'''); +- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onDeclaration_BAD_lastStatement() async { +- await resolveTestUnit(''' +-main() { +- if (true) +- var v; +-} +-'''); +- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onDeclaration_BAD_nextNotAssignmentExpression() async { +- await resolveTestUnit(''' +-main() { +- var v; +- 42; +-} +-'''); +- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onDeclaration_BAD_nextNotExpressionStatement() async { +- await resolveTestUnit(''' +-main() { +- var v; +- if (true) return; +-} +-'''); +- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onDeclaration_BAD_nextNotPureAssignment() async { +- await resolveTestUnit(''' +-main() { +- var v; +- v += 1; +-} +-'''); +- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onDeclaration_BAD_notOneVariable() async { +- await resolveTestUnit(''' +-main() { +- var v, v2; +- v = 1; +-} +-'''); +- await assertNoAssistAt('v, ', DartAssistKind.JOIN_VARIABLE_DECLARATION); +- } +- +- test_joinVariableDeclaration_onDeclaration_OK_onName() async { +- await resolveTestUnit(''' +-main() { +- var v; +- v = 1; +-} +-'''); +- await assertHasAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION, ''' +-main() { +- var v = 1; +-} +-'''); +- } +- +- test_joinVariableDeclaration_onDeclaration_OK_onType() async { +- await resolveTestUnit(''' +-main() { +- int v; +- v = 1; +-} +-'''); +- await assertHasAssistAt( +- 'int v', DartAssistKind.JOIN_VARIABLE_DECLARATION, ''' +-main() { +- int v = 1; +-} +-'''); +- } +- +- test_joinVariableDeclaration_onDeclaration_OK_onVar() async { +- await resolveTestUnit(''' +-main() { +- var v; +- v = 1; +-} +-'''); +- await assertHasAssistAt( +- 'var v', DartAssistKind.JOIN_VARIABLE_DECLARATION, ''' +-main() { +- var v = 1; +-} +-'''); +- } +- +- test_moveFlutterWidgetDown_OK() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new /*caret*/GestureDetector( +- onTap: () => startResize(), +- child: new Center( +- child: new Container( +- width: 200.0, +- height: 300.0, +- ), +- key: null, +- ), +- ), +-// end +- ); +-} +-startResize() {} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.MOVE_FLUTTER_WIDGET_DOWN, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- child: new /*caret*/GestureDetector( +- onTap: () => startResize(), +- child: new Container( +- width: 200.0, +- height: 300.0, +- ), +- ), +- key: null, +- ), +-// end +- ); +-} +-startResize() {} +-'''); +- } +- +- test_moveFlutterWidgetUp_OK() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new Center( +- child: new /*caret*/GestureDetector( +- onTap: () => startResize(), +- child: new Container( +- width: 200.0, +- height: 300.0, +- ), +- ), +- key: null, +- ), +-// end +- ); +-} +-startResize() {} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.MOVE_FLUTTER_WIDGET_UP, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +-// start +- body: new /*caret*/GestureDetector( +- onTap: () => startResize(), +- child: new Center( +- child: new Container( +- width: 200.0, +- height: 300.0, +- ), +- key: null, +- ), +- ), +-// end +- ); +-} +-startResize() {} +-'''); +- } +- +- test_removeTypeAnnotation_classField_OK() async { +- await resolveTestUnit(''' +-class A { +- int v = 1; +-} +-'''); +- await assertHasAssistAt('v = ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-class A { +- var v = 1; +-} +-'''); +- } +- +- test_removeTypeAnnotation_classField_OK_final() async { +- await resolveTestUnit(''' +-class A { +- final int v = 1; +-} +-'''); +- await assertHasAssistAt('v = ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-class A { +- final v = 1; +-} +-'''); +- } +- +- test_removeTypeAnnotation_field_BAD_noInitializer() async { +- await resolveTestUnit(''' +-class A { +- int v; +-} +-'''); +- await assertNoAssistAt('v;', DartAssistKind.REMOVE_TYPE_ANNOTATION); +- } +- +- test_removeTypeAnnotation_localVariable_BAD_noInitializer() async { +- await resolveTestUnit(''' +-main() { +- int v; +-} +-'''); +- await assertNoAssistAt('v;', DartAssistKind.REMOVE_TYPE_ANNOTATION); +- } +- +- test_removeTypeAnnotation_localVariable_BAD_onInitializer() async { +- await resolveTestUnit(''' +-main() { +- final int v = 1; +-} +-'''); +- await assertNoAssistAt('1;', DartAssistKind.REMOVE_TYPE_ANNOTATION); +- } +- +- test_removeTypeAnnotation_localVariable_OK() async { +- await resolveTestUnit(''' +-main() { +- int a = 1, b = 2; +-} +-'''); +- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-main() { +- var a = 1, b = 2; +-} +-'''); +- } +- +- test_removeTypeAnnotation_localVariable_OK_const() async { +- await resolveTestUnit(''' +-main() { +- const int v = 1; +-} +-'''); +- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-main() { +- const v = 1; +-} +-'''); +- } +- +- test_removeTypeAnnotation_localVariable_OK_final() async { +- await resolveTestUnit(''' +-main() { +- final int v = 1; +-} +-'''); +- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-main() { +- final v = 1; +-} +-'''); +- } +- +- test_removeTypeAnnotation_topLevelVariable_BAD_noInitializer() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-int v; +-'''); +- await assertNoAssistAt('v;', DartAssistKind.REMOVE_TYPE_ANNOTATION); +- } +- +- test_removeTypeAnnotation_topLevelVariable_BAD_syntheticName() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-MyType +-'''); +- await assertNoAssistAt('MyType', DartAssistKind.REMOVE_TYPE_ANNOTATION); +- } +- +- test_removeTypeAnnotation_topLevelVariable_OK() async { +- await resolveTestUnit(''' +-int V = 1; +-'''); +- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-var V = 1; +-'''); +- } +- +- test_removeTypeAnnotation_topLevelVariable_OK_final() async { +- await resolveTestUnit(''' +-final int V = 1; +-'''); +- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, ''' +-final V = 1; +-'''); +- } +- +- test_reparentFlutterList_BAD_multiLine() async { +- verifyNoTestUnitErrors = false; +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +- children: [/*caret*/ +-// start +- new Transform(), +- new Object(), +- new AspectRatio(), +-// end +- ], +- ), +- ); +-} +-'''); +- _setCaretLocation(); +- await assertNoAssist(DartAssistKind.REPARENT_FLUTTER_LIST); +- } +- +- test_reparentFlutterList_BAD_singleLine() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +- var obj; +-// start +- return new Row(children: [/*caret*/ new Transform()]); +-// end +- } +-} +-'''); +- _setCaretLocation(); +- await assertNoAssist(DartAssistKind.REPARENT_FLUTTER_LIST); +- } +- +- test_reparentFlutterList_OK_multiLine() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +-// start +- children: [/*caret*/ +- new Transform(), +- new Transform(), +- new AspectRatio(), +- ], +-// end +- ), +- ); +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_LIST, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +-// start +- children: [ +- new widget( +- children: [/*caret*/ +- new Transform(), +- new Transform(), +- new AspectRatio(), +- ], +- ), +- ], +-// end +- ), +- ); +-} +-'''); +- } +- +- test_reparentFlutterWidget_BAD_minimal() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-/*caret*/x(){} +-'''); +- _setCaretLocation(); +- await assertNoAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET); +- } +- +- test_reparentFlutterWidget_BAD_singleLine() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +- var obj; +-// start +- return new Container(child: obj.xyz./*caret*/abc); +-// end +- } +-} +-'''); +- _setCaretLocation(); +- await assertNoAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET); +- } +- +- test_reparentFlutterWidget_OK_multiLines() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +- return new Container( +-// start +- child: new /*caret*/DefaultTextStyle( +- child: new Row( +- children: [ +- new Container( +- ), +- ], +- ), +- ), +-// end +- ); +- } +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +- return new Container( +-// start +- child: new widget( +- child: new /*caret*/DefaultTextStyle( +- child: new Row( +- children: [ +- new Container( +- ), +- ], +- ), +- ), +- ), +-// end +- ); +- } +-} +-'''); +- } +- +- test_reparentFlutterWidget_OK_multiLines_eol2() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart';\r +-class FakeFlutter {\r +- main() {\r +- return new Container(\r +-// start\r +- child: new /*caret*/DefaultTextStyle(\r +- child: new Row(\r +- children: [\r +- new Container(\r +- ),\r +- ],\r +- ),\r +- ),\r +-// end\r +- );\r +- }\r +-}\r +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, ''' +-import 'package:flutter/src/widgets/framework.dart';\r +-class FakeFlutter {\r +- main() {\r +- return new Container(\r +-// start\r +- child: new widget(\r +- child: new /*caret*/DefaultTextStyle(\r +- child: new Row(\r +- children: [\r +- new Container(\r +- ),\r +- ],\r +- ),\r +- ),\r +- ),\r +-// end\r +- );\r +- }\r +-}\r +-'''); +- } +- +- test_reparentFlutterWidget_OK_singleLine1() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +-// start +- return /*caret*/new Container(); +-// end +- } +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +-// start +- return /*caret*/new widget(child: new Container()); +-// end +- } +-} +-'''); +- } +- +- test_reparentFlutterWidget_OK_singleLine2() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +-// start +- return new ClipRect./*caret*/rect(); +-// end +- } +-} +-'''); +- _setCaretLocation(); +- await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-class FakeFlutter { +- main() { +-// start +- return new widget(child: new ClipRect./*caret*/rect()); +-// end +- } +-} +-'''); +- } +- +- test_replaceConditionalWithIfElse_BAD_noEnclosingStatement() async { +- await resolveTestUnit(''' +-var v = true ? 111 : 222; +-'''); +- await assertNoAssistAt( +- '? 111', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE); +- } +- +- test_replaceConditionalWithIfElse_BAD_notConditional() async { +- await resolveTestUnit(''' +-main() { +- var v = 42; +-} +-'''); +- await assertNoAssistAt( +- 'v = 42', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE); +- } +- +- test_replaceConditionalWithIfElse_OK_assignment() async { +- await resolveTestUnit(''' +-main() { +- var v; +- v = true ? 111 : 222; +-} +-'''); +- // on conditional +- await assertHasAssistAt( +- '11 :', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, ''' +-main() { +- var v; +- if (true) { +- v = 111; +- } else { +- v = 222; +- } +-} +-'''); +- // on variable +- await assertHasAssistAt( +- 'v =', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, ''' +-main() { +- var v; +- if (true) { +- v = 111; +- } else { +- v = 222; +- } +-} +-'''); +- } +- +- test_replaceConditionalWithIfElse_OK_return() async { +- await resolveTestUnit(''' +-main() { +- return true ? 111 : 222; +-} +-'''); +- await assertHasAssistAt( +- 'return ', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, ''' +-main() { +- if (true) { +- return 111; +- } else { +- return 222; +- } +-} +-'''); +- } +- +- test_replaceConditionalWithIfElse_OK_variableDeclaration() async { +- await resolveTestUnit(''' +-main() { +- int a = 1, vvv = true ? 111 : 222, b = 2; +-} +-'''); +- await assertHasAssistAt( +- '11 :', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, ''' +-main() { +- int a = 1, vvv, b = 2; +- if (true) { +- vvv = 111; +- } else { +- vvv = 222; +- } +-} +-'''); +- } +- +- test_replaceIfElseWithConditional_BAD_expressionVsReturn() async { +- await resolveTestUnit(''' +-main() { +- if (true) { +- print(42); +- } else { +- return; +- } +-} +-'''); +- await assertNoAssistAt( +- 'else', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL); +- } +- +- test_replaceIfElseWithConditional_BAD_notIfStatement() async { +- await resolveTestUnit(''' +-main() { +- print(0); +-} +-'''); +- await assertNoAssistAt( +- 'print', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL); +- } +- +- test_replaceIfElseWithConditional_BAD_notSingleStatement() async { +- await resolveTestUnit(''' +-main() { +- int vvv; +- if (true) { +- print(0); +- vvv = 111; +- } else { +- print(0); +- vvv = 222; +- } +-} +-'''); +- await assertNoAssistAt( +- 'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL); +- } +- +- test_replaceIfElseWithConditional_OK_assignment() async { +- await resolveTestUnit(''' +-main() { +- int vvv; +- if (true) { +- vvv = 111; +- } else { +- vvv = 222; +- } +-} +-'''); +- await assertHasAssistAt( +- 'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, ''' +-main() { +- int vvv; +- vvv = true ? 111 : 222; +-} +-'''); +- } +- +- test_replaceIfElseWithConditional_OK_return() async { +- await resolveTestUnit(''' +-main() { +- if (true) { +- return 111; +- } else { +- return 222; +- } +-} +-'''); +- await assertHasAssistAt( +- 'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, ''' +-main() { +- return true ? 111 : 222; +-} +-'''); +- } +- +- test_splitAndCondition_BAD_hasElse() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(1); +- } else { +- print(2); +- } +-} +-'''); +- await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION); +- } +- +- test_splitAndCondition_BAD_notAnd() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1 || 2 == 2) { +- print(0); +- } +-} +-'''); +- await assertNoAssistAt('|| 2', DartAssistKind.SPLIT_AND_CONDITION); +- } +- +- test_splitAndCondition_BAD_notPartOfIf() async { +- await resolveTestUnit(''' +-main() { +- print(1 == 1 && 2 == 2); +-} +-'''); +- await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION); +- } +- +- test_splitAndCondition_BAD_notTopLevelAnd() async { +- await resolveTestUnit(''' +-main() { +- if (true || (1 == 1 && 2 == 2)) { +- print(0); +- } +- if (true && (3 == 3 && 4 == 4)) { +- print(0); +- } +-} +-'''); +- await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION); +- await assertNoAssistAt('&& 4', DartAssistKind.SPLIT_AND_CONDITION); +- } +- +- test_splitAndCondition_OK_innerAndExpression() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1 && 2 == 2 && 3 == 3) { +- print(0); +- } +-} +-'''); +- await assertHasAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION, ''' +-main() { +- if (1 == 1) { +- if (2 == 2 && 3 == 3) { +- print(0); +- } +- } +-} +-'''); +- } +- +- test_splitAndCondition_OK_thenBlock() async { +- await resolveTestUnit(''' +-main() { +- if (true && false) { +- print(0); +- if (3 == 3) { +- print(1); +- } +- } +-} +-'''); +- await assertHasAssistAt('&& false', DartAssistKind.SPLIT_AND_CONDITION, ''' +-main() { +- if (true) { +- if (false) { +- print(0); +- if (3 == 3) { +- print(1); +- } +- } +- } +-} +-'''); +- } +- +- test_splitAndCondition_OK_thenStatement() async { +- await resolveTestUnit(''' +-main() { +- if (true && false) +- print(0); +-} +-'''); +- await assertHasAssistAt('&& false', DartAssistKind.SPLIT_AND_CONDITION, ''' +-main() { +- if (true) +- if (false) +- print(0); +-} +-'''); +- } +- +- test_splitAndCondition_wrong() async { +- await resolveTestUnit(''' +-main() { +- if (1 == 1 && 2 == 2) { +- print(0); +- } +- print(3 == 3 && 4 == 4); +-} +-'''); +- // not binary expression +- await assertNoAssistAt('main() {', DartAssistKind.SPLIT_AND_CONDITION); +- // selection is not empty and includes more than just operator +- { +- length = 5; +- await assertNoAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION); +- } +- } +- +- test_splitVariableDeclaration_BAD_notOneVariable() async { +- await resolveTestUnit(''' +-main() { +- var v = 1, v2; +-} +-'''); +- await assertNoAssistAt('v = 1', DartAssistKind.SPLIT_VARIABLE_DECLARATION); +- } +- +- test_splitVariableDeclaration_OK_onName() async { +- await resolveTestUnit(''' +-main() { +- var v = 1; +-} +-'''); +- await assertHasAssistAt( +- 'v =', DartAssistKind.SPLIT_VARIABLE_DECLARATION, ''' +-main() { +- var v; +- v = 1; +-} +-'''); +- } +- +- test_splitVariableDeclaration_OK_onType() async { +- await resolveTestUnit(''' +-main() { +- int v = 1; +-} +-'''); +- await assertHasAssistAt( +- 'int ', DartAssistKind.SPLIT_VARIABLE_DECLARATION, ''' +-main() { +- int v; +- v = 1; +-} +-'''); +- } +- +- test_splitVariableDeclaration_OK_onVar() async { +- await resolveTestUnit(''' +-main() { +- var v = 1; +-} +-'''); +- await assertHasAssistAt( +- 'var ', DartAssistKind.SPLIT_VARIABLE_DECLARATION, ''' +-main() { +- var v; +- v = 1; +-} +-'''); +- } +- +- test_surroundWith_block() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_BLOCK, ''' +-main() { +-// start +- { +- print(0); +- print(1); +- } +-// end +-} +-'''); +- } +- +- test_surroundWith_doWhile() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_DO_WHILE, ''' +-main() { +-// start +- do { +- print(0); +- print(1); +- } while (condition); +-// end +-} +-'''); +- } +- +- test_surroundWith_for() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_FOR, ''' +-main() { +-// start +- for (var v = init; condition; increment) { +- print(0); +- print(1); +- } +-// end +-} +-'''); +- } +- +- test_surroundWith_forIn() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_FOR_IN, ''' +-main() { +-// start +- for (var item in iterable) { +- print(0); +- print(1); +- } +-// end +-} +-'''); +- } +- +- test_surroundWith_if() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_IF, ''' +-main() { +-// start +- if (condition) { +- print(0); +- print(1); +- } +-// end +-} +-'''); +- } +- +- test_surroundWith_tryCatch() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_TRY_CATCH, ''' +-main() { +-// start +- try { +- print(0); +- print(1); +- } on Exception catch (e) { +- // TODO +- } +-// end +-} +-'''); +- } +- +- test_surroundWith_tryFinally() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_TRY_FINALLY, ''' +-main() { +-// start +- try { +- print(0); +- print(1); +- } finally { +- // TODO +- } +-// end +-} +-'''); +- } +- +- test_surroundWith_while() async { +- await resolveTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _setStartEndSelection(); +- await assertHasAssist(DartAssistKind.SURROUND_WITH_WHILE, ''' +-main() { +-// start +- while (condition) { +- print(0); +- print(1); +- } +-// end +-} +-'''); +- } +- +- /** +- * Computes assists and verifies that there is an assist of the given kind. +- */ +- Future _assertHasAssist(AssistKind kind) async { +- List assists = await _computeAssists(); +- for (Assist assist in assists) { +- if (assist.kind == kind) { +- return assist; +- } +- } +- throw fail('Expected to find assist $kind in\n${assists.join('\n')}'); +- } +- +- void _assertLinkedGroup(LinkedEditGroup group, List expectedStrings, +- [List expectedSuggestions]) { +- List expectedPositions = _findResultPositions(expectedStrings); +- expect(group.positions, unorderedEquals(expectedPositions)); +- if (expectedSuggestions != null) { +- expect(group.suggestions, unorderedEquals(expectedSuggestions)); +- } +- } +- +- Future> _computeAssists() async { +- CompilationUnitElement testUnitElement = +- resolutionMap.elementDeclaredByCompilationUnit(testUnit); +- DartAssistContext assistContext; +- assistContext = new _DartAssistContextForValues(testUnitElement.source, +- offset, length, driver, new AstProviderForDriver(driver), testUnit); +- AssistProcessor processor = new AssistProcessor(assistContext); +- return await processor.compute(); +- } +- +- /** +- * Configures the [SourceFactory] to have the `flutter` package in +- * `/packages/flutter/lib` folder. +- */ +- void _configureFlutterPkg(Map pathToCode) { +- pathToCode.forEach((path, code) { +- provider.newFile('$flutterPkgLibPath/$path', code); +- }); +- // configure SourceFactory +- Folder myPkgFolder = provider.getResource(flutterPkgLibPath); +- UriResolver pkgResolver = new PackageMapUriResolver(provider, { +- 'flutter': [myPkgFolder] +- }); +- SourceFactory sourceFactory = new SourceFactory( +- [new DartUriResolver(sdk), pkgResolver, resourceResolver]); +- driver.configure(sourceFactory: sourceFactory); +- // force 'flutter' resolution +- addSource( +- '/tmp/other.dart', +- pathToCode.keys +- .map((path) => "import 'package:flutter/$path';") +- .join('\n')); +- } +- +- List _findResultPositions(List searchStrings) { +- List positions = []; +- for (String search in searchStrings) { +- int offset = resultCode.indexOf(search); +- positions.add(new Position(testFile, offset)); +- } +- return positions; +- } +- +- void _setCaretLocation() { +- offset = findOffset('/*caret*/') + '/*caret*/'.length; +- length = 0; +- } +- +- void _setStartEndSelection() { +- offset = findOffset('// start\n') + '// start\n'.length; +- length = findOffset('// end') - offset; +- } +-} +- +-class _DartAssistContextForValues implements DartAssistContext { +- @override +- final Source source; +- +- @override +- final int selectionOffset; +- +- @override +- final int selectionLength; +- +- @override +- final AnalysisDriver analysisDriver; +- +- @override +- final AstProvider astProvider; +- +- @override +- final CompilationUnit unit; +- +- _DartAssistContextForValues(this.source, this.selectionOffset, +- this.selectionLength, this.analysisDriver, this.astProvider, this.unit); +-} +diff --git a/pkg/analysis_server/test/services/correction/change_test.dart b/pkg/analysis_server/test/services/correction/change_test.dart +deleted file mode 100644 +index 0dc019bb658..00000000000 +--- a/pkg/analysis_server/test/services/correction/change_test.dart ++++ /dev/null +@@ -1,296 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/constants.dart'; +-import 'package:analysis_server/src/protocol_server.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ChangeTest); +- defineReflectiveTests(EditTest); +- defineReflectiveTests(FileEditTest); +- defineReflectiveTests(LinkedEditGroupTest); +- defineReflectiveTests(LinkedEditSuggestionTest); +- defineReflectiveTests(PositionTest); +- }); +-} +- +-@reflectiveTest +-class ChangeTest { +- void test_addEdit() { +- SourceChange change = new SourceChange('msg'); +- SourceEdit edit1 = new SourceEdit(1, 2, 'a'); +- SourceEdit edit2 = new SourceEdit(1, 2, 'b'); +- expect(change.edits, hasLength(0)); +- change.addEdit('/a.dart', 0, edit1); +- expect(change.edits, hasLength(1)); +- change.addEdit('/a.dart', 0, edit2); +- expect(change.edits, hasLength(1)); +- { +- SourceFileEdit fileEdit = change.getFileEdit('/a.dart'); +- expect(fileEdit, isNotNull); +- expect(fileEdit.edits, unorderedEquals([edit1, edit2])); +- } +- } +- +- void test_getFileEdit() { +- SourceChange change = new SourceChange('msg'); +- SourceFileEdit fileEdit = new SourceFileEdit('/a.dart', 0); +- change.addFileEdit(fileEdit); +- expect(change.getFileEdit('/a.dart'), fileEdit); +- } +- +- void test_getFileEdit_empty() { +- SourceChange change = new SourceChange('msg'); +- expect(change.getFileEdit('/some.dart'), isNull); +- } +- +- void test_toJson() { +- SourceChange change = new SourceChange('msg'); +- change.addFileEdit(new SourceFileEdit('/a.dart', 1) +- ..add(new SourceEdit(1, 2, 'aaa')) +- ..add(new SourceEdit(10, 20, 'bbb'))); +- change.addFileEdit(new SourceFileEdit('/b.dart', 2) +- ..add(new SourceEdit(21, 22, 'xxx')) +- ..add(new SourceEdit(210, 220, 'yyy'))); +- { +- var group = new LinkedEditGroup.empty(); +- change.addLinkedEditGroup(group +- ..addPosition(new Position('/ga.dart', 1), 2) +- ..addPosition(new Position('/ga.dart', 10), 2)); +- group.addSuggestion( +- new LinkedEditSuggestion('AA', LinkedEditSuggestionKind.TYPE)); +- group.addSuggestion( +- new LinkedEditSuggestion('BB', LinkedEditSuggestionKind.TYPE)); +- } +- change.addLinkedEditGroup(new LinkedEditGroup.empty() +- ..addPosition(new Position('/gb.dart', 10), 5) +- ..addPosition(new Position('/gb.dart', 100), 5)); +- change.selection = new Position('/selection.dart', 42); +- var expectedJson = { +- 'message': 'msg', +- 'edits': [ +- { +- 'file': '/a.dart', +- 'fileStamp': 1, +- 'edits': [ +- {'offset': 10, 'length': 20, 'replacement': 'bbb'}, +- {'offset': 1, 'length': 2, 'replacement': 'aaa'} +- ] +- }, +- { +- 'file': '/b.dart', +- 'fileStamp': 2, +- 'edits': [ +- {'offset': 210, 'length': 220, 'replacement': 'yyy'}, +- {'offset': 21, 'length': 22, 'replacement': 'xxx'} +- ] +- } +- ], +- 'linkedEditGroups': [ +- { +- 'length': 2, +- 'positions': [ +- {'file': '/ga.dart', 'offset': 1}, +- {'file': '/ga.dart', 'offset': 10} +- ], +- 'suggestions': [ +- {'kind': 'TYPE', 'value': 'AA'}, +- {'kind': 'TYPE', 'value': 'BB'} +- ] +- }, +- { +- 'length': 5, +- 'positions': [ +- {'file': '/gb.dart', 'offset': 10}, +- {'file': '/gb.dart', 'offset': 100} +- ], +- 'suggestions': [] +- } +- ], +- 'selection': {'file': '/selection.dart', 'offset': 42} +- }; +- expect(change.toJson(), expectedJson); +- // some toString() +- change.toString(); +- } +-} +- +-@reflectiveTest +-class EditTest { +- void test_applySequence() { +- SourceEdit edit1 = new SourceEdit(5, 2, 'abc'); +- SourceEdit edit2 = new SourceEdit(1, 0, '!'); +- expect( +- SourceEdit.applySequence('0123456789', [edit1, edit2]), '0!1234abc789'); +- } +- +- void test_editFromRange() { +- SourceRange range = new SourceRange(1, 2); +- SourceEdit edit = newSourceEdit_range(range, 'foo'); +- expect(edit.offset, 1); +- expect(edit.length, 2); +- expect(edit.replacement, 'foo'); +- } +- +- void test_eqEq() { +- SourceEdit a = new SourceEdit(1, 2, 'aaa'); +- expect(a == a, isTrue); +- expect(a == new SourceEdit(1, 2, 'aaa'), isTrue); +- expect(a == this, isFalse); +- expect(a == new SourceEdit(1, 2, 'bbb'), isFalse); +- expect(a == new SourceEdit(10, 2, 'aaa'), isFalse); +- } +- +- void test_new() { +- SourceEdit edit = new SourceEdit(1, 2, 'foo', id: 'my-id'); +- expect(edit.offset, 1); +- expect(edit.length, 2); +- expect(edit.replacement, 'foo'); +- expect(edit.toJson(), +- {'offset': 1, 'length': 2, 'replacement': 'foo', 'id': 'my-id'}); +- } +- +- void test_toJson() { +- SourceEdit edit = new SourceEdit(1, 2, 'foo'); +- var expectedJson = {OFFSET: 1, LENGTH: 2, REPLACEMENT: 'foo'}; +- expect(edit.toJson(), expectedJson); +- } +-} +- +-@reflectiveTest +-class FileEditTest { +- void test_add_sorts() { +- SourceEdit edit1a = new SourceEdit(1, 0, 'a1'); +- SourceEdit edit1b = new SourceEdit(1, 0, 'a2'); +- SourceEdit edit10 = new SourceEdit(10, 1, 'b'); +- SourceEdit edit100 = new SourceEdit(100, 2, 'c'); +- SourceFileEdit fileEdit = new SourceFileEdit('/test.dart', 0); +- fileEdit.add(edit100); +- fileEdit.add(edit1a); +- fileEdit.add(edit1b); +- fileEdit.add(edit10); +- expect(fileEdit.edits, [edit100, edit10, edit1b, edit1a]); +- } +- +- void test_addAll() { +- SourceEdit edit1a = new SourceEdit(1, 0, 'a1'); +- SourceEdit edit1b = new SourceEdit(1, 0, 'a2'); +- SourceEdit edit10 = new SourceEdit(10, 1, 'b'); +- SourceEdit edit100 = new SourceEdit(100, 2, 'c'); +- SourceFileEdit fileEdit = new SourceFileEdit('/test.dart', 0); +- fileEdit.addAll([edit100, edit1a, edit10, edit1b]); +- expect(fileEdit.edits, [edit100, edit10, edit1b, edit1a]); +- } +- +- void test_new() { +- SourceFileEdit fileEdit = new SourceFileEdit('/test.dart', 100); +- fileEdit.add(new SourceEdit(1, 2, 'aaa')); +- fileEdit.add(new SourceEdit(10, 20, 'bbb')); +- expect( +- fileEdit.toString(), +- '{"file":"/test.dart","fileStamp":100,"edits":[' +- '{"offset":10,"length":20,"replacement":"bbb"},' +- '{"offset":1,"length":2,"replacement":"aaa"}]}'); +- } +- +- void test_toJson() { +- SourceFileEdit fileEdit = new SourceFileEdit('/test.dart', 100); +- fileEdit.add(new SourceEdit(1, 2, 'aaa')); +- fileEdit.add(new SourceEdit(10, 20, 'bbb')); +- var expectedJson = { +- FILE: '/test.dart', +- FILE_STAMP: 100, +- EDITS: [ +- {OFFSET: 10, LENGTH: 20, REPLACEMENT: 'bbb'}, +- {OFFSET: 1, LENGTH: 2, REPLACEMENT: 'aaa'}, +- ] +- }; +- expect(fileEdit.toJson(), expectedJson); +- } +-} +- +-@reflectiveTest +-class LinkedEditGroupTest { +- void test_new() { +- LinkedEditGroup group = new LinkedEditGroup.empty(); +- group.addPosition(new Position('/a.dart', 1), 2); +- group.addPosition(new Position('/b.dart', 10), 2); +- expect( +- group.toString(), +- '{"positions":[' +- '{"file":"/a.dart","offset":1},' +- '{"file":"/b.dart","offset":10}],"length":2,"suggestions":[]}'); +- } +- +- void test_toJson() { +- LinkedEditGroup group = new LinkedEditGroup.empty(); +- group.addPosition(new Position('/a.dart', 1), 2); +- group.addPosition(new Position('/b.dart', 10), 2); +- group.addSuggestion( +- new LinkedEditSuggestion('AA', LinkedEditSuggestionKind.TYPE)); +- group.addSuggestion( +- new LinkedEditSuggestion('BB', LinkedEditSuggestionKind.TYPE)); +- expect(group.toJson(), { +- 'length': 2, +- 'positions': [ +- {'file': '/a.dart', 'offset': 1}, +- {'file': '/b.dart', 'offset': 10} +- ], +- 'suggestions': [ +- {'kind': 'TYPE', 'value': 'AA'}, +- {'kind': 'TYPE', 'value': 'BB'} +- ] +- }); +- } +-} +- +-@reflectiveTest +-class LinkedEditSuggestionTest { +- void test_eqEq() { +- var a = new LinkedEditSuggestion('a', LinkedEditSuggestionKind.METHOD); +- var a2 = new LinkedEditSuggestion('a', LinkedEditSuggestionKind.METHOD); +- var b = new LinkedEditSuggestion('a', LinkedEditSuggestionKind.TYPE); +- var c = new LinkedEditSuggestion('c', LinkedEditSuggestionKind.METHOD); +- expect(a == a, isTrue); +- expect(a == a2, isTrue); +- expect(a == this, isFalse); +- expect(a == b, isFalse); +- expect(a == c, isFalse); +- } +-} +- +-@reflectiveTest +-class PositionTest { +- void test_eqEq() { +- Position a = new Position('/a.dart', 1); +- Position a2 = new Position('/a.dart', 1); +- Position b = new Position('/b.dart', 1); +- expect(a == a, isTrue); +- expect(a == a2, isTrue); +- expect(a == b, isFalse); +- expect(a == this, isFalse); +- } +- +- void test_hashCode() { +- Position position = new Position('/test.dart', 1); +- position.hashCode; +- } +- +- void test_new() { +- Position position = new Position('/test.dart', 1); +- expect(position.file, '/test.dart'); +- expect(position.offset, 1); +- expect(position.toString(), '{"file":"/test.dart","offset":1}'); +- } +- +- void test_toJson() { +- Position position = new Position('/test.dart', 1); +- var expectedJson = {FILE: '/test.dart', OFFSET: 1}; +- expect(position.toJson(), expectedJson); +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart +deleted file mode 100644 +index b4c7c4ded55..00000000000 +--- a/pkg/analysis_server/test/services/correction/fix_test.dart ++++ /dev/null +@@ -1,6753 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/plugin/edit/fix/fix_core.dart'; +-import 'package:analysis_server/plugin/edit/fix/fix_dart.dart'; +-import 'package:analysis_server/src/services/correction/fix.dart'; +-import 'package:analysis_server/src/services/correction/fix_internal.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/ast/standard_resolution_map.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/error/codes.dart'; +-import 'package:analyzer/src/generated/parser.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- hide AnalysisError; +-import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +-import '../../src/utilities/flutter_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FixProcessorTest); +- defineReflectiveTests(LintFixTest); +- }); +-} +- +-typedef bool AnalysisErrorFilter(AnalysisError error); +- +-/** +- * Base class for fix processor tests. +- */ +-class BaseFixProcessorTest extends AbstractSingleUnitTest { +- AnalysisErrorFilter errorFilter = (AnalysisError error) { +- return error.errorCode != HintCode.UNUSED_CATCH_CLAUSE && +- error.errorCode != HintCode.UNUSED_CATCH_STACK && +- error.errorCode != HintCode.UNUSED_ELEMENT && +- error.errorCode != HintCode.UNUSED_FIELD && +- error.errorCode != HintCode.UNUSED_LOCAL_VARIABLE; +- }; +- +- String myPkgLibPath = '/packages/my_pkg/lib'; +- +- String flutterPkgLibPath = '/packages/flutter/lib'; +- +- Fix fix; +- +- SourceChange change; +- String resultCode; +- +- assert_undefinedFunction_create_returnType_bool(String lineWithTest) async { +- await resolveTestUnit(''' +-main() { +- bool b = true; +- $lineWithTest +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- bool b = true; +- $lineWithTest +-} +- +-bool test() { +-} +-'''); +- } +- +- assertHasFix(FixKind kind, String expected, {String target}) async { +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(kind, error); +- change = fix.change; +- +- // apply to "file" +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- +- String fileContent = testCode; +- if (target != null) { +- expect(target, fileEdits.first.file); +- fileContent = provider.getFile(target).readAsStringSync(); +- } +- +- resultCode = SourceEdit.applySequence(fileContent, change.edits[0].edits); +- // verify +- expect(resultCode, expected); +- } +- +- assertNoFix(FixKind kind) async { +- AnalysisError error = await _findErrorToFix(); +- List fixes = await _computeFixes(error); +- for (Fix fix in fixes) { +- if (fix.kind == kind) { +- throw fail('Unexpected fix $kind in\n${fixes.join('\n')}'); +- } +- } +- } +- +- Position expectedPosition(String search) { +- int offset = resultCode.indexOf(search); +- return new Position(testFile, offset); +- } +- +- List expectedPositions(List patterns) { +- List positions = []; +- patterns.forEach((String search) { +- positions.add(expectedPosition(search)); +- }); +- return positions; +- } +- +- List expectedSuggestions( +- LinkedEditSuggestionKind kind, List values) { +- return values.map((value) { +- return new LinkedEditSuggestion(value, kind); +- }).toList(); +- } +- +- void setUp() { +- super.setUp(); +- verifyNoTestUnitErrors = false; +- } +- +- /** +- * Computes fixes and verifies that there is a fix of the given kind. +- */ +- Future _assertHasFix(FixKind kind, AnalysisError error) async { +- List fixes = await _computeFixes(error); +- for (Fix fix in fixes) { +- if (fix.kind == kind) { +- return fix; +- } +- } +- throw fail('Expected to find fix $kind in\n${fixes.join('\n')}'); +- } +- +- void _assertLinkedGroup(LinkedEditGroup group, List expectedStrings, +- [List expectedSuggestions]) { +- List expectedPositions = _findResultPositions(expectedStrings); +- expect(group.positions, unorderedEquals(expectedPositions)); +- if (expectedSuggestions != null) { +- expect(group.suggestions, unorderedEquals(expectedSuggestions)); +- } +- } +- +- Future> _computeErrors() async { +- return (await driver.getResult(testFile)).errors; +- } +- +- /** +- * Computes fixes for the given [error] in [testUnit]. +- */ +- Future> _computeFixes(AnalysisError error) async { +- DartFixContext fixContext = new _DartFixContextImpl( +- provider, driver, new AstProviderForDriver(driver), testUnit, error); +- return await new DefaultFixContributor().internalComputeFixes(fixContext); +- } +- +- /** +- * Configures the [SourceFactory] to have the `my_pkg` package in +- * `/packages/my_pkg/lib` folder. +- */ +- void _configureMyPkg(Map pathToCode) { +- pathToCode.forEach((path, code) { +- provider.newFile('$myPkgLibPath/$path', code); +- }); +- // configure SourceFactory +- Folder myPkgFolder = provider.getResource(myPkgLibPath); +- UriResolver pkgResolver = new PackageMapUriResolver(provider, { +- 'my_pkg': [myPkgFolder] +- }); +- SourceFactory sourceFactory = new SourceFactory( +- [new DartUriResolver(sdk), pkgResolver, resourceResolver]); +- driver.configure(sourceFactory: sourceFactory); +- // force 'my_pkg' resolution +- addSource( +- '/tmp/other.dart', +- pathToCode.keys +- .map((path) => "import 'package:my_pkg/$path';") +- .join('\n')); +- } +- +- Future _findErrorToFix() async { +- List errors = await _computeErrors(); +- if (errorFilter != null) { +- errors = errors.where(errorFilter).toList(); +- } +- expect(errors, hasLength(1)); +- return errors[0]; +- } +- +- List _findResultPositions(List searchStrings) { +- List positions = []; +- for (String search in searchStrings) { +- int offset = resultCode.indexOf(search); +- positions.add(new Position(testFile, offset)); +- } +- return positions; +- } +-} +- +-@reflectiveTest +-class FixProcessorTest extends BaseFixProcessorTest { +- test_addFieldFormalParameters_hasRequiredParameter() async { +- await resolveTestUnit(''' +-class Test { +- final int a; +- final int b; +- final int c; +- Test(this.a); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, ''' +-class Test { +- final int a; +- final int b; +- final int c; +- Test(this.a, this.b, this.c); +-} +-'''); +- } +- +- test_addFieldFormalParameters_noParameters() async { +- await resolveTestUnit(''' +-class Test { +- final int a; +- final int b; +- final int c; +- Test(); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, ''' +-class Test { +- final int a; +- final int b; +- final int c; +- Test(this.a, this.b, this.c); +-} +-'''); +- } +- +- test_addFieldFormalParameters_noRequiredParameter() async { +- await resolveTestUnit(''' +-class Test { +- final int a; +- final int b; +- final int c; +- Test([this.c]); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, ''' +-class Test { +- final int a; +- final int b; +- final int c; +- Test(this.a, this.b, [this.c]); +-} +-'''); +- } +- +- test_addFieldFormalParameters_notAllFinal() async { +- await resolveTestUnit(''' +-class Test { +- final int a; +- int b; +- final int c; +- Test(); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, ''' +-class Test { +- final int a; +- int b; +- final int c; +- Test(this.a, this.c); +-} +-'''); +- } +- +- test_addMissingParameter_function_positional_hasNamed() async { +- await resolveTestUnit(''' +-test({int a}) {} +-main() { +- test(1); +-} +-'''); +- await assertNoFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL); +- } +- +- test_addMissingParameter_function_positional_hasZero() async { +- await resolveTestUnit(''' +-test() {} +-main() { +- test(1); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, ''' +-test([int i]) {} +-main() { +- test(1); +-} +-'''); +- } +- +- test_addMissingParameter_function_required_hasNamed() async { +- await resolveTestUnit(''' +-test({int a}) {} +-main() { +- test(1); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, ''' +-test(int i, {int a}) {} +-main() { +- test(1); +-} +-'''); +- } +- +- test_addMissingParameter_function_required_hasOne() async { +- await resolveTestUnit(''' +-test(int a) {} +-main() { +- test(1, 2.0); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, ''' +-test(int a, double d) {} +-main() { +- test(1, 2.0); +-} +-'''); +- } +- +- test_addMissingParameter_function_required_hasZero() async { +- await resolveTestUnit(''' +-test() {} +-main() { +- test(1); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, ''' +-test(int i) {} +-main() { +- test(1); +-} +-'''); +- } +- +- test_addMissingParameter_method_positional_hasOne() async { +- await resolveTestUnit(''' +-class A { +- test(int a) {} +- main() { +- test(1, 2.0); +- } +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, ''' +-class A { +- test(int a, [double d]) {} +- main() { +- test(1, 2.0); +- } +-} +-'''); +- } +- +- test_addMissingParameter_method_required_hasOne() async { +- await resolveTestUnit(''' +-class A { +- test(int a) {} +- main() { +- test(1, 2.0); +- } +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, ''' +-class A { +- test(int a, double d) {} +- main() { +- test(1, 2.0); +- } +-} +-'''); +- } +- +- test_addMissingParameter_method_required_hasZero() async { +- await resolveTestUnit(''' +-class A { +- test() {} +- main() { +- test(1); +- } +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, ''' +-class A { +- test(int i) {} +- main() { +- test(1); +- } +-} +-'''); +- } +- +- test_addMissingRequiredArg_cons_flutter_children() async { +- addPackageSource( +- 'flutter', 'src/widgets/framework.dart', flutter_framework_code); +- +- _addMetaPackageSource(); +- +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-import 'package:meta/meta.dart'; +- +-class MyWidget extends Widget { +- MyWidget({@required List children}); +-} +- +-build() { +- return new MyWidget(); +-} +-'''); +- +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'package:flutter/src/widgets/framework.dart'; +-import 'package:meta/meta.dart'; +- +-class MyWidget extends Widget { +- MyWidget({@required List children}); +-} +- +-build() { +- return new MyWidget(children: [],); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_cons_single() async { +- _addMetaPackageSource(); +- addSource('/libA.dart', r''' +-library libA; +-import 'package:meta/meta.dart'; +- +-class A { +- A({@required int a}) {} +-} +-'''); +- +- await resolveTestUnit(''' +-import 'libA.dart'; +- +-main() { +- A a = new A(); +-} +-'''); +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'libA.dart'; +- +-main() { +- A a = new A(a: null); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_cons_single_closure() async { +- _addMetaPackageSource(); +- +- addSource('/libA.dart', r''' +-library libA; +-import 'package:meta/meta.dart'; +- +-typedef void VoidCallback(); +- +-class A { +- A({@required VoidCallback onPressed}) {} +-} +-'''); +- +- await resolveTestUnit(''' +-import 'libA.dart'; +- +-main() { +- A a = new A(); +-} +-'''); +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'libA.dart'; +- +-main() { +- A a = new A(onPressed: () {}); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_cons_single_closure_2() async { +- _addMetaPackageSource(); +- +- addSource('/libA.dart', r''' +-library libA; +-import 'package:meta/meta.dart'; +- +-typedef void Callback(e); +- +-class A { +- A({@required Callback callback}) {} +-} +-'''); +- +- await resolveTestUnit(''' +-import 'libA.dart'; +- +-main() { +- A a = new A(); +-} +-'''); +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'libA.dart'; +- +-main() { +- A a = new A(callback: (e) {}); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_cons_single_closure_3() async { +- _addMetaPackageSource(); +- +- addSource('/libA.dart', r''' +-library libA; +-import 'package:meta/meta.dart'; +- +-typedef void Callback(a,b,c); +- +-class A { +- A({@required Callback callback}) {} +-} +-'''); +- +- await resolveTestUnit(''' +-import 'libA.dart'; +- +-main() { +- A a = new A(); +-} +-'''); +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'libA.dart'; +- +-main() { +- A a = new A(callback: (a, b, c) {}); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_cons_single_closure_4() async { +- _addMetaPackageSource(); +- +- addSource('/libA.dart', r''' +-library libA; +-import 'package:meta/meta.dart'; +- +-typedef int Callback(int a, String b,c); +- +-class A { +- A({@required Callback callback}) {} +-} +-'''); +- +- await resolveTestUnit(''' +-import 'libA.dart'; +- +-main() { +- A a = new A(); +-} +-'''); +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'libA.dart'; +- +-main() { +- A a = new A(callback: (int a, String b, c) {}); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_cons_single_list() async { +- _addMetaPackageSource(); +- +- addSource('/libA.dart', r''' +-library libA; +-import 'package:meta/meta.dart'; +- +-class A { +- A({@required List names}) {} +-} +-'''); +- +- await resolveTestUnit(''' +-import 'libA.dart'; +- +-main() { +- A a = new A(); +-} +-'''); +- await assertHasFix( +- DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, +- ''' +-import 'libA.dart'; +- +-main() { +- A a = new A(names: []); +-} +-''', +- target: '/test.dart'); +- } +- +- test_addMissingRequiredArg_multiple() async { +- _addMetaPackageSource(); +- +- await resolveTestUnit(''' +-import 'package:meta/meta.dart'; +- +-test({@required int a, @required int bcd}) {} +-main() { +- test(a: 3); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, ''' +-import 'package:meta/meta.dart'; +- +-test({@required int a, @required int bcd}) {} +-main() { +- test(a: 3, bcd: null); +-} +-'''); +- } +- +- test_addMissingRequiredArg_multiple_2() async { +- _addMetaPackageSource(); +- +- await resolveTestUnit(''' +-import 'package:meta/meta.dart'; +- +-test({@required int a, @required int bcd}) {} +-main() { +- test(); +-} +-'''); +- +- // For now we expect one error per missing arg (dartbug.com/28830). +- List errors = await _computeErrors(); +- expect(errors, hasLength(2)); +- +- List filteredErrors = errors +- .where((e) => e.message == "The parameter 'a' is required.") +- .toList(); +- expect(filteredErrors, hasLength(1)); +- +- List fixes = await _computeFixes(filteredErrors.first); +- +- List filteredFixes = fixes +- .where((fix) => fix.change.message == "Add required argument 'a'") +- .toList(); +- expect(filteredFixes, hasLength(1)); +- change = filteredFixes.first.change; +- resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits); +- // verify +- expect(resultCode, ''' +-import 'package:meta/meta.dart'; +- +-test({@required int a, @required int bcd}) {} +-main() { +- test(a: null); +-} +-'''); +- } +- +- test_addMissingRequiredArg_single() async { +- _addMetaPackageSource(); +- +- await resolveTestUnit(''' +-import 'package:meta/meta.dart'; +- +-test({@required int abc}) {} +-main() { +- test(); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, ''' +-import 'package:meta/meta.dart'; +- +-test({@required int abc}) {} +-main() { +- test(abc: null); +-} +-'''); +- } +- +- test_addMissingRequiredArg_single_normal() async { +- _addMetaPackageSource(); +- +- await resolveTestUnit(''' +-import 'package:meta/meta.dart'; +- +-test(String x, {@required int abc}) {} +-main() { +- test("foo"); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, ''' +-import 'package:meta/meta.dart'; +- +-test(String x, {@required int abc}) {} +-main() { +- test("foo", abc: null); +-} +-'''); +- } +- +- test_addMissingRequiredArg_single_with_details() async { +- _addMetaPackageSource(); +- +- await resolveTestUnit(''' +-import 'package:meta/meta.dart'; +- +-test({@Required("Really who doesn't need an abc?") int abc}) {} +-main() { +- test(); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, ''' +-import 'package:meta/meta.dart'; +- +-test({@Required("Really who doesn't need an abc?") int abc}) {} +-main() { +- test(abc: null); +-} +-'''); +- } +- +- test_addSync_asyncFor() async { +- await resolveTestUnit(''' +-import 'dart:async'; +-void main(Stream names) { +- await for (String name in names) { +- print(name); +- } +-} +-'''); +- await assertHasFix(DartFixKind.ADD_ASYNC, ''' +-import 'dart:async'; +-Future main(Stream names) async { +- await for (String name in names) { +- print(name); +- } +-} +-'''); +- } +- +- test_addSync_BAD_nullFunctionBody() async { +- await resolveTestUnit(''' +-var F = await; +-'''); +- await assertNoFix(DartFixKind.ADD_ASYNC); +- } +- +- test_addSync_blockFunctionBody() async { +- await resolveTestUnit(''' +-foo() {} +-main() { +- await foo(); +-} +-'''); +- List errors = await _computeErrors(); +- expect(errors, hasLength(2)); +- errors.sort((a, b) => a.message.compareTo(b.message)); +- // No fix for ";". +- { +- AnalysisError error = errors[0]; +- expect(error.message, "Expected to find ';'."); +- List fixes = await _computeFixes(error); +- expect(fixes, isEmpty); +- } +- // Has fix for "await". +- { +- AnalysisError error = errors[1]; +- expect(error.message, startsWith("Undefined name 'await' in function")); +- List fixes = await _computeFixes(error); +- // has exactly one fix +- expect(fixes, hasLength(1)); +- Fix fix = fixes[0]; +- expect(fix.kind, DartFixKind.ADD_ASYNC); +- // apply to "file" +- List fileEdits = fix.change.edits; +- expect(fileEdits, hasLength(1)); +- resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits); +- // verify +- expect(resultCode, ''' +-foo() {} +-main() async { +- await foo(); +-} +-'''); +- } +- } +- +- test_addSync_expressionFunctionBody() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT; +- }; +- await resolveTestUnit(''' +-foo() {} +-main() => await foo(); +-'''); +- await assertHasFix(DartFixKind.ADD_ASYNC, ''' +-foo() {} +-main() async => await foo(); +-'''); +- } +- +- test_addSync_returnFuture() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT; +- }; +- await resolveTestUnit(''' +-foo() {} +-int main() { +- await foo(); +- return 42; +-} +-'''); +- await assertHasFix(DartFixKind.ADD_ASYNC, ''' +-import 'dart:async'; +- +-foo() {} +-Future main() async { +- await foo(); +- return 42; +-} +-'''); +- } +- +- test_addSync_returnFuture_alreadyFuture() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT; +- }; +- await resolveTestUnit(''' +-import 'dart:async'; +-foo() {} +-Future main() { +- await foo(); +- return 42; +-} +-'''); +- await assertHasFix(DartFixKind.ADD_ASYNC, ''' +-import 'dart:async'; +-foo() {} +-Future main() async { +- await foo(); +- return 42; +-} +-'''); +- } +- +- test_addSync_returnFuture_dynamic() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT; +- }; +- await resolveTestUnit(''' +-foo() {} +-dynamic main() { +- await foo(); +- return 42; +-} +-'''); +- await assertHasFix(DartFixKind.ADD_ASYNC, ''' +-foo() {} +-dynamic main() async { +- await foo(); +- return 42; +-} +-'''); +- } +- +- test_addSync_returnFuture_noType() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT; +- }; +- await resolveTestUnit(''' +-foo() {} +-main() { +- await foo(); +- return 42; +-} +-'''); +- await assertHasFix(DartFixKind.ADD_ASYNC, ''' +-foo() {} +-main() async { +- await foo(); +- return 42; +-} +-'''); +- } +- +- test_boolean() async { +- await resolveTestUnit(''' +-main() { +- boolean v; +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_BOOLEAN_WITH_BOOL, ''' +-main() { +- bool v; +-} +-'''); +- } +- +- test_canBeNullAfterNullAware_chain() async { +- await resolveTestUnit(''' +-main(x) { +- x?.a.b.c; +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_WITH_NULL_AWARE, ''' +-main(x) { +- x?.a?.b?.c; +-} +-'''); +- } +- +- test_canBeNullAfterNullAware_methodInvocation() async { +- await resolveTestUnit(''' +-main(x) { +- x?.a.b(); +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_WITH_NULL_AWARE, ''' +-main(x) { +- x?.a?.b(); +-} +-'''); +- } +- +- test_canBeNullAfterNullAware_propertyAccess() async { +- await resolveTestUnit(''' +-main(x) { +- x?.a().b; +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_WITH_NULL_AWARE, ''' +-main(x) { +- x?.a()?.b; +-} +-'''); +- } +- +- test_changeToStaticAccess_method() async { +- await resolveTestUnit(''' +-class A { +- static foo() {} +-} +-main(A a) { +- a.foo(); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, ''' +-class A { +- static foo() {} +-} +-main(A a) { +- A.foo(); +-} +-'''); +- } +- +- test_changeToStaticAccess_method_importType() async { +- addSource('/libA.dart', r''' +-library libA; +-class A { +- static foo() {} +-} +-'''); +- addSource('/libB.dart', r''' +-library libB; +-import 'libA.dart'; +-class B extends A {} +-'''); +- await resolveTestUnit(''' +-import 'libB.dart'; +-main(B b) { +- b.foo(); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, ''' +-import 'libA.dart'; +-import 'libB.dart'; +-main(B b) { +- A.foo(); +-} +-'''); +- } +- +- test_changeToStaticAccess_method_prefixLibrary() async { +- await resolveTestUnit(''' +-import 'dart:async' as pref; +-main(pref.Future f) { +- f.wait([]); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, ''' +-import 'dart:async' as pref; +-main(pref.Future f) { +- pref.Future.wait([]); +-} +-'''); +- } +- +- test_changeToStaticAccess_property() async { +- await resolveTestUnit(''' +-class A { +- static get foo => 42; +-} +-main(A a) { +- a.foo; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, ''' +-class A { +- static get foo => 42; +-} +-main(A a) { +- A.foo; +-} +-'''); +- } +- +- test_changeToStaticAccess_property_importType() async { +- addSource('/libA.dart', r''' +-library libA; +-class A { +- static get foo => null; +-} +-'''); +- addSource('/libB.dart', r''' +-library libB; +-import 'libA.dart'; +-class B extends A {} +-'''); +- await resolveTestUnit(''' +-import 'libB.dart'; +-main(B b) { +- b.foo; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, ''' +-import 'libA.dart'; +-import 'libB.dart'; +-main(B b) { +- A.foo; +-} +-'''); +- } +- +- test_changeTypeAnnotation_BAD_multipleVariables() async { +- await resolveTestUnit(''' +-main() { +- String a, b = 42; +-} +-'''); +- await assertNoFix(DartFixKind.CHANGE_TYPE_ANNOTATION); +- } +- +- test_changeTypeAnnotation_BAD_notVariableDeclaration() async { +- await resolveTestUnit(''' +-main() { +- String v; +- v = 42; +-} +-'''); +- await assertNoFix(DartFixKind.CHANGE_TYPE_ANNOTATION); +- } +- +- test_changeTypeAnnotation_OK_generic() async { +- await resolveTestUnit(''' +-main() { +- String v = []; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TYPE_ANNOTATION, ''' +-main() { +- List v = []; +-} +-'''); +- } +- +- test_changeTypeAnnotation_OK_simple() async { +- await resolveTestUnit(''' +-main() { +- String v = 'abc'.length; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TYPE_ANNOTATION, ''' +-main() { +- int v = 'abc'.length; +-} +-'''); +- } +- +- test_createClass() async { +- await resolveTestUnit(''' +-main() { +- Test v = null; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CLASS, ''' +-main() { +- Test v = null; +-} +- +-class Test { +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']); +- } +- +- test_createClass_BAD_hasUnresolvedPrefix() async { +- await resolveTestUnit(''' +-main() { +- prefix.Test v = null; +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_CLASS); +- } +- +- test_createClass_inLibraryOfPrefix() async { +- String libCode = r''' +-library my.lib; +- +-class A {} +-'''; +- addSource('/lib.dart', libCode); +- await resolveTestUnit(''' +-import 'lib.dart' as lib; +- +-main() { +- lib.A a = null; +- lib.Test t = null; +-} +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_CLASS, error); +- change = fix.change; +- // apply to "lib.dart" +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/lib.dart'); +- expect(SourceEdit.applySequence(libCode, fileEdit.edits), r''' +-library my.lib; +- +-class A {} +- +-class Test { +-} +-'''); +- expect(change.linkedEditGroups, hasLength(1)); +- } +- +- test_createClass_innerLocalFunction() async { +- await resolveTestUnit(''' +-f() { +- g() { +- Test v = null; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CLASS, ''' +-f() { +- g() { +- Test v = null; +- } +-} +- +-class Test { +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']); +- } +- +- test_createClass_itemOfList() async { +- await resolveTestUnit(''' +-main() { +- var a = [Test]; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CLASS, ''' +-main() { +- var a = [Test]; +-} +- +-class Test { +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']); +- } +- +- test_createClass_itemOfList_inAnnotation() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER; +- }; +- await resolveTestUnit(''' +-class MyAnnotation { +- const MyAnnotation(a, b); +-} +-@MyAnnotation(int, const [Test]) +-main() {} +-'''); +- await assertHasFix(DartFixKind.CREATE_CLASS, ''' +-class MyAnnotation { +- const MyAnnotation(a, b); +-} +-@MyAnnotation(int, const [Test]) +-main() {} +- +-class Test { +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']); +- } +- +- test_createConstructor_forFinalFields() async { +- errorFilter = (AnalysisError error) { +- return error.message.contains("'a'"); +- }; +- await resolveTestUnit(''' +-class Test { +- final int a; +- final int b = 2; +- final int c; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, ''' +-class Test { +- final int a; +- final int b = 2; +- final int c; +- +- Test(this.a, this.c); +-} +-'''); +- } +- +- test_createConstructor_insteadOfSyntheticDefault() async { +- await resolveTestUnit(''' +-class A { +- int field; +- +- method() {} +-} +-main() { +- new A(1, 2.0); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, ''' +-class A { +- int field; +- +- A(int i, double d); +- +- method() {} +-} +-main() { +- new A(1, 2.0); +-} +-'''); +- } +- +- test_createConstructor_named() async { +- await resolveTestUnit(''' +-class A { +- method() {} +-} +-main() { +- new A.named(1, 2.0); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, ''' +-class A { +- A.named(int i, double d); +- +- method() {} +-} +-main() { +- new A.named(1, 2.0); +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']); +- } +- +- test_createConstructor_named_emptyClassBody() async { +- await resolveTestUnit(''' +-class A {} +-main() { +- new A.named(1); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, ''' +-class A { +- A.named(int i); +-} +-main() { +- new A.named(1); +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']); +- } +- +- test_createConstructorForFinalFields_inTopLevelMethod() async { +- await resolveTestUnit(''' +-main() { +- final int v; +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS); +- } +- +- test_createConstructorForFinalFields_topLevelField() async { +- await resolveTestUnit(''' +-final int v; +-'''); +- await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS); +- } +- +- test_createConstructorSuperExplicit() async { +- await resolveTestUnit(''' +-class A { +- A(bool p1, int p2, double p3, String p4, {p5}); +-} +-class B extends A { +- B() {} +-} +-'''); +- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' +-class A { +- A(bool p1, int p2, double p3, String p4, {p5}); +-} +-class B extends A { +- B() : super(false, 0, 0.0, '') {} +-} +-'''); +- } +- +- test_createConstructorSuperExplicit_hasInitializers() async { +- await resolveTestUnit(''' +-class A { +- A(int p); +-} +-class B extends A { +- int field; +- B() : field = 42 {} +-} +-'''); +- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' +-class A { +- A(int p); +-} +-class B extends A { +- int field; +- B() : field = 42, super(0) {} +-} +-'''); +- } +- +- test_createConstructorSuperExplicit_named() async { +- await resolveTestUnit(''' +-class A { +- A.named(int p); +-} +-class B extends A { +- B() {} +-} +-'''); +- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' +-class A { +- A.named(int p); +-} +-class B extends A { +- B() : super.named(0) {} +-} +-'''); +- } +- +- test_createConstructorSuperExplicit_named_private() async { +- await resolveTestUnit(''' +-class A { +- A._named(int p); +-} +-class B extends A { +- B() {} +-} +-'''); +- await assertNoFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION); +- } +- +- test_createConstructorSuperExplicit_typeArgument() async { +- await resolveTestUnit(''' +-class A { +- A(T p); +-} +-class B extends A { +- B(); +-} +-'''); +- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' +-class A { +- A(T p); +-} +-class B extends A { +- B() : super(0); +-} +-'''); +- } +- +- test_createConstructorSuperImplicit() async { +- await resolveTestUnit(''' +-class A { +- A(p1, int p2, List p3, [int p4]); +-} +-class B extends A { +- int existingField; +- +- void existingMethod() {} +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, ''' +-class A { +- A(p1, int p2, List p3, [int p4]); +-} +-class B extends A { +- int existingField; +- +- B(p1, int p2, List p3) : super(p1, p2, p3); +- +- void existingMethod() {} +-} +-'''); +- } +- +- test_createConstructorSuperImplicit_fieldInitializer() async { +- await resolveTestUnit(''' +-class A { +- int _field; +- A(this._field); +-} +-class B extends A { +- int existingField; +- +- void existingMethod() {} +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, ''' +-class A { +- int _field; +- A(this._field); +-} +-class B extends A { +- int existingField; +- +- B(int field) : super(field); +- +- void existingMethod() {} +-} +-'''); +- } +- +- test_createConstructorSuperImplicit_importType() async { +- addSource('/libA.dart', r''' +-library libA; +-class A {} +-'''); +- addSource('/libB.dart', r''' +-library libB; +-import 'libA.dart'; +-class B { +- B(A a); +-} +-'''); +- await resolveTestUnit(''' +-import 'libB.dart'; +-class C extends B { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, ''' +-import 'libA.dart'; +-import 'libB.dart'; +-class C extends B { +- C(A a) : super(a); +-} +-'''); +- } +- +- test_createConstructorSuperImplicit_named() async { +- await resolveTestUnit(''' +-class A { +- A.named(p1, int p2); +-} +-class B extends A { +- int existingField; +- +- void existingMethod() {} +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, ''' +-class A { +- A.named(p1, int p2); +-} +-class B extends A { +- int existingField; +- +- B.named(p1, int p2) : super.named(p1, p2); +- +- void existingMethod() {} +-} +-'''); +- } +- +- test_createConstructorSuperImplicit_private() async { +- await resolveTestUnit(''' +-class A { +- A._named(p); +-} +-class B extends A { +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER); +- } +- +- test_createConstructorSuperImplicit_typeArgument() async { +- await resolveTestUnit(''' +-class C { +- final T x; +- C(this.x); +-} +-class D extends C { +-}'''); +- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, ''' +-class C { +- final T x; +- C(this.x); +-} +-class D extends C { +- D(int x) : super(x); +-}'''); +- } +- +- test_createField_BAD_inEnum() async { +- await resolveTestUnit(''' +-enum MyEnum { +- AAA, BBB +-} +-main() { +- MyEnum.foo; +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_FIELD); +- } +- +- test_createField_BAD_inSDK() async { +- await resolveTestUnit(''' +-main(List p) { +- p.foo = 1; +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_FIELD); +- } +- +- test_createField_getter_multiLevel() async { +- await resolveTestUnit(''' +-class A { +-} +-class B { +- A a; +-} +-class C { +- B b; +-} +-main(C c) { +- int v = c.b.a.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +-} +-class B { +- A a; +-} +-class C { +- B b; +-} +-main(C c) { +- int v = c.b.a.test; +-} +-'''); +- } +- +- test_createField_getter_qualified_instance() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- int v = a.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +-} +-main(A a) { +- int v = a.test; +-} +-'''); +- } +- +- test_createField_getter_qualified_instance_differentLibrary() async { +- addSource('/other.dart', ''' +-/** +- * A comment to push the offset of the braces for the following class +- * declaration past the end of the content of the test file. Used to catch an +- * index out of bounds exception that occurs when using the test source instead +- * of the target source to compute the location at which to insert the field. +- */ +-class A { +-} +-'''); +- await resolveTestUnit(''' +-import 'other.dart'; +-main(A a) { +- int v = a.test; +-} +-'''); +- await assertHasFix( +- DartFixKind.CREATE_FIELD, +- ''' +-/** +- * A comment to push the offset of the braces for the following class +- * declaration past the end of the content of the test file. Used to catch an +- * index out of bounds exception that occurs when using the test source instead +- * of the target source to compute the location at which to insert the field. +- */ +-class A { +- int test; +-} +-''', +- target: '/other.dart'); +- } +- +- test_createField_getter_qualified_instance_dynamicType() async { +- await resolveTestUnit(''' +-class A { +- B b; +- void f(Object p) { +- p == b.test; +- } +-} +-class B { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- B b; +- void f(Object p) { +- p == b.test; +- } +-} +-class B { +- var test; +-} +-'''); +- } +- +- test_createField_getter_qualified_propagatedType() async { +- await resolveTestUnit(''' +-class A { +- A get self => this; +-} +-main() { +- var a = new A(); +- int v = a.self.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +- +- A get self => this; +-} +-main() { +- var a = new A(); +- int v = a.self.test; +-} +-'''); +- } +- +- test_createField_getter_unqualified_instance_asInvocationArgument() async { +- await resolveTestUnit(''' +-class A { +- main() { +- f(test); +- } +-} +-f(String s) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- String test; +- +- main() { +- f(test); +- } +-} +-f(String s) {} +-'''); +- } +- +- test_createField_getter_unqualified_instance_assignmentRhs() async { +- await resolveTestUnit(''' +-class A { +- main() { +- int v = test; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +- +- main() { +- int v = test; +- } +-} +-'''); +- } +- +- test_createField_getter_unqualified_instance_asStatement() async { +- await resolveTestUnit(''' +-class A { +- main() { +- test; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- var test; +- +- main() { +- test; +- } +-} +-'''); +- } +- +- test_createField_hint() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- var x = a; +- int v = x.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +-} +-main(A a) { +- var x = a; +- int v = x.test; +-} +-'''); +- } +- +- test_createField_hint_setter() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- var x = a; +- x.test = 0; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +-} +-main(A a) { +- var x = a; +- x.test = 0; +-} +-'''); +- } +- +- test_createField_importType() async { +- addSource('/libA.dart', r''' +-library libA; +-class A {} +-'''); +- addSource('/libB.dart', r''' +-library libB; +-import 'libA.dart'; +-A getA() => null; +-'''); +- await resolveTestUnit(''' +-import 'libB.dart'; +-class C { +-} +-main(C c) { +- c.test = getA(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-import 'libA.dart'; +-import 'libB.dart'; +-class C { +- A test; +-} +-main(C c) { +- c.test = getA(); +-} +-'''); +- } +- +- test_createField_invalidInitializer_withoutType() async { +- await resolveTestUnit(''' +-class C { +- C(this.text); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class C { +- var text; +- +- C(this.text); +-} +-'''); +- } +- +- test_createField_invalidInitializer_withType() async { +- await resolveTestUnit(''' +-class C { +- C(String this.text); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class C { +- String text; +- +- C(String this.text); +-} +-'''); +- } +- +- test_createField_setter_generic_BAD() async { +- await resolveTestUnit(''' +-class A { +-} +-class B { +- List items; +- main(A a) { +- a.test = items; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- List test; +-} +-class B { +- List items; +- main(A a) { +- a.test = items; +- } +-} +-'''); +- } +- +- test_createField_setter_generic_OK_local() async { +- await resolveTestUnit(''' +-class A { +- List items; +- +- main(A a) { +- test = items; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- List items; +- +- List test; +- +- main(A a) { +- test = items; +- } +-} +-'''); +- } +- +- test_createField_setter_qualified_instance_hasField() async { +- await resolveTestUnit(''' +-class A { +- int aaa; +- int zzz; +- +- existingMethod() {} +-} +-main(A a) { +- a.test = 5; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int aaa; +- int zzz; +- +- int test; +- +- existingMethod() {} +-} +-main(A a) { +- a.test = 5; +-} +-'''); +- } +- +- test_createField_setter_qualified_instance_hasMethod() async { +- await resolveTestUnit(''' +-class A { +- existingMethod() {} +-} +-main(A a) { +- a.test = 5; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +- +- existingMethod() {} +-} +-main(A a) { +- a.test = 5; +-} +-'''); +- } +- +- test_createField_setter_qualified_static() async { +- await resolveTestUnit(''' +-class A { +-} +-main() { +- A.test = 5; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- static int test; +-} +-main() { +- A.test = 5; +-} +-'''); +- } +- +- test_createField_setter_unqualified_instance() async { +- await resolveTestUnit(''' +-class A { +- main() { +- test = 5; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- int test; +- +- main() { +- test = 5; +- } +-} +-'''); +- } +- +- test_createField_setter_unqualified_static() async { +- await resolveTestUnit(''' +-class A { +- static main() { +- test = 5; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FIELD, ''' +-class A { +- static int test; +- +- static main() { +- test = 5; +- } +-} +-'''); +- } +- +- test_createFile_forImport() async { +- testFile = '/my/project/bin/test.dart'; +- await resolveTestUnit(''' +-import 'my_file.dart'; +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error); +- change = fix.change; +- // validate change +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/my/project/bin/my_file.dart'); +- expect(fileEdit.fileStamp, -1); +- expect(fileEdit.edits, hasLength(1)); +- expect(fileEdit.edits[0].replacement, contains('library my_file;')); +- } +- +- test_createFile_forImport_BAD_inPackage_lib_justLib() async { +- provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package'); +- testFile = '/projects/my_package/test.dart'; +- await resolveTestUnit(''' +-import 'lib'; +-'''); +- await assertNoFix(DartFixKind.CREATE_FILE); +- } +- +- test_createFile_forImport_BAD_notDart() async { +- testFile = '/my/project/bin/test.dart'; +- await resolveTestUnit(''' +-import 'my_file.txt'; +-'''); +- await assertNoFix(DartFixKind.CREATE_FILE); +- } +- +- test_createFile_forImport_inPackage_lib() async { +- provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package'); +- testFile = '/projects/my_package/lib/test.dart'; +- provider.newFolder('/projects/my_package/lib'); +- await resolveTestUnit(''' +-import 'a/bb/c_cc/my_lib.dart'; +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error); +- change = fix.change; +- // validate change +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/projects/my_package/lib/a/bb/c_cc/my_lib.dart'); +- expect(fileEdit.fileStamp, -1); +- expect(fileEdit.edits, hasLength(1)); +- expect(fileEdit.edits[0].replacement, +- contains('library my_package.a.bb.c_cc.my_lib;')); +- } +- +- test_createFile_forImport_inPackage_test() async { +- provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package'); +- testFile = '/projects/my_package/test/misc/test_all.dart'; +- await resolveTestUnit(''' +-import 'a/bb/my_lib.dart'; +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error); +- change = fix.change; +- // validate change +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/projects/my_package/test/misc/a/bb/my_lib.dart'); +- expect(fileEdit.fileStamp, -1); +- expect(fileEdit.edits, hasLength(1)); +- expect(fileEdit.edits[0].replacement, +- contains('library my_package.test.misc.a.bb.my_lib;')); +- } +- +- test_createFile_forPart() async { +- testFile = '/my/project/bin/test.dart'; +- await resolveTestUnit(''' +-library my.lib; +-part 'my_part.dart'; +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error); +- change = fix.change; +- // validate change +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/my/project/bin/my_part.dart'); +- expect(fileEdit.fileStamp, -1); +- expect(fileEdit.edits, hasLength(1)); +- expect(fileEdit.edits[0].replacement, contains('part of my.lib;')); +- } +- +- test_createFile_forPart_inPackageLib() async { +- provider.newFile('/my/pubspec.yaml', r''' +-name: my_test +-'''); +- testFile = '/my/lib/test.dart'; +- addTestSource(''' +-library my.lib; +-part 'my_part.dart'; +-''', Uri.parse('package:my/test.dart')); +- // configure SourceFactory +- UriResolver pkgResolver = new PackageMapUriResolver(provider, { +- 'my': [provider.getResource('/my/lib')], +- }); +- SourceFactory sourceFactory = new SourceFactory( +- [new DartUriResolver(sdk), pkgResolver, resourceResolver]); +- driver.configure(sourceFactory: sourceFactory); +- testUnit = (await driver.getResult(testFile)).unit; +- // prepare fix +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error); +- change = fix.change; +- // validate change +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/my/lib/my_part.dart'); +- expect(fileEdit.fileStamp, -1); +- expect(fileEdit.edits, hasLength(1)); +- expect(fileEdit.edits[0].replacement, contains('part of my.lib;')); +- } +- +- test_createGetter_BAD_inSDK() async { +- await resolveTestUnit(''' +-main(List p) { +- int v = p.foo; +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_GETTER); +- } +- +- test_createGetter_hint_getter() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- var x = a; +- int v = x.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- int get test => null; +-} +-main(A a) { +- var x = a; +- int v = x.test; +-} +-'''); +- } +- +- test_createGetter_location_afterLastGetter() async { +- await resolveTestUnit(''' +-class A { +- int existingField; +- +- int get existingGetter => null; +- +- existingMethod() {} +-} +-main(A a) { +- int v = a.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- int existingField; +- +- int get existingGetter => null; +- +- int get test => null; +- +- existingMethod() {} +-} +-main(A a) { +- int v = a.test; +-} +-'''); +- } +- +- test_createGetter_multiLevel() async { +- await resolveTestUnit(''' +-class A { +-} +-class B { +- A a; +-} +-class C { +- B b; +-} +-main(C c) { +- int v = c.b.a.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- int get test => null; +-} +-class B { +- A a; +-} +-class C { +- B b; +-} +-main(C c) { +- int v = c.b.a.test; +-} +-'''); +- } +- +- test_createGetter_qualified_instance() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- int v = a.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- int get test => null; +-} +-main(A a) { +- int v = a.test; +-} +-'''); +- } +- +- test_createGetter_qualified_instance_differentLibrary() async { +- addSource('/other.dart', ''' +-/** +- * A comment to push the offset of the braces for the following class +- * declaration past the end of the content of the test file. Used to catch an +- * index out of bounds exception that occurs when using the test source instead +- * of the target source to compute the location at which to insert the field. +- */ +-class A { +-} +-'''); +- await resolveTestUnit(''' +-import 'other.dart'; +-main(A a) { +- int v = a.test; +-} +-'''); +- await assertHasFix( +- DartFixKind.CREATE_GETTER, +- ''' +-/** +- * A comment to push the offset of the braces for the following class +- * declaration past the end of the content of the test file. Used to catch an +- * index out of bounds exception that occurs when using the test source instead +- * of the target source to compute the location at which to insert the field. +- */ +-class A { +- int get test => null; +-} +-''', +- target: '/other.dart'); +- } +- +- test_createGetter_qualified_instance_dynamicType() async { +- await resolveTestUnit(''' +-class A { +- B b; +- void f(Object p) { +- p == b.test; +- } +-} +-class B { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- B b; +- void f(Object p) { +- p == b.test; +- } +-} +-class B { +- get test => null; +-} +-'''); +- } +- +- test_createGetter_qualified_propagatedType() async { +- await resolveTestUnit(''' +-class A { +- A get self => this; +-} +-main() { +- var a = new A(); +- int v = a.self.test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- A get self => this; +- +- int get test => null; +-} +-main() { +- var a = new A(); +- int v = a.self.test; +-} +-'''); +- } +- +- test_createGetter_setterContext() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- a.test = 42; +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_GETTER); +- } +- +- test_createGetter_unqualified_instance_asInvocationArgument() async { +- await resolveTestUnit(''' +-class A { +- main() { +- f(test); +- } +-} +-f(String s) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- String get test => null; +- +- main() { +- f(test); +- } +-} +-f(String s) {} +-'''); +- } +- +- test_createGetter_unqualified_instance_assignmentLhs() async { +- await resolveTestUnit(''' +-class A { +- main() { +- test = 42; +- } +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_GETTER); +- } +- +- test_createGetter_unqualified_instance_assignmentRhs() async { +- await resolveTestUnit(''' +-class A { +- main() { +- int v = test; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- int get test => null; +- +- main() { +- int v = test; +- } +-} +-'''); +- } +- +- test_createGetter_unqualified_instance_asStatement() async { +- await resolveTestUnit(''' +-class A { +- main() { +- test; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_GETTER, ''' +-class A { +- get test => null; +- +- main() { +- test; +- } +-} +-'''); +- } +- +- test_createLocalVariable_functionType_named() async { +- await resolveTestUnit(''' +-typedef MY_FUNCTION(int p); +-foo(MY_FUNCTION f) {} +-main() { +- foo(bar); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-typedef MY_FUNCTION(int p); +-foo(MY_FUNCTION f) {} +-main() { +- MY_FUNCTION bar; +- foo(bar); +-} +-'''); +- } +- +- test_createLocalVariable_functionType_named_generic() async { +- await resolveTestUnit(''' +-typedef MY_FUNCTION(T p); +-foo(MY_FUNCTION f) {} +-main() { +- foo(bar); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-typedef MY_FUNCTION(T p); +-foo(MY_FUNCTION f) {} +-main() { +- MY_FUNCTION bar; +- foo(bar); +-} +-'''); +- } +- +- @failingTest +- test_createLocalVariable_functionType_synthetic() async { +- await resolveTestUnit(''' +-foo(f(int p)) {} +-main() { +- foo(bar); +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_LOCAL_VARIABLE); +- } +- +- test_createLocalVariable_read_typeAssignment() async { +- await resolveTestUnit(''' +-main() { +- int a = test; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-main() { +- int test; +- int a = test; +-} +-'''); +- } +- +- test_createLocalVariable_read_typeCondition() async { +- await resolveTestUnit(''' +-main() { +- if (!test) { +- print(42); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-main() { +- bool test; +- if (!test) { +- print(42); +- } +-} +-'''); +- } +- +- test_createLocalVariable_read_typeInvocationArgument() async { +- await resolveTestUnit(''' +-main() { +- f(test); +-} +-f(String p) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-main() { +- String test; +- f(test); +-} +-f(String p) {} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['String test;']); +- _assertLinkedGroup(change.linkedEditGroups[1], ['test;', 'test);']); +- } +- +- test_createLocalVariable_read_typeInvocationTarget() async { +- await resolveTestUnit(''' +-main() { +- test.add('hello'); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-main() { +- var test; +- test.add('hello'); +-} +-'''); +- _assertLinkedGroup(change.linkedEditGroups[0], ['test;', 'test.add(']); +- } +- +- test_createLocalVariable_withImport() async { +- addPackageSource('pkg', 'a/a.dart', ''' +-class A {} +-'''); +- addPackageSource('pkg', 'b/b.dart', ''' +-class B {} +-'''); +- addPackageSource('pkg', 'c/c.dart', ''' +-import 'package:pkg/a/a.dart'; +-import 'package:pkg/b/b.dart'; +- +-class C { +- C(A a, B b); +-} +-'''); +- +- await resolveTestUnit(''' +-import 'package:pkg/a/a.dart'; +-import 'package:pkg/c/c.dart'; +- +-main() { +- A a; +- new C(a, b); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-import 'package:pkg/a/a.dart'; +-import 'package:pkg/b/b.dart'; +-import 'package:pkg/c/c.dart'; +- +-main() { +- A a; +- B b; +- new C(a, b); +-} +-'''); +- +- List groups = change.linkedEditGroups; +- expect(groups, hasLength(2)); +- LinkedEditGroup typeGroup = groups[0]; +- List typePositions = typeGroup.positions; +- expect(typePositions, hasLength(1)); +- expect(typePositions[0].offset, 112); +- LinkedEditGroup nameGroup = groups[1]; +- List groupPositions = nameGroup.positions; +- expect(groupPositions, hasLength(2)); +- expect(groupPositions[0].offset, 114); +- expect(groupPositions[1].offset, 128); +- } +- +- test_createLocalVariable_write_assignment() async { +- await resolveTestUnit(''' +-main() { +- test = 42; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-main() { +- var test = 42; +-} +-'''); +- } +- +- test_createLocalVariable_write_assignment_compound() async { +- await resolveTestUnit(''' +-main() { +- test += 42; +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, ''' +-main() { +- int test; +- test += 42; +-} +-'''); +- } +- +- test_createMissingMethodCall() async { +- await resolveTestUnit(''' +-class C implements Function { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_METHOD_CALL, ''' +-class C implements Function { +- call() { +- // TODO: implement call +- } +-} +-'''); +- } +- +- test_createMissingOverrides_field_untyped() async { +- await resolveTestUnit(''' +-class A { +- var f; +-} +- +-class B implements A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-class A { +- var f; +-} +- +-class B implements A { +- @override +- var f; +-} +-'''); +- } +- +- test_createMissingOverrides_functionTypeAlias() async { +- await resolveTestUnit(''' +-typedef int Binary(int left, int right); +- +-abstract class Emulator { +- void performBinary(Binary binary); +-} +- +-class MyEmulator extends Emulator { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-typedef int Binary(int left, int right); +- +-abstract class Emulator { +- void performBinary(Binary binary); +-} +- +-class MyEmulator extends Emulator { +- @override +- void performBinary(Binary binary) { +- // TODO: implement performBinary +- } +-} +-'''); +- } +- +- @failingTest +- test_createMissingOverrides_functionTypedParameter() async { +- await resolveTestUnit(''' +-abstract class A { +- forEach(int f(double p1, String p2)); +-} +- +-class B extends A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class A { +- forEach(int f(double p1, String p2)); +-} +- +-class B extends A { +- @override +- forEach(int f(double p1, String p2)) { +- // TODO: implement forEach +- } +-} +-'''); +- } +- +- test_createMissingOverrides_generics_typeArguments() async { +- await resolveTestUnit(''' +-class Iterator { +-} +- +-abstract class IterableMixin { +- Iterator get iterator; +-} +- +-class Test extends IterableMixin { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-class Iterator { +-} +- +-abstract class IterableMixin { +- Iterator get iterator; +-} +- +-class Test extends IterableMixin { +- // TODO: implement iterator +- @override +- Iterator get iterator => null; +-} +-'''); +- } +- +- test_createMissingOverrides_generics_typeParameters() async { +- await resolveTestUnit(''' +-abstract class ItemProvider { +- List getItems(); +-} +- +-class Test extends ItemProvider { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class ItemProvider { +- List getItems(); +-} +- +-class Test extends ItemProvider { +- @override +- List getItems() { +- // TODO: implement getItems +- } +-} +-'''); +- } +- +- test_createMissingOverrides_getter() async { +- await resolveTestUnit(''' +-abstract class A { +- get g1; +- int get g2; +-} +- +-class B extends A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class A { +- get g1; +- int get g2; +-} +- +-class B extends A { +- // TODO: implement g1 +- @override +- get g1 => null; +- +- // TODO: implement g2 +- @override +- int get g2 => null; +-} +-'''); +- } +- +- test_createMissingOverrides_importPrefix() async { +- await resolveTestUnit(''' +-import 'dart:async' as aaa; +-abstract class A { +- Map> g(aaa.Future p); +-} +- +-class B extends A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-import 'dart:async' as aaa; +-abstract class A { +- Map> g(aaa.Future p); +-} +- +-class B extends A { +- @override +- Map> g(aaa.Future p) { +- // TODO: implement g +- } +-} +-'''); +- } +- +- test_createMissingOverrides_mergeToField_getterSetter() async { +- await resolveTestUnit(''' +-class A { +- int ma; +- void mb() {} +- double mc; +-} +- +-class B implements A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-class A { +- int ma; +- void mb() {} +- double mc; +-} +- +-class B implements A { +- @override +- int ma; +- +- @override +- double mc; +- +- @override +- void mb() { +- // TODO: implement mb +- } +-} +-'''); +- } +- +- test_createMissingOverrides_method() async { +- await resolveTestUnit(''' +-abstract class A { +- m1(); +- int m2(); +- String m3(int p1, double p2, Map> p3); +- String m4(p1, p2); +- String m5(p1, [int p2 = 2, int p3, p4 = 4]); +- String m6(p1, {int p2: 2, int p3, p4: 4}); +-} +- +-class B extends A { +-} +-'''); +- String expectedCode = ''' +-abstract class A { +- m1(); +- int m2(); +- String m3(int p1, double p2, Map> p3); +- String m4(p1, p2); +- String m5(p1, [int p2 = 2, int p3, p4 = 4]); +- String m6(p1, {int p2: 2, int p3, p4: 4}); +-} +- +-class B extends A { +- @override +- m1() { +- // TODO: implement m1 +- } +- +- @override +- int m2() { +- // TODO: implement m2 +- } +- +- @override +- String m3(int p1, double p2, Map> p3) { +- // TODO: implement m3 +- } +- +- @override +- String m4(p1, p2) { +- // TODO: implement m4 +- } +- +- @override +- String m5(p1, [int p2 = 2, int p3, p4 = 4]) { +- // TODO: implement m5 +- } +- +- @override +- String m6(p1, {int p2: 2, int p3, p4: 4}) { +- // TODO: implement m6 +- } +-} +-'''; +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, expectedCode); +- // end position should be on "m1", not on "m2", "m3", etc +- { +- Position endPosition = change.selection; +- expect(endPosition, isNotNull); +- expect(endPosition.file, testFile); +- int endOffset = endPosition.offset; +- String endString = expectedCode.substring(endOffset, endOffset + 25); +- expect(endString, contains('m1')); +- expect(endString, isNot(contains('m2'))); +- expect(endString, isNot(contains('m3'))); +- expect(endString, isNot(contains('m4'))); +- expect(endString, isNot(contains('m5'))); +- expect(endString, isNot(contains('m6'))); +- } +- } +- +- test_createMissingOverrides_method_emptyClassBody() async { +- await resolveTestUnit(''' +-abstract class A { +- void foo(); +-} +- +-class B extends A {} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class A { +- void foo(); +-} +- +-class B extends A { +- @override +- void foo() { +- // TODO: implement foo +- } +-} +-'''); +- } +- +- test_createMissingOverrides_method_generic() async { +- await resolveTestUnit(''' +-class C {} +-class V {} +- +-abstract class A { +- E1 foo>(V v); +-} +- +-class B implements A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-class C {} +-class V {} +- +-abstract class A { +- E1 foo>(V v); +-} +- +-class B implements A { +- @override +- E1 foo>(V v) { +- // TODO: implement foo +- } +-} +-'''); +- } +- +- test_createMissingOverrides_method_notEmptyClassBody() async { +- await resolveTestUnit(''' +-abstract class A { +- void foo(); +-} +- +-class B extends A { +- void bar() {} +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class A { +- void foo(); +-} +- +-class B extends A { +- void bar() {} +- +- @override +- void foo() { +- // TODO: implement foo +- } +-} +-'''); +- } +- +- test_createMissingOverrides_operator() async { +- await resolveTestUnit(''' +-abstract class A { +- int operator [](int index); +- void operator []=(int index, String value); +-} +- +-class B extends A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class A { +- int operator [](int index); +- void operator []=(int index, String value); +-} +- +-class B extends A { +- @override +- int operator [](int index) { +- // TODO: implement [] +- } +- +- @override +- void operator []=(int index, String value) { +- // TODO: implement []= +- } +-} +-'''); +- } +- +- test_createMissingOverrides_setter() async { +- await resolveTestUnit(''' +-abstract class A { +- set s1(x); +- set s2(int x); +- void set s3(String x); +-} +- +-class B extends A { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, ''' +-abstract class A { +- set s1(x); +- set s2(int x); +- void set s3(String x); +-} +- +-class B extends A { +- @override +- set s1(x) { +- // TODO: implement s1 +- } +- +- @override +- set s2(int x) { +- // TODO: implement s2 +- } +- +- @override +- set s3(String x) { +- // TODO: implement s3 +- } +-} +-'''); +- } +- +- test_createNoSuchMethod() async { +- await resolveTestUnit(''' +-abstract class A { +- m1(); +- int m2(); +-} +- +-class B extends A { +- existing() {} +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_NO_SUCH_METHOD, ''' +-abstract class A { +- m1(); +- int m2(); +-} +- +-class B extends A { +- existing() {} +- +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_cascadeSecond() async { +- await resolveTestUnit(''' +-class A { +- B ma() => null; +-} +-class B { +- useFunction(int g(double a, String b)) {} +-} +- +-main() { +- A a = new A(); +- a..ma().useFunction(test); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-class A { +- B ma() => null; +-} +-class B { +- useFunction(int g(double a, String b)) {} +-} +- +-main() { +- A a = new A(); +- a..ma().useFunction(test); +-} +- +-int test(double a, String b) { +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_coreFunction() async { +- await resolveTestUnit(''' +-main() { +- useFunction(g: test); +-} +-useFunction({Function g}) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- useFunction(g: test); +-} +-useFunction({Function g}) {} +- +-test() { +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_dynamicArgument() async { +- await resolveTestUnit(''' +-main() { +- useFunction(test); +-} +-useFunction(int g(a, b)) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- useFunction(test); +-} +-useFunction(int g(a, b)) {} +- +-int test(a, b) { +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_function() async { +- await resolveTestUnit(''' +-main() { +- useFunction(test); +-} +-useFunction(int g(double a, String b)) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- useFunction(test); +-} +-useFunction(int g(double a, String b)) {} +- +-int test(double a, String b) { +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_function_namedArgument() async { +- await resolveTestUnit(''' +-main() { +- useFunction(g: test); +-} +-useFunction({int g(double a, String b)}) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- useFunction(g: test); +-} +-useFunction({int g(double a, String b)}) {} +- +-int test(double a, String b) { +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_importType() async { +- addSource('/libA.dart', r''' +-library libA; +-class A {} +-'''); +- addSource('/libB.dart', r''' +-library libB; +-import 'libA.dart'; +-useFunction(int g(A a)) {} +-'''); +- await resolveTestUnit(''' +-import 'libB.dart'; +-main() { +- useFunction(test); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-import 'libA.dart'; +-import 'libB.dart'; +-main() { +- useFunction(test); +-} +- +-int test(A a) { +-} +-'''); +- } +- +- test_creationFunction_forFunctionType_method_enclosingClass_static() async { +- await resolveTestUnit(''' +-class A { +- static foo() { +- useFunction(test); +- } +-} +-useFunction(int g(double a, String b)) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- static foo() { +- useFunction(test); +- } +- +- static int test(double a, String b) { +- } +-} +-useFunction(int g(double a, String b)) {} +-'''); +- } +- +- test_creationFunction_forFunctionType_method_enclosingClass_static2() async { +- await resolveTestUnit(''' +-class A { +- var f; +- A() : f = useFunction(test); +-} +-useFunction(int g(double a, String b)) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- var f; +- A() : f = useFunction(test); +- +- static int test(double a, String b) { +- } +-} +-useFunction(int g(double a, String b)) {} +-'''); +- } +- +- test_creationFunction_forFunctionType_method_targetClass() async { +- await resolveTestUnit(''' +-main(A a) { +- useFunction(a.test); +-} +-class A { +-} +-useFunction(int g(double a, String b)) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-main(A a) { +- useFunction(a.test); +-} +-class A { +- int test(double a, String b) { +- } +-} +-useFunction(int g(double a, String b)) {} +-'''); +- } +- +- test_creationFunction_forFunctionType_method_targetClass_hasOtherMember() async { +- await resolveTestUnit(''' +-main(A a) { +- useFunction(a.test); +-} +-class A { +- m() {} +-} +-useFunction(int g(double a, String b)) {} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-main(A a) { +- useFunction(a.test); +-} +-class A { +- m() {} +- +- int test(double a, String b) { +- } +-} +-useFunction(int g(double a, String b)) {} +-'''); +- } +- +- test_creationFunction_forFunctionType_notFunctionType() async { +- await resolveTestUnit(''' +-main(A a) { +- useFunction(a.test); +-} +-typedef A(); +-useFunction(g) {} +-'''); +- await assertNoFix(DartFixKind.CREATE_METHOD); +- await assertNoFix(DartFixKind.CREATE_FUNCTION); +- } +- +- test_creationFunction_forFunctionType_unknownTarget() async { +- await resolveTestUnit(''' +-main(A a) { +- useFunction(a.test); +-} +-class A { +-} +-useFunction(g) {} +-'''); +- await assertNoFix(DartFixKind.CREATE_METHOD); +- } +- +- test_expectedToken_semicolon() async { +- await resolveTestUnit(''' +-main() { +- print(0) +-} +-'''); +- await assertHasFix(DartFixKind.INSERT_SEMICOLON, ''' +-main() { +- print(0); +-} +-'''); +- } +- +- test_illegalAsyncReturnType_adjacentNodes() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE; +- }; +- await resolveTestUnit(''' +-import 'dart:async'; +-var v;int main() async => 0; +-'''); +- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, ''' +-import 'dart:async'; +-var v;Future main() async => 0; +-'''); +- } +- +- test_illegalAsyncReturnType_asyncLibrary_import() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE; +- }; +- await resolveTestUnit(''' +-library main; +-int main() async { +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, ''' +-library main; +- +-import 'dart:async'; +- +-Future main() async { +-} +-'''); +- } +- +- test_illegalAsyncReturnType_asyncLibrary_usePrefix() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE; +- }; +- await resolveTestUnit(''' +-import 'dart:async' as al; +-int main() async { +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, ''' +-import 'dart:async' as al; +-al.Future main() async { +-} +-'''); +- } +- +- test_illegalAsyncReturnType_complexTypeName() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE; +- }; +- await resolveTestUnit(''' +-import 'dart:async'; +-List main() async { +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, ''' +-import 'dart:async'; +-Future> main() async { +-} +-'''); +- } +- +- test_illegalAsyncReturnType_void() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE; +- }; +- await resolveTestUnit(''' +-import 'dart:async'; +-void main() async { +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, ''' +-import 'dart:async'; +-Future main() async { +-} +-'''); +- } +- +- test_importLibraryPackage_preferDirectOverExport() async { +- _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"}); +- await resolveTestUnit(''' +-main() { +- Test test = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'package:my_pkg/b.dart'; +- +-main() { +- Test test = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT2, ''' +-import 'package:my_pkg/a.dart'; +- +-main() { +- Test test = null; +-} +-'''); +- } +- +- test_importLibraryPackage_preferDirectOverExport_src() async { +- myPkgLibPath = '/my/src/packages/my_pkg/lib'; +- _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"}); +- await resolveTestUnit(''' +-main() { +- Test test = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'package:my_pkg/b.dart'; +- +-main() { +- Test test = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT2, ''' +-import 'package:my_pkg/a.dart'; +- +-main() { +- Test test = null; +-} +-'''); +- } +- +- test_importLibraryPackage_preferPublicOverPrivate() async { +- _configureMyPkg( +- {'src/a.dart': 'class Test {}', 'b.dart': "export 'src/a.dart';"}); +- await resolveTestUnit(''' +-main() { +- Test test = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT2, ''' +-import 'package:my_pkg/b.dart'; +- +-main() { +- Test test = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT3, ''' +-import 'package:my_pkg/src/a.dart'; +- +-main() { +- Test test = null; +-} +-'''); +- } +- +- test_importLibraryProject_BAD_notInLib_BUILD() async { +- testFile = '/aaa/bin/test.dart'; +- provider.newFile('/aaa/BUILD', ''); +- provider.newFile('/bbb/BUILD', ''); +- addSource('/bbb/test/lib.dart', 'class Test {}'); +- await resolveTestUnit(''' +-main() { +- Test t; +-} +-'''); +- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT1); +- } +- +- test_importLibraryProject_BAD_notInLib_pubspec() async { +- testFile = '/aaa/bin/test.dart'; +- provider.newFile('/aaa/pubspec.yaml', 'name: aaa'); +- provider.newFile('/bbb/pubspec.yaml', 'name: bbb'); +- addSource('/bbb/test/lib.dart', 'class Test {}'); +- await resolveTestUnit(''' +-main() { +- Test t; +-} +-'''); +- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT1); +- } +- +- test_importLibraryProject_withClass_annotation() async { +- addSource('/lib.dart', ''' +-library lib; +-class Test { +- const Test(int p); +-} +-'''); +- await resolveTestUnit(''' +-@Test(0) +-main() { +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-@Test(0) +-main() { +-} +-'''); +- } +- +- test_importLibraryProject_withClass_constInstanceCreation() async { +- addSource('/lib.dart', ''' +-class Test { +- const Test(); +-} +-'''); +- await resolveTestUnit(''' +-main() { +- const Test(); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-main() { +- const Test(); +-} +-'''); +- } +- +- test_importLibraryProject_withClass_hasOtherLibraryWithPrefix() async { +- testFile = '/project/bin/test.dart'; +- addSource('/project/bin/a.dart', ''' +-library a; +-class One {} +-'''); +- addSource('/project/bin/b.dart', ''' +-library b; +-class One {} +-class Two {} +-'''); +- await resolveTestUnit(''' +-import 'b.dart' show Two; +-main () { +- new Two(); +- new One(); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'a.dart'; +-import 'b.dart' show Two; +-main () { +- new Two(); +- new One(); +-} +-'''); +- } +- +- test_importLibraryProject_withClass_inParentFolder() async { +- testFile = '/project/bin/test.dart'; +- addSource('/project/lib.dart', ''' +-library lib; +-class Test {} +-'''); +- await resolveTestUnit(''' +-main() { +- Test t = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import '../lib.dart'; +- +-main() { +- Test t = null; +-} +-'''); +- } +- +- test_importLibraryProject_withClass_inRelativeFolder() async { +- testFile = '/project/bin/test.dart'; +- addSource('/project/lib/sub/folder/lib.dart', ''' +-library lib; +-class Test {} +-'''); +- await resolveTestUnit(''' +-main() { +- Test t = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import '../lib/sub/folder/lib.dart'; +- +-main() { +- Test t = null; +-} +-'''); +- } +- +- test_importLibraryProject_withClass_inSameFolder() async { +- testFile = '/project/bin/test.dart'; +- addSource('/project/bin/lib.dart', ''' +-library lib; +-class Test {} +-'''); +- await resolveTestUnit(''' +-main() { +- Test t = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-main() { +- Test t = null; +-} +-'''); +- } +- +- test_importLibraryProject_withFunction() async { +- addSource('/lib.dart', ''' +-library lib; +-myFunction() {} +-'''); +- await resolveTestUnit(''' +-main() { +- myFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-main() { +- myFunction(); +-} +-'''); +- } +- +- test_importLibraryProject_withFunction_unresolvedMethod() async { +- addSource('/lib.dart', ''' +-library lib; +-myFunction() {} +-'''); +- await resolveTestUnit(''' +-class A { +- main() { +- myFunction(); +- } +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-class A { +- main() { +- myFunction(); +- } +-} +-'''); +- } +- +- test_importLibraryProject_withFunctionTypeAlias() async { +- testFile = '/project/bin/test.dart'; +- addSource('/project/bin/lib.dart', ''' +-library lib; +-typedef MyFunction(); +-'''); +- await resolveTestUnit(''' +-main() { +- MyFunction t = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-main() { +- MyFunction t = null; +-} +-'''); +- } +- +- test_importLibraryProject_withTopLevelVariable() async { +- addSource('/lib.dart', ''' +-library lib; +-int MY_VAR = 42; +-'''); +- await resolveTestUnit(''' +-main() { +- print(MY_VAR); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, ''' +-import 'lib.dart'; +- +-main() { +- print(MY_VAR); +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_AsExpression() async { +- await resolveTestUnit(''' +-main(p) { +- p as Future; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main(p) { +- p as Future; +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_invocationTarget() async { +- await resolveTestUnit(''' +-main() { +- Future.wait(null); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main() { +- Future.wait(null); +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_IsExpression() async { +- await resolveTestUnit(''' +-main(p) { +- p is Future; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main(p) { +- p is Future; +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_itemOfList() async { +- await resolveTestUnit(''' +-main() { +- var a = [Future]; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main() { +- var a = [Future]; +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_itemOfList_inAnnotation() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER; +- }; +- await resolveTestUnit(''' +-class MyAnnotation { +- const MyAnnotation(a, b); +-} +-@MyAnnotation(int, const [Future]) +-main() {} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-class MyAnnotation { +- const MyAnnotation(a, b); +-} +-@MyAnnotation(int, const [Future]) +-main() {} +-'''); +- } +- +- test_importLibrarySdk_withClass_typeAnnotation() async { +- await resolveTestUnit(''' +-main() { +- Future f = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main() { +- Future f = null; +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_typeAnnotation_PrefixedIdentifier() async { +- await resolveTestUnit(''' +-main() { +- Future.wait; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main() { +- Future.wait; +-} +-'''); +- } +- +- test_importLibrarySdk_withClass_typeArgument() async { +- await resolveTestUnit(''' +-main() { +- List futures = []; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:async'; +- +-main() { +- List futures = []; +-} +-'''); +- } +- +- test_importLibrarySdk_withTopLevelVariable() async { +- await resolveTestUnit(''' +-main() { +- print(PI); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:math'; +- +-main() { +- print(PI); +-} +-'''); +- } +- +- test_importLibrarySdk_withTopLevelVariable_annotation() async { +- await resolveTestUnit(''' +-@PI +-main() { +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, ''' +-import 'dart:math'; +- +-@PI +-main() { +-} +-'''); +- } +- +- test_importLibraryShow_project() async { +- testFile = '/project/bin/test.dart'; +- addSource('/project/bin/lib.dart', ''' +-class A {} +-class B {} +-'''); +- await resolveTestUnit(''' +-import 'lib.dart' show A; +-main() { +- A a; +- B b; +-} +-'''); +- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT1); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SHOW, ''' +-import 'lib.dart' show A, B; +-main() { +- A a; +- B b; +-} +-'''); +- } +- +- test_importLibraryShow_sdk() async { +- await resolveTestUnit(''' +-import 'dart:async' show Stream; +-main() { +- Stream s = null; +- Future f = null; +-} +-'''); +- await assertNoFix(DartFixKind.IMPORT_LIBRARY_SDK); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SHOW, ''' +-import 'dart:async' show Future, Stream; +-main() { +- Stream s = null; +- Future f = null; +-} +-'''); +- } +- +- test_invokeConstructorUsingNew() async { +- await resolveTestUnit(''' +-class C { +- C.c(); +-} +-main() { +- C c = C.c(); +-} +-'''); +- await assertHasFix(DartFixKind.INVOKE_CONSTRUCTOR_USING_NEW, ''' +-class C { +- C.c(); +-} +-main() { +- C c = new C.c(); +-} +-'''); +- } +- +- test_isNotNull() async { +- await resolveTestUnit(''' +-main(p) { +- p is! Null; +-} +-'''); +- await assertHasFix(DartFixKind.USE_NOT_EQ_NULL, ''' +-main(p) { +- p != null; +-} +-'''); +- } +- +- test_isNull() async { +- await resolveTestUnit(''' +-main(p) { +- p is Null; +-} +-'''); +- await assertHasFix(DartFixKind.USE_EQ_EQ_NULL, ''' +-main(p) { +- p == null; +-} +-'''); +- } +- +- test_makeEnclosingClassAbstract_declaresAbstractMethod() async { +- await resolveTestUnit(''' +-class A { +- m(); +-} +-'''); +- await assertHasFix(DartFixKind.MAKE_CLASS_ABSTRACT, ''' +-abstract class A { +- m(); +-} +-'''); +- } +- +- test_makeEnclosingClassAbstract_inheritsAbstractMethod() async { +- await resolveTestUnit(''' +-abstract class A { +- m(); +-} +-class B extends A { +-} +-'''); +- await assertHasFix(DartFixKind.MAKE_CLASS_ABSTRACT, ''' +-abstract class A { +- m(); +-} +-abstract class B extends A { +-} +-'''); +- } +- +- test_makeFieldNotFinal_hasType() async { +- await resolveTestUnit(''' +-class A { +- final int fff = 1; +- main() { +- fff = 2; +- } +-} +-'''); +- await assertHasFix(DartFixKind.MAKE_FIELD_NOT_FINAL, ''' +-class A { +- int fff = 1; +- main() { +- fff = 2; +- } +-} +-'''); +- } +- +- test_makeFieldNotFinal_noType() async { +- await resolveTestUnit(''' +-class A { +- final fff = 1; +- main() { +- fff = 2; +- } +-} +-'''); +- await assertHasFix(DartFixKind.MAKE_FIELD_NOT_FINAL, ''' +-class A { +- var fff = 1; +- main() { +- fff = 2; +- } +-} +-'''); +- } +- +- test_noException_1() async { +- await resolveTestUnit(''' +-main(p) { +- p i s Null; +-}'''); +- List errors = await _computeErrors(); +- for (var error in errors) { +- await _computeFixes(error); +- } +- } +- +- test_nonBoolCondition_addNotNull() async { +- await resolveTestUnit(''' +-main(String p) { +- if (p) { +- print(p); +- } +-} +-'''); +- await assertHasFix(DartFixKind.ADD_NE_NULL, ''' +-main(String p) { +- if (p != null) { +- print(p); +- } +-} +-'''); +- } +- +- test_removeDeadCode_condition() async { +- await resolveTestUnit(''' +-main(int p) { +- if (true || p > 5) { +- print(1); +- } +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_DEAD_CODE, ''' +-main(int p) { +- if (true) { +- print(1); +- } +-} +-'''); +- } +- +- test_removeDeadCode_statements_one() async { +- await resolveTestUnit(''' +-int main() { +- print(0); +- return 42; +- print(1); +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_DEAD_CODE, ''' +-int main() { +- print(0); +- return 42; +-} +-'''); +- } +- +- test_removeDeadCode_statements_two() async { +- await resolveTestUnit(''' +-int main() { +- print(0); +- return 42; +- print(1); +- print(2); +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_DEAD_CODE, ''' +-int main() { +- print(0); +- return 42; +-} +-'''); +- } +- +- test_removeParentheses_inGetterDeclaration() async { +- await resolveTestUnit(''' +-class A { +- int get foo() => 0; +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, ''' +-class A { +- int get foo => 0; +-} +-'''); +- } +- +- test_removeParentheses_inGetterInvocation() async { +- await resolveTestUnit(''' +-class A { +- int get foo => 0; +-} +-main(A a) { +- a.foo(); +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, ''' +-class A { +- int get foo => 0; +-} +-main(A a) { +- a.foo; +-} +-'''); +- } +- +- test_removeUnnecessaryCast_assignment() async { +- await resolveTestUnit(''' +-main(Object p) { +- if (p is String) { +- String v = ((p as String)); +- } +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_UNNECESSARY_CAST, ''' +-main(Object p) { +- if (p is String) { +- String v = p; +- } +-} +-'''); +- } +- +- test_removeUnusedCatchClause() async { +- errorFilter = (AnalysisError error) => true; +- await resolveTestUnit(''' +-main() { +- try { +- throw 42; +- } on int catch (e) { +- } +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE, ''' +-main() { +- try { +- throw 42; +- } on int { +- } +-} +-'''); +- } +- +- test_removeUnusedCatchStack() async { +- errorFilter = (AnalysisError error) => true; +- await resolveTestUnit(''' +-main() { +- try { +- throw 42; +- } catch (e, stack) { +- } +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_UNUSED_CATCH_STACK, ''' +-main() { +- try { +- throw 42; +- } catch (e) { +- } +-} +-'''); +- } +- +- test_removeUnusedImport() async { +- await resolveTestUnit(''' +-import 'dart:math'; +-main() { +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, ''' +-main() { +-} +-'''); +- } +- +- test_removeUnusedImport_anotherImportOnLine() async { +- await resolveTestUnit(''' +-import 'dart:math'; import 'dart:async'; +- +-main() { +- Future f; +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, ''' +-import 'dart:async'; +- +-main() { +- Future f; +-} +-'''); +- } +- +- test_removeUnusedImport_severalLines() async { +- await resolveTestUnit(''' +-import +- 'dart:math'; +-main() { +-} +-'''); +- await assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, ''' +-main() { +-} +-'''); +- } +- +- test_replaceVarWithDynamic() async { +- errorFilter = (AnalysisError error) { +- return error.errorCode == ParserErrorCode.VAR_AS_TYPE_NAME; +- }; +- await resolveTestUnit(''' +-class A { +- Map m; +-} +-'''); +- await assertHasFix(DartFixKind.REPLACE_VAR_WITH_DYNAMIC, ''' +-class A { +- Map m; +-} +-'''); +- } +- +- test_replaceWithConstInstanceCreation() async { +- await resolveTestUnit(''' +-class A { +- const A(); +-} +-const a = new A(); +-'''); +- await assertHasFix(DartFixKind.USE_CONST, ''' +-class A { +- const A(); +-} +-const a = const A(); +-'''); +- } +- +- test_undefinedClass_useSimilar_BAD_prefixed() async { +- await resolveTestUnit(''' +-import 'dart:async' as c; +-main() { +- c.Fture v = null; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-import 'dart:async' as c; +-main() { +- c.Future v = null; +-} +-'''); +- } +- +- test_undefinedClass_useSimilar_fromImport() async { +- await resolveTestUnit(''' +-main() { +- Stirng s = 'abc'; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-main() { +- String s = 'abc'; +-} +-'''); +- } +- +- test_undefinedClass_useSimilar_fromThisLibrary() async { +- await resolveTestUnit(''' +-class MyClass {} +-main() { +- MyCalss v = null; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class MyClass {} +-main() { +- MyClass v = null; +-} +-'''); +- } +- +- test_undefinedFunction_create_bottomArgument() async { +- await resolveTestUnit(''' +-main() { +- test(throw 42); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- test(throw 42); +-} +- +-void test(param0) { +-} +-'''); +- } +- +- test_undefinedFunction_create_duplicateArgumentNames() async { +- await resolveTestUnit(''' +-class C { +- int x; +-} +- +-foo(C c1, C c2) { +- bar(c1.x, c2.x); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-class C { +- int x; +-} +- +-foo(C c1, C c2) { +- bar(c1.x, c2.x); +-} +- +-void bar(int x, int x2) { +-} +-'''); +- } +- +- test_undefinedFunction_create_dynamicArgument() async { +- await resolveTestUnit(''' +-main() { +- dynamic v; +- test(v); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- dynamic v; +- test(v); +-} +- +-void test(v) { +-} +-'''); +- } +- +- test_undefinedFunction_create_dynamicReturnType() async { +- await resolveTestUnit(''' +-main() { +- dynamic v = test(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- dynamic v = test(); +-} +- +-test() { +-} +-'''); +- } +- +- test_undefinedFunction_create_fromFunction() async { +- await resolveTestUnit(''' +-main() { +- int v = myUndefinedFunction(1, 2.0, '3'); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- int v = myUndefinedFunction(1, 2.0, '3'); +-} +- +-int myUndefinedFunction(int i, double d, String s) { +-} +-'''); +- } +- +- test_undefinedFunction_create_fromMethod() async { +- await resolveTestUnit(''' +-class A { +- main() { +- int v = myUndefinedFunction(1, 2.0, '3'); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-class A { +- main() { +- int v = myUndefinedFunction(1, 2.0, '3'); +- } +-} +- +-int myUndefinedFunction(int i, double d, String s) { +-} +-'''); +- } +- +- test_undefinedFunction_create_generic_BAD() async { +- await resolveTestUnit(''' +-class A { +- Map items; +- main() { +- process(items); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-class A { +- Map items; +- main() { +- process(items); +- } +-} +- +-void process(Map items) { +-} +-'''); +- } +- +- test_undefinedFunction_create_generic_OK() async { +- await resolveTestUnit(''' +-class A { +- List items; +- main() { +- process(items); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-class A { +- List items; +- main() { +- process(items); +- } +-} +- +-void process(List items) { +-} +-'''); +- _assertLinkedGroup( +- change.linkedEditGroups[2], +- ['List items) {'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['List', 'Iterable', 'Object'])); +- } +- +- test_undefinedFunction_create_importType() async { +- addSource('/lib.dart', r''' +-library lib; +-import 'dart:async'; +-Future getFuture() => null; +-'''); +- await resolveTestUnit(''' +-import 'lib.dart'; +-main() { +- test(getFuture()); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-import 'dart:async'; +- +-import 'lib.dart'; +-main() { +- test(getFuture()); +-} +- +-void test(Future future) { +-} +-'''); +- } +- +- test_undefinedFunction_create_nullArgument() async { +- await resolveTestUnit(''' +-main() { +- test(null); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- test(null); +-} +- +-void test(param0) { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_bool_expressions() async { +- await assert_undefinedFunction_create_returnType_bool("!test();"); +- await assert_undefinedFunction_create_returnType_bool("b && test();"); +- await assert_undefinedFunction_create_returnType_bool("test() && b;"); +- await assert_undefinedFunction_create_returnType_bool("b || test();"); +- await assert_undefinedFunction_create_returnType_bool("test() || b;"); +- } +- +- test_undefinedFunction_create_returnType_bool_statements() async { +- await assert_undefinedFunction_create_returnType_bool("assert ( test() );"); +- await assert_undefinedFunction_create_returnType_bool("if ( test() ) {}"); +- await assert_undefinedFunction_create_returnType_bool( +- "while ( test() ) {}"); +- await assert_undefinedFunction_create_returnType_bool( +- "do {} while ( test() );"); +- } +- +- test_undefinedFunction_create_returnType_fromAssignment_eq() async { +- await resolveTestUnit(''' +-main() { +- int v; +- v = myUndefinedFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- int v; +- v = myUndefinedFunction(); +-} +- +-int myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_fromAssignment_plusEq() async { +- await resolveTestUnit(''' +-main() { +- int v; +- v += myUndefinedFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- int v; +- v += myUndefinedFunction(); +-} +- +-num myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_fromBinary_right() async { +- await resolveTestUnit(''' +-main() { +- 0 + myUndefinedFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- 0 + myUndefinedFunction(); +-} +- +-num myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_fromInitializer() async { +- await resolveTestUnit(''' +-main() { +- int v = myUndefinedFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- int v = myUndefinedFunction(); +-} +- +-int myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_fromInvocationArgument() async { +- await resolveTestUnit(''' +-foo(int p) {} +-main() { +- foo( myUndefinedFunction() ); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-foo(int p) {} +-main() { +- foo( myUndefinedFunction() ); +-} +- +-int myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_fromReturn() async { +- await resolveTestUnit(''' +-int main() { +- return myUndefinedFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-int main() { +- return myUndefinedFunction(); +-} +- +-int myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_create_returnType_void() async { +- await resolveTestUnit(''' +-main() { +- myUndefinedFunction(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_FUNCTION, ''' +-main() { +- myUndefinedFunction(); +-} +- +-void myUndefinedFunction() { +-} +-'''); +- } +- +- test_undefinedFunction_useSimilar_fromImport() async { +- await resolveTestUnit(''' +-main() { +- pritn(0); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-main() { +- print(0); +-} +-'''); +- } +- +- test_undefinedFunction_useSimilar_prefixed_fromImport() async { +- await resolveTestUnit(''' +-import 'dart:core' as c; +-main() { +- c.prnt(42); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-import 'dart:core' as c; +-main() { +- c.print(42); +-} +-'''); +- } +- +- test_undefinedFunction_useSimilar_prefixed_ignoreLocal() async { +- await resolveTestUnit(''' +-import 'dart:async' as c; +-main() { +- c.main(); +-} +-'''); +- await assertNoFix(DartFixKind.CHANGE_TO); +- } +- +- test_undefinedFunction_useSimilar_thisLibrary() async { +- await resolveTestUnit(''' +-myFunction() {} +-main() { +- myFuntcion(); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-myFunction() {} +-main() { +- myFunction(); +-} +-'''); +- } +- +- test_undefinedGetter_useSimilar_hint() async { +- await resolveTestUnit(''' +-class A { +- int myField; +-} +-main(A a) { +- var x = a; +- print(x.myFild); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- int myField; +-} +-main(A a) { +- var x = a; +- print(x.myField); +-} +-'''); +- } +- +- test_undefinedGetter_useSimilar_qualified() async { +- await resolveTestUnit(''' +-class A { +- int myField; +-} +-main(A a) { +- print(a.myFild); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- int myField; +-} +-main(A a) { +- print(a.myField); +-} +-'''); +- } +- +- test_undefinedGetter_useSimilar_qualified_static() async { +- await resolveTestUnit(''' +-class A { +- static int MY_NAME = 1; +-} +-main() { +- A.MY_NAM; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- static int MY_NAME = 1; +-} +-main() { +- A.MY_NAME; +-} +-'''); +- } +- +- test_undefinedGetter_useSimilar_unqualified() async { +- await resolveTestUnit(''' +-class A { +- int myField; +- main() { +- print(myFild); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- int myField; +- main() { +- print(myField); +- } +-} +-'''); +- } +- +- test_undefinedMethod_create_BAD_inSDK() async { +- await resolveTestUnit(''' +-main() { +- List.foo(); +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_METHOD); +- } +- +- test_undefinedMethod_create_BAD_targetIsEnum() async { +- await resolveTestUnit(''' +-enum MyEnum {A, B} +-main() { +- MyEnum.foo(); +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_METHOD); +- } +- +- test_undefinedMethod_create_generic_BAD_argumentType() async { +- await resolveTestUnit(''' +-class A { +- B b; +- Map items; +- main() { +- b.process(items); +- } +-} +- +-class B { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- B b; +- Map items; +- main() { +- b.process(items); +- } +-} +- +-class B { +- void process(Map items) {} +-} +-'''); +- } +- +- test_undefinedMethod_create_generic_BAD_returnType() async { +- await resolveTestUnit(''' +-class A { +- main() { +- T t = new B().compute(); +- } +-} +- +-class B { +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- main() { +- T t = new B().compute(); +- } +-} +- +-class B { +- compute() {} +-} +-'''); +- } +- +- test_undefinedMethod_create_generic_OK_literal() async { +- await resolveTestUnit(''' +-class A { +- B b; +- List items; +- main() { +- b.process(items); +- } +-} +- +-class B {} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- B b; +- List items; +- main() { +- b.process(items); +- } +-} +- +-class B { +- void process(List items) {} +-} +-'''); +- } +- +- test_undefinedMethod_create_generic_OK_local() async { +- await resolveTestUnit(''' +-class A { +- List items; +- main() { +- process(items); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- List items; +- main() { +- process(items); +- } +- +- void process(List items) {} +-} +-'''); +- } +- +- test_undefinedMethod_createQualified_emptyClassBody() async { +- await resolveTestUnit(''' +-class A {} +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- static void myUndefinedMethod() {} +-} +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- } +- +- test_undefinedMethod_createQualified_fromClass() async { +- await resolveTestUnit(''' +-class A { +-} +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- static void myUndefinedMethod() {} +-} +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- } +- +- test_undefinedMethod_createQualified_fromClass_hasOtherMember() async { +- await resolveTestUnit(''' +-class A { +- foo() {} +-} +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- foo() {} +- +- static void myUndefinedMethod() {} +-} +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- } +- +- test_undefinedMethod_createQualified_fromInstance() async { +- await resolveTestUnit(''' +-class A { +-} +-main(A a) { +- a.myUndefinedMethod(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- void myUndefinedMethod() {} +-} +-main(A a) { +- a.myUndefinedMethod(); +-} +-'''); +- } +- +- test_undefinedMethod_createQualified_targetIsFunctionType() async { +- await resolveTestUnit(''' +-typedef A(); +-main() { +- A.myUndefinedMethod(); +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_METHOD); +- } +- +- test_undefinedMethod_createQualified_targetIsUnresolved() async { +- await resolveTestUnit(''' +-main() { +- NoSuchClass.myUndefinedMethod(); +-} +-'''); +- await assertNoFix(DartFixKind.CREATE_METHOD); +- } +- +- test_undefinedMethod_createUnqualified_duplicateArgumentNames() async { +- await resolveTestUnit(''' +-class C { +- int x; +-} +- +-class D { +- foo(C c1, C c2) { +- bar(c1.x, c2.x); +- } +-}'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class C { +- int x; +-} +- +-class D { +- foo(C c1, C c2) { +- bar(c1.x, c2.x); +- } +- +- void bar(int x, int x2) {} +-}'''); +- } +- +- test_undefinedMethod_createUnqualified_parameters() async { +- await resolveTestUnit(''' +-class A { +- main() { +- myUndefinedMethod(0, 1.0, '3'); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- main() { +- myUndefinedMethod(0, 1.0, '3'); +- } +- +- void myUndefinedMethod(int i, double d, String s) {} +-} +-'''); +- // linked positions +- int index = 0; +- _assertLinkedGroup( +- change.linkedEditGroups[index++], ['void myUndefinedMethod(']); +- _assertLinkedGroup(change.linkedEditGroups[index++], +- ['myUndefinedMethod(0', 'myUndefinedMethod(int']); +- _assertLinkedGroup( +- change.linkedEditGroups[index++], +- ['int i'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['int', 'num', 'Object', 'Comparable'])); +- _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']); +- _assertLinkedGroup( +- change.linkedEditGroups[index++], +- ['double d'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['double', 'num', 'Object', 'Comparable'])); +- _assertLinkedGroup(change.linkedEditGroups[index++], ['d,']); +- _assertLinkedGroup( +- change.linkedEditGroups[index++], +- ['String s'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['String', 'Object', 'Comparable'])); +- _assertLinkedGroup(change.linkedEditGroups[index++], ['s)']); +- } +- +- test_undefinedMethod_createUnqualified_parameters_named() async { +- await resolveTestUnit(''' +-class A { +- main() { +- myUndefinedMethod(0, bbb: 1.0, ccc: '2'); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- main() { +- myUndefinedMethod(0, bbb: 1.0, ccc: '2'); +- } +- +- void myUndefinedMethod(int i, {double bbb, String ccc}) {} +-} +-'''); +- // linked positions +- int index = 0; +- _assertLinkedGroup( +- change.linkedEditGroups[index++], ['void myUndefinedMethod(']); +- _assertLinkedGroup(change.linkedEditGroups[index++], +- ['myUndefinedMethod(0', 'myUndefinedMethod(int']); +- _assertLinkedGroup( +- change.linkedEditGroups[index++], +- ['int i'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['int', 'num', 'Object', 'Comparable'])); +- _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']); +- _assertLinkedGroup( +- change.linkedEditGroups[index++], +- ['double bbb'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['double', 'num', 'Object', 'Comparable'])); +- _assertLinkedGroup( +- change.linkedEditGroups[index++], +- ['String ccc'], +- expectedSuggestions(LinkedEditSuggestionKind.TYPE, +- ['String', 'Object', 'Comparable'])); +- } +- +- test_undefinedMethod_createUnqualified_returnType() async { +- await resolveTestUnit(''' +-class A { +- main() { +- int v = myUndefinedMethod(); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- main() { +- int v = myUndefinedMethod(); +- } +- +- int myUndefinedMethod() {} +-} +-'''); +- // linked positions +- _assertLinkedGroup(change.linkedEditGroups[0], ['int myUndefinedMethod(']); +- _assertLinkedGroup(change.linkedEditGroups[1], +- ['myUndefinedMethod();', 'myUndefinedMethod() {']); +- } +- +- test_undefinedMethod_createUnqualified_staticFromField() async { +- await resolveTestUnit(''' +-class A { +- static var f = myUndefinedMethod(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- static var f = myUndefinedMethod(); +- +- static myUndefinedMethod() {} +-} +-'''); +- } +- +- test_undefinedMethod_createUnqualified_staticFromMethod() async { +- await resolveTestUnit(''' +-class A { +- static main() { +- myUndefinedMethod(); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- static main() { +- myUndefinedMethod(); +- } +- +- static void myUndefinedMethod() {} +-} +-'''); +- } +- +- test_undefinedMethod_hint_createQualified_fromInstance() async { +- await resolveTestUnit(''' +-class A { +-} +-main() { +- var a = new A(); +- a.myUndefinedMethod(); +-} +-'''); +- await assertHasFix(DartFixKind.CREATE_METHOD, ''' +-class A { +- void myUndefinedMethod() {} +-} +-main() { +- var a = new A(); +- a.myUndefinedMethod(); +-} +-'''); +- } +- +- test_undefinedMethod_parameterType_differentPrefixInTargetUnit() async { +- String code2 = r''' +-library test2; +-import 'test3.dart' as bbb; +-export 'test3.dart'; +-class D { +-} +-'''; +- addSource('/test2.dart', code2); +- addSource('/test3.dart', r''' +-library test3; +-class E {} +-'''); +- await resolveTestUnit(''' +-library test; +-import 'test2.dart' as aaa; +-main(aaa.D d, aaa.E e) { +- d.foo(e); +-} +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error); +- change = fix.change; +- // apply to "test2.dart" +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/test2.dart'); +- expect(SourceEdit.applySequence(code2, fileEdit.edits), r''' +-library test2; +-import 'test3.dart' as bbb; +-export 'test3.dart'; +-class D { +- void foo(bbb.E e) {} +-} +-'''); +- } +- +- test_undefinedMethod_parameterType_inTargetUnit() async { +- String code2 = r''' +-library test2; +-class D { +-} +-class E {} +-'''; +- addSource('/test2.dart', code2); +- await resolveTestUnit(''' +-library test; +-import 'test2.dart' as test2; +-main(test2.D d, test2.E e) { +- d.foo(e); +-} +-'''); +- AnalysisError error = await _findErrorToFix(); +- fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error); +- change = fix.change; +- // apply to "test2.dart" +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- SourceFileEdit fileEdit = change.edits[0]; +- expect(fileEdit.file, '/test2.dart'); +- expect(SourceEdit.applySequence(code2, fileEdit.edits), r''' +-library test2; +-class D { +- void foo(E e) {} +-} +-class E {} +-'''); +- } +- +- test_undefinedMethod_useSimilar_ignoreOperators() async { +- await resolveTestUnit(''' +-main(Object object) { +- object.then(); +-} +-'''); +- await assertNoFix(DartFixKind.CHANGE_TO); +- } +- +- test_undefinedMethod_useSimilar_qualified() async { +- await resolveTestUnit(''' +-class A { +- myMethod() {} +-} +-main() { +- A a = new A(); +- a.myMehtod(); +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- myMethod() {} +-} +-main() { +- A a = new A(); +- a.myMethod(); +-} +-'''); +- } +- +- test_undefinedMethod_useSimilar_unqualified_superClass() async { +- await resolveTestUnit(''' +-class A { +- myMethod() {} +-} +-class B extends A { +- main() { +- myMehtod(); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- myMethod() {} +-} +-class B extends A { +- main() { +- myMethod(); +- } +-} +-'''); +- } +- +- test_undefinedMethod_useSimilar_unqualified_thisClass() async { +- await resolveTestUnit(''' +-class A { +- myMethod() {} +- main() { +- myMehtod(); +- } +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- myMethod() {} +- main() { +- myMethod(); +- } +-} +-'''); +- } +- +- test_undefinedParameter_convertFlutterChild_invalidList() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +- child: [ +- new Transform(), +- null, +- new AspectRatio(), +- ], +- ), +- ); +-} +-'''); +- await assertNoFix(DartFixKind.CONVERT_FLUTTER_CHILD); +- } +- +- test_undefinedParameter_convertFlutterChild_OK_hasList() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +- child: [ +- new Transform(), +- new ClipRect.rect(), +- new AspectRatio(), +- ], +- ), +- ); +-} +-'''); +- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +- children: [ +- new Transform(), +- new ClipRect.rect(), +- new AspectRatio(), +- ], +- ), +- ); +-} +-'''); +- } +- +- test_undefinedParameter_convertFlutterChild_OK_hasTypedList() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +- child: [ +- new Transform(), +- new ClipRect.rect(), +- new AspectRatio(), +- ], +- ), +- ); +-} +-'''); +- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Container( +- child: new Row( +- children: [ +- new Transform(), +- new ClipRect.rect(), +- new AspectRatio(), +- ], +- ), +- ); +-} +-'''); +- } +- +- test_undefinedParameter_convertFlutterChild_OK_multiLine() async { +- _configureFlutterPkg({ +- 'src/widgets/framework.dart': flutter_framework_code, +- }); +- await resolveTestUnit(''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +- body: new Row( +- child: new Container( +- width: 200.0, +- height: 300.0, +- ), +- ), +- ); +-} +-'''); +- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, ''' +-import 'package:flutter/src/widgets/framework.dart'; +-build() { +- return new Scaffold( +- body: new Row( +- children: [ +- new Container( +- width: 200.0, +- height: 300.0, +- ), +- ], +- ), +- ); +-} +-'''); +- } +- +- test_undefinedSetter_useSimilar_hint() async { +- await resolveTestUnit(''' +-class A { +- int myField; +-} +-main(A a) { +- var x = a; +- x.myFild = 42; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- int myField; +-} +-main(A a) { +- var x = a; +- x.myField = 42; +-} +-'''); +- } +- +- test_undefinedSetter_useSimilar_qualified() async { +- await resolveTestUnit(''' +-class A { +- int myField; +-} +-main(A a) { +- a.myFild = 42; +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- int myField; +-} +-main(A a) { +- a.myField = 42; +-} +-'''); +- } +- +- test_undefinedSetter_useSimilar_unqualified() async { +- await resolveTestUnit(''' +-class A { +- int myField; +- main() { +- myFild = 42; +- } +-} +-'''); +- await assertHasFix(DartFixKind.CHANGE_TO, ''' +-class A { +- int myField; +- main() { +- myField = 42; +- } +-} +-'''); +- } +- +- test_useEffectiveIntegerDivision() async { +- await resolveTestUnit(''' +-main() { +- var a = 5; +- var b = 2; +- print((a / b).toInt()); +-} +-'''); +- await assertHasFix(DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION, ''' +-main() { +- var a = 5; +- var b = 2; +- print(a ~/ b); +-} +-'''); +- } +- +- test_useImportPrefix_withClass() async { +- await resolveTestUnit(''' +-import 'dart:async' as pref; +-main() { +- pref.Stream s = null; +- Future f = null; +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PREFIX, ''' +-import 'dart:async' as pref; +-main() { +- pref.Stream s = null; +- pref.Future f = null; +-} +-'''); +- } +- +- test_useImportPrefix_withTopLevelVariable() async { +- await resolveTestUnit(''' +-import 'dart:math' as pref; +-main() { +- print(pref.E); +- print(PI); +-} +-'''); +- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PREFIX, ''' +-import 'dart:math' as pref; +-main() { +- print(pref.E); +- print(pref.PI); +-} +-'''); +- } +- +- void _addMetaPackageSource() { +- addPackageSource('meta', 'meta.dart', r''' +-library meta; +- +-const Required required = const Required(); +- +-class Required { +- final String reason; +- const Required([this.reason]); +-} +-'''); +- } +- +- /** +- * Configures the [SourceFactory] to have the `flutter` package in +- * `/packages/flutter/lib` folder. +- */ +- void _configureFlutterPkg(Map pathToCode) { +- pathToCode.forEach((path, code) { +- provider.newFile('$flutterPkgLibPath/$path', code); +- }); +- // configure SourceFactory +- Folder myPkgFolder = provider.getResource(flutterPkgLibPath); +- UriResolver pkgResolver = new PackageMapUriResolver(provider, { +- 'flutter': [myPkgFolder] +- }); +- SourceFactory sourceFactory = new SourceFactory( +- [new DartUriResolver(sdk), pkgResolver, resourceResolver]); +- driver.configure(sourceFactory: sourceFactory); +- // force 'flutter' resolution +- addSource( +- '/tmp/other.dart', +- pathToCode.keys +- .map((path) => "import 'package:flutter/$path';") +- .join('\n')); +- } +-} +- +-@reflectiveTest +-class LintFixTest extends BaseFixProcessorTest { +- AnalysisError error; +- +- Future applyFix(FixKind kind) async { +- fix = await _assertHasFix(kind, error); +- change = fix.change; +- // apply to "file" +- List fileEdits = change.edits; +- expect(fileEdits, hasLength(1)); +- resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits); +- } +- +- Future findLint(String src, String lintCode, {int length: 1}) async { +- int errorOffset = src.indexOf('/*LINT*/'); +- await resolveTestUnit(src.replaceAll('/*LINT*/', '')); +- error = new AnalysisError( +- resolutionMap.elementDeclaredByCompilationUnit(testUnit).source, +- errorOffset, +- length, +- new LintCode(lintCode, '')); +- } +- +- test_addRequiredAnnotation() async { +- String src = ''' +-void function({String /*LINT*/param}) { +- assert(param != null); +-} +-'''; +- await findLint(src, LintNames.always_require_non_null_named_parameters); +- await applyFix(DartFixKind.LINT_ADD_REQUIRED); +- verifyResult(''' +-void function({@required String param}) { +- assert(param != null); +-} +-'''); +- } +- +- test_isNotEmpty() async { +- String src = ''' +-f(c) { +- if (/*LINT*/!c.isEmpty) {} +-} +-'''; +- await findLint(src, LintNames.prefer_is_not_empty); +- +- await applyFix(DartFixKind.USE_IS_NOT_EMPTY); +- +- verifyResult(''' +-f(c) { +- if (c.isNotEmpty) {} +-} +-'''); +- } +- +- test_lint_addMissingOverride_field() async { +- String src = ''' +-class abstract Test { +- int get t; +-} +-class Sub extends Test { +- int /*LINT*/t = 42; +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class abstract Test { +- int get t; +-} +-class Sub extends Test { +- @override +- int t = 42; +-} +-'''); +- } +- +- test_lint_addMissingOverride_getter() async { +- String src = ''' +-class Test { +- int get t => null; +-} +-class Sub extends Test { +- int get /*LINT*/t => null; +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class Test { +- int get t => null; +-} +-class Sub extends Test { +- @override +- int get t => null; +-} +-'''); +- } +- +- test_lint_addMissingOverride_method() async { +- String src = ''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- void /*LINT*/t() { } +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- @override +- void t() { } +-} +-'''); +- } +- +- test_lint_addMissingOverride_method_with_doc_comment() async { +- String src = ''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- /// Doc comment. +- void /*LINT*/t() { } +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- /// Doc comment. +- @override +- void t() { } +-} +-'''); +- } +- +- test_lint_addMissingOverride_method_with_doc_comment_2() async { +- String src = ''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- /** +- * Doc comment. +- */ +- void /*LINT*/t() { } +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- /** +- * Doc comment. +- */ +- @override +- void t() { } +-} +-'''); +- } +- +- test_lint_addMissingOverride_method_with_doc_comment_and_metadata() async { +- String src = ''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- /// Doc comment. +- @foo +- void /*LINT*/t() { } +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- /// Doc comment. +- @override +- @foo +- void t() { } +-} +-'''); +- } +- +- test_lint_addMissingOverride_method_with_non_doc_comment() async { +- String src = ''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- // Non-doc comment. +- void /*LINT*/t() { } +-} +-'''; +- await findLint(src, LintNames.annotate_overrides); +- +- await applyFix(DartFixKind.LINT_ADD_OVERRIDE); +- +- verifyResult(''' +-class Test { +- void t() { } +-} +-class Sub extends Test { +- // Non-doc comment. +- @override +- void t() { } +-} +-'''); +- } +- +- test_lint_removeInterpolationBraces() async { +- String src = r''' +-main() { +- var v = 42; +- print('v: /*LINT*/${ v}'); +-} +-'''; +- await findLint(src, LintNames.unnecessary_brace_in_string_interp, +- length: 4); +- await applyFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES); +- verifyResult(r''' +-main() { +- var v = 42; +- print('v: $v'); +-} +-'''); +- } +- +- test_removeAwait_intLiteral() async { +- String src = ''' +-bad() async { +- print(/*LINT*/await 23); +-} +-'''; +- await findLint(src, LintNames.await_only_futures); +- +- await applyFix(DartFixKind.REMOVE_AWAIT); +- +- verifyResult(''' +-bad() async { +- print(23); +-} +-'''); +- } +- +- test_removeAwait_StringLiteral() async { +- String src = ''' +-bad() async { +- print(/*LINT*/await 'hola'); +-} +-'''; +- await findLint(src, LintNames.await_only_futures); +- +- await applyFix(DartFixKind.REMOVE_AWAIT); +- +- verifyResult(''' +-bad() async { +- print('hola'); +-} +-'''); +- } +- +- test_removeEmptyCatch_newLine() async { +- String src = ''' +-void foo() { +- try {} +- catch (e) {/*LINT*/} +- finally {} +-} +-'''; +- await findLint(src, LintNames.empty_catches); +- +- await applyFix(DartFixKind.REMOVE_EMPTY_CATCH); +- +- verifyResult(''' +-void foo() { +- try {} +- finally {} +-} +-'''); +- } +- +- test_removeEmptyCatch_sameLine() async { +- String src = ''' +-void foo() { +- try {} catch (e) {/*LINT*/} finally {} +-} +-'''; +- await findLint(src, LintNames.empty_catches); +- +- await applyFix(DartFixKind.REMOVE_EMPTY_CATCH); +- +- verifyResult(''' +-void foo() { +- try {} finally {} +-} +-'''); +- } +- +- test_removeEmptyConstructorBody() async { +- String src = ''' +-class C { +- C() {/*LINT*/} +-} +-'''; +- await findLint(src, LintNames.empty_constructor_bodies); +- +- await applyFix(DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY); +- +- verifyResult(''' +-class C { +- C(); +-} +-'''); +- } +- +- test_removeEmptyElse_newLine() async { +- String src = ''' +-void foo(bool cond) { +- if (cond) { +- // +- } +- else /*LINT*/; +-} +-'''; +- await findLint(src, LintNames.avoid_empty_else); +- +- await applyFix(DartFixKind.REMOVE_EMPTY_ELSE); +- +- verifyResult(''' +-void foo(bool cond) { +- if (cond) { +- // +- } +-} +-'''); +- } +- +- test_removeEmptyElse_sameLine() async { +- String src = ''' +-void foo(bool cond) { +- if (cond) { +- // +- } else /*LINT*/; +-} +-'''; +- await findLint(src, LintNames.avoid_empty_else); +- +- await applyFix(DartFixKind.REMOVE_EMPTY_ELSE); +- +- verifyResult(''' +-void foo(bool cond) { +- if (cond) { +- // +- } +-} +-'''); +- } +- +- test_removeEmptyStatement_insideBlock() async { +- String src = ''' +-void foo() { +- while(true) { +- /*LINT*/; +- } +-} +-'''; +- await findLint(src, LintNames.empty_statements); +- +- await applyFix(DartFixKind.REMOVE_EMPTY_STATEMENT); +- +- verifyResult(''' +-void foo() { +- while(true) { +- } +-} +-'''); +- } +- +- test_removeEmptyStatement_outOfBlock_otherLine() async { +- String src = ''' +-void foo() { +- while(true) +- /*LINT*/; +- print('hi'); +-} +-'''; +- await findLint(src, LintNames.empty_statements); +- +- await applyFix(DartFixKind.REPLACE_WITH_BRACKETS); +- +- verifyResult(''' +-void foo() { +- while(true) {} +- print('hi'); +-} +-'''); +- } +- +- test_removeEmptyStatement_outOfBlock_sameLine() async { +- String src = ''' +-void foo() { +- while(true)/*LINT*/; +- print('hi'); +-} +-'''; +- await findLint(src, LintNames.empty_statements); +- +- await applyFix(DartFixKind.REPLACE_WITH_BRACKETS); +- +- verifyResult(''' +-void foo() { +- while(true) {} +- print('hi'); +-} +-'''); +- } +- +- test_removeInitializer_field() async { +- String src = ''' +-class Test { +- int /*LINT*/x = null; +-} +-'''; +- await findLint(src, LintNames.avoid_init_to_null); +- +- await applyFix(DartFixKind.REMOVE_INITIALIZER); +- +- verifyResult(''' +-class Test { +- int x; +-} +-'''); +- } +- +- test_removeInitializer_listOfVariableDeclarations() async { +- String src = ''' +-String a = 'a', /*LINT*/b = null, c = 'c'; +-'''; +- await findLint(src, LintNames.avoid_init_to_null); +- +- await applyFix(DartFixKind.REMOVE_INITIALIZER); +- +- verifyResult(''' +-String a = 'a', b, c = 'c'; +-'''); +- } +- +- test_removeInitializer_topLevel() async { +- String src = ''' +-var /*LINT*/x = null; +-'''; +- await findLint(src, LintNames.avoid_init_to_null); +- +- await applyFix(DartFixKind.REMOVE_INITIALIZER); +- +- verifyResult(''' +-var x; +-'''); +- } +- +- test_removeMethodDeclaration_getter() async { +- String src = ''' +-class A { +- int x; +-} +-class B extends A { +- @override +- int get /*LINT*/x => super.x; +-} +-'''; +- await findLint(src, LintNames.unnecessary_override); +- +- await applyFix(DartFixKind.REMOVE_METHOD_DECLARATION); +- +- verifyResult(''' +-class A { +- int x; +-} +-class B extends A { +-} +-'''); +- } +- +- test_removeMethodDeclaration_method() async { +- String src = ''' +-class A { +- @override +- String /*LINT*/toString() => super.toString(); +-} +-'''; +- await findLint(src, LintNames.unnecessary_override); +- +- await applyFix(DartFixKind.REMOVE_METHOD_DECLARATION); +- +- verifyResult(''' +-class A { +-} +-'''); +- } +- +- test_removeMethodDeclaration_setter() async { +- String src = ''' +-class A { +- int x; +-} +-class B extends A { +- @override +- set /*LINT*/x(int other) { +- this.x = other; +- } +-} +-'''; +- await findLint(src, LintNames.unnecessary_override); +- +- await applyFix(DartFixKind.REMOVE_METHOD_DECLARATION); +- +- verifyResult(''' +-class A { +- int x; +-} +-class B extends A { +-} +-'''); +- } +- +- test_removeThisExpression_methodInvocation_oneCharacterOperator() async { +- String src = ''' +-class A { +- void foo() { +- /*LINT*/this.foo(); +- } +-} +-'''; +- await findLint(src, LintNames.unnecessary_this); +- +- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION); +- +- verifyResult(''' +-class A { +- void foo() { +- foo(); +- } +-} +-'''); +- } +- +- test_removeThisExpression_methodInvocation_twoCharactersOperator() async { +- String src = ''' +-class A { +- void foo() { +- /*LINT*/this?.foo(); +- } +-} +-'''; +- await findLint(src, LintNames.unnecessary_this); +- +- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION); +- +- verifyResult(''' +-class A { +- void foo() { +- foo(); +- } +-} +-'''); +- } +- +- test_removeThisExpression_propertyAccess_oneCharacterOperator() async { +- String src = ''' +-class A { +- int x; +- void foo() { +- /*LINT*/this.x = 2; +- } +-} +-'''; +- await findLint(src, LintNames.unnecessary_this); +- +- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION); +- +- verifyResult(''' +-class A { +- int x; +- void foo() { +- x = 2; +- } +-} +-'''); +- } +- +- test_removeThisExpression_propertyAccess_twoCharactersOperator() async { +- String src = ''' +-class A { +- int x; +- void foo() { +- /*LINT*/this?.x = 2; +- } +-} +-'''; +- await findLint(src, LintNames.unnecessary_this); +- +- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION); +- +- verifyResult(''' +-class A { +- int x; +- void foo() { +- x = 2; +- } +-} +-'''); +- } +- +- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_InsideFunctionTypedFormalParameter() async { +- String src = ''' +-bad(void foo(/*LINT*/dynamic x)) { +- return null; +-} +-'''; +- await findLint(src, LintNames.avoid_annotating_with_dynamic); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-bad(void foo(x)) { +- return null; +-} +-'''); +- } +- +- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_NamedParameter() async { +- String src = ''' +-bad({/*LINT*/dynamic defaultValue}) { +- return null; +-} +-'''; +- await findLint(src, LintNames.avoid_annotating_with_dynamic); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-bad({defaultValue}) { +- return null; +-} +-'''); +- } +- +- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_NormalParameter() async { +- String src = ''' +-bad(/*LINT*/dynamic defaultValue) { +- return null; +-} +-'''; +- await findLint(src, LintNames.avoid_annotating_with_dynamic); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-bad(defaultValue) { +- return null; +-} +-'''); +- } +- +- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_OptionalParameter() async { +- String src = ''' +-bad([/*LINT*/dynamic defaultValue]) { +- return null; +-} +-'''; +- await findLint(src, LintNames.avoid_annotating_with_dynamic); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-bad([defaultValue]) { +- return null; +-} +-'''); +- } +- +- test_removeTypeAnnotation_avoidReturnTypesOnSetters_void() async { +- String src = ''' +-/*LINT*/void set speed2(int ms) {} +-'''; +- await findLint(src, LintNames.avoid_return_types_on_setters); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-set speed2(int ms) {} +-'''); +- } +- +- test_removeTypeAnnotation_avoidTypesOnClosureParameters_FunctionTypedFormalParameter() async { +- String src = ''' +-var functionWithFunction = (/*LINT*/int f(int x)) => f(0); +-'''; +- await findLint(src, LintNames.avoid_types_on_closure_parameters); +- +- await applyFix(DartFixKind.REPLACE_WITH_IDENTIFIER); +- +- verifyResult(''' +-var functionWithFunction = (f) => f(0); +-'''); +- } +- +- test_removeTypeAnnotation_avoidTypesOnClosureParameters_NamedParameter() async { +- String src = ''' +-var x = ({/*LINT*/Future defaultValue}) { +- return null; +-}; +-'''; +- await findLint(src, LintNames.avoid_types_on_closure_parameters); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-var x = ({defaultValue}) { +- return null; +-}; +-'''); +- } +- +- test_removeTypeAnnotation_avoidTypesOnClosureParameters_NormalParameter() async { +- String src = ''' +-var x = (/*LINT*/Future defaultValue) { +- return null; +-}; +-'''; +- await findLint(src, LintNames.avoid_types_on_closure_parameters); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-var x = (defaultValue) { +- return null; +-}; +-'''); +- } +- +- test_removeTypeAnnotation_avoidTypesOnClosureParameters_OptionalParameter() async { +- String src = ''' +-var x = ([/*LINT*/Future defaultValue]) { +- return null; +-}; +-'''; +- await findLint(src, LintNames.avoid_types_on_closure_parameters); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-var x = ([defaultValue]) { +- return null; +-}; +-'''); +- } +- +- test_removeTypeAnnotation_typeInitFormals_void() async { +- String src = ''' +-class C { +- int f; +- C(/*LINT*/int this.f); +-} +-'''; +- await findLint(src, LintNames.type_init_formals); +- +- await applyFix(DartFixKind.REMOVE_TYPE_NAME); +- +- verifyResult(''' +-class C { +- int f; +- C(this.f); +-} +-'''); +- } +- +- test_replaceWithConditionalAssignment_withCodeBeforeAndAfter() async { +- String src = ''' +-class Person { +- String _fullName; +- void foo() { +- print('hi'); +- /*LINT*/if (_fullName == null) { +- _fullName = getFullUserName(this); +- } +- print('hi'); +- } +-} +-'''; +- await findLint(src, LintNames.prefer_conditional_assignment); +- +- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT); +- +- verifyResult(''' +-class Person { +- String _fullName; +- void foo() { +- print('hi'); +- _fullName ??= getFullUserName(this); +- print('hi'); +- } +-} +-'''); +- } +- +- test_replaceWithConditionalAssignment_withOneBlock() async { +- String src = ''' +-class Person { +- String _fullName; +- void foo() { +- /*LINT*/if (_fullName == null) { +- _fullName = getFullUserName(this); +- } +- } +-} +-'''; +- await findLint(src, LintNames.prefer_conditional_assignment); +- +- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT); +- +- verifyResult(''' +-class Person { +- String _fullName; +- void foo() { +- _fullName ??= getFullUserName(this); +- } +-} +-'''); +- } +- +- test_replaceWithConditionalAssignment_withoutBlock() async { +- String src = ''' +-class Person { +- String _fullName; +- void foo() { +- /*LINT*/if (_fullName == null) +- _fullName = getFullUserName(this); +- } +-} +-'''; +- await findLint(src, LintNames.prefer_conditional_assignment); +- +- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT); +- +- verifyResult(''' +-class Person { +- String _fullName; +- void foo() { +- _fullName ??= getFullUserName(this); +- } +-} +-'''); +- } +- +- test_replaceWithConditionalAssignment_withTwoBlock() async { +- String src = ''' +-class Person { +- String _fullName; +- void foo() { +- /*LINT*/if (_fullName == null) {{ +- _fullName = getFullUserName(this); +- }} +- } +-} +-'''; +- await findLint(src, LintNames.prefer_conditional_assignment); +- +- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT); +- +- verifyResult(''' +-class Person { +- String _fullName; +- void foo() { +- _fullName ??= getFullUserName(this); +- } +-} +-'''); +- } +- +- test_replaceWithLiteral_linkedHashMap_withCommentsInGeneric() async { +- String src = ''' +-import 'dart:collection'; +- +-final a = /*LINT*/new LinkedHashMap(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-import 'dart:collection'; +- +-final a = {}; +-'''); +- } +- +- test_replaceWithLiteral_linkedHashMap_withDynamicGenerics() async { +- String src = ''' +-import 'dart:collection'; +- +-final a = /*LINT*/new LinkedHashMap(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-import 'dart:collection'; +- +-final a = {}; +-'''); +- } +- +- test_replaceWithLiteral_linkedHashMap_withGeneric() async { +- String src = ''' +-import 'dart:collection'; +- +-final a = /*LINT*/new LinkedHashMap(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-import 'dart:collection'; +- +-final a = {}; +-'''); +- } +- +- test_replaceWithLiteral_linkedHashMap_withoutGeneric() async { +- String src = ''' +-import 'dart:collection'; +- +-final a = /*LINT*/new LinkedHashMap(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-import 'dart:collection'; +- +-final a = {}; +-'''); +- } +- +- test_replaceWithLiteral_list_withGeneric() async { +- String src = ''' +-final a = /*LINT*/new List(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-final a = []; +-'''); +- } +- +- test_replaceWithLiteral_list_withoutGeneric() async { +- String src = ''' +-final a = /*LINT*/new List(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-final a = []; +-'''); +- } +- +- test_replaceWithLiteral_map_withGeneric() async { +- String src = ''' +-final a = /*LINT*/new Map(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-final a = {}; +-'''); +- } +- +- test_replaceWithLiteral_map_withoutGeneric() async { +- String src = ''' +-final a = /*LINT*/new Map(); +-'''; +- await findLint(src, LintNames.prefer_collection_literals); +- +- await applyFix(DartFixKind.REPLACE_WITH_LITERAL); +- +- verifyResult(''' +-final a = {}; +-'''); +- } +- +- test_replaceWithTearOff_function_oneParameter() async { +- String src = ''' +-final x = /*LINT*/(name) { +- print(name); +-}; +-'''; +- await findLint(src, LintNames.unnecessary_lambdas); +- +- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF); +- +- verifyResult(''' +-final x = print; +-'''); +- } +- +- test_replaceWithTearOff_function_zeroParameters() async { +- String src = ''' +-void foo(){} +-Function finalVar() { +- return /*LINT*/() { +- foo(); +- }; +-} +-'''; +- await findLint(src, LintNames.unnecessary_lambdas); +- +- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF); +- +- verifyResult(''' +-void foo(){} +-Function finalVar() { +- return foo; +-} +-'''); +- } +- +- test_replaceWithTearOff_lambda_asArgument() async { +- String src = ''' +-void foo() { +- bool isPair(int a) => a % 2 == 0; +- final finalList = []; +- finalList.where(/*LINT*/(number) => +- isPair(number)); +-} +-'''; +- await findLint(src, LintNames.unnecessary_lambdas); +- +- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF); +- +- verifyResult(''' +-void foo() { +- bool isPair(int a) => a % 2 == 0; +- final finalList = []; +- finalList.where(isPair); +-} +-'''); +- } +- +- test_replaceWithTearOff_method_oneParameter() async { +- String src = ''' +-var a = /*LINT*/(x) => finalList.remove(x); +-'''; +- await findLint(src, LintNames.unnecessary_lambdas); +- +- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF); +- +- verifyResult(''' +-var a = finalList.remove; +-'''); +- } +- +- test_replaceWithTearOff_method_zeroParameter() async { +- String src = ''' +-final Object a; +-Function finalVar() { +- return /*LINT*/() { +- return a.toString(); +- }; +-} +-'''; +- await findLint(src, LintNames.unnecessary_lambdas); +- +- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF); +- +- verifyResult(''' +-final Object a; +-Function finalVar() { +- return a.toString; +-} +-'''); +- } +- +- void verifyResult(String expectedResult) { +- expect(resultCode, expectedResult); +- } +-} +- +-class _DartFixContextImpl implements DartFixContext { +- @override +- final ResourceProvider resourceProvider; +- +- @override +- final AnalysisDriver analysisDriver; +- +- @override +- final AstProvider astProvider; +- +- @override +- final CompilationUnit unit; +- +- @override +- final AnalysisError error; +- +- _DartFixContextImpl(this.resourceProvider, this.analysisDriver, +- this.astProvider, this.unit, this.error); +- +- @override +- GetTopLevelDeclarations get getTopLevelDeclarations => +- analysisDriver.getTopLevelNameDeclarations; +-} +diff --git a/pkg/analysis_server/test/services/correction/levenshtein_test.dart b/pkg/analysis_server/test/services/correction/levenshtein_test.dart +deleted file mode 100644 +index c344a4c06f8..00000000000 +--- a/pkg/analysis_server/test/services/correction/levenshtein_test.dart ++++ /dev/null +@@ -1,66 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/levenshtein.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LevenshteinTest); +- }); +-} +- +-@reflectiveTest +-class LevenshteinTest { +- void test_different_caseInsensitive() { +- expect(levenshtein('Saturday', 'sunday', 5, caseSensitive: false), 3); +- expect(levenshtein('SaturDay', 'sunday', 5, caseSensitive: false), 3); +- } +- +- void test_different_onThreshold() { +- expect(levenshtein('', 'abcde', 5), 5); +- expect(levenshtein('abcde', '', 5), 5); +- } +- +- void test_different_overThreshold() { +- expect(levenshtein('', 'abcde', 2), LEVENSHTEIN_MAX); +- expect(levenshtein('abcde', '', 2), LEVENSHTEIN_MAX); +- } +- +- void test_different_overThreshold_length() { +- expect(levenshtein('a', 'abcdefgh', 5), LEVENSHTEIN_MAX); +- expect(levenshtein('abcdefgh', 'a', 5), LEVENSHTEIN_MAX); +- } +- +- void test_different_underThreshold() { +- expect(levenshtein('String', 'Stirng', 5), 2); +- expect(levenshtein('kitten', 'sitting', 5), 3); +- expect(levenshtein('Saturday', 'Sunday', 5), 3); +- } +- +- void test_negativeThreshold() { +- expect(() { +- levenshtein('', '', -5); +- }, throwsArgumentError); +- } +- +- void test_null() { +- expect(() { +- levenshtein('', null, 5); +- }, throwsArgumentError); +- expect(() { +- levenshtein(null, '', 5); +- }, throwsArgumentError); +- } +- +- void test_same() { +- expect(levenshtein('', '', 5), 0); +- expect(levenshtein('test', 'test', 5), 0); +- } +- +- void test_same_caseInsensitive() { +- expect(levenshtein('test', 'Test', 5, caseSensitive: false), 0); +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart +deleted file mode 100644 +index 24f5ed80ebd..00000000000 +--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart ++++ /dev/null +@@ -1,369 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/name_suggestion.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/type.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(VariableNameSuggestionTest); +- }); +-} +- +-@reflectiveTest +-class VariableNameSuggestionTest extends AbstractSingleUnitTest { +- test_forExpression_cast() async { +- await resolveTestUnit(''' +-main() { +- var sortedNodes; +- var res = sortedNodes as String; +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('as String', (node) => node is AsExpression); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- test_forExpression_expectedType() async { +- await resolveTestUnit(''' +-class TreeNode {} +-main() { +- TreeNode node = null; +-} +-'''); +- Set excluded = new Set.from([]); +- DartType expectedType = findLocalVariable('node').type; +- Expression assignedExpression = +- findNodeAtString('null;', (node) => node is NullLiteral); +- List suggestions = getVariableNameSuggestionsForExpression( +- expectedType, assignedExpression, excluded); +- expect(suggestions, unorderedEquals(['treeNode', 'node'])); +- } +- +- test_forExpression_expectedType_double() async { +- await resolveTestUnit(''' +-main() { +- double res = 0.0; +-} +-'''); +- DartType expectedType = findLocalVariable('res').type; +- Expression assignedExpression = findNodeAtString('0.0;'); +- // first choice for "double" is "d" +- expect( +- getVariableNameSuggestionsForExpression( +- expectedType, assignedExpression, new Set.from([])), +- unorderedEquals(['d'])); +- // if "d" is used, try "e", "f", etc +- expect( +- getVariableNameSuggestionsForExpression( +- expectedType, assignedExpression, new Set.from(['d', 'e'])), +- unorderedEquals(['f'])); +- } +- +- test_forExpression_expectedType_int() async { +- await resolveTestUnit(''' +-main() { +- int res = 0; +-} +-'''); +- DartType expectedType = findLocalVariable('res').type; +- Expression assignedExpression = findNodeAtString('0;'); +- // first choice for "int" is "i" +- expect( +- getVariableNameSuggestionsForExpression( +- expectedType, assignedExpression, new Set.from([])), +- unorderedEquals(['i'])); +- // if "i" is used, try "j", "k", etc +- expect( +- getVariableNameSuggestionsForExpression( +- expectedType, assignedExpression, new Set.from(['i', 'j'])), +- unorderedEquals(['k'])); +- } +- +- test_forExpression_expectedType_String() async { +- await resolveTestUnit(''' +-main() { +- String res = 'abc'; +-} +-'''); +- DartType expectedType = findLocalVariable('res').type; +- Expression assignedExpression = findNodeAtString("'abc';"); +- // first choice for "String" is "s" +- expect( +- getVariableNameSuggestionsForExpression( +- expectedType, assignedExpression, new Set.from([])), +- unorderedEquals(['s'])); +- } +- +- test_forExpression_indexExpression_endsWithE() async { +- await resolveTestUnit(''' +-main() { +- var topNodes = [0, 1, 2]; +- print(topNodes[0]); +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('topNodes[0]').parent; +- var names = getVariableNameSuggestionsForExpression(null, expr, excluded); +- expect(names, unorderedEquals(['topNode', 'node', 'object'])); +- } +- +- test_forExpression_instanceCreation() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-import 'dart:math' as p; +-main(p) { +- new NoSuchClass(); +- new p.NoSuchClass(); +- new NoSuchClass.named(); +-} +-'''); +- var excluded = new Set.from([]); +- expect( +- getVariableNameSuggestionsForExpression( +- null, findNodeAtString('new NoSuchClass()'), excluded), +- unorderedEquals(['noSuchClass', 'suchClass', 'class'])); +- expect( +- getVariableNameSuggestionsForExpression( +- null, findNodeAtString('new NoSuchClass.named()'), excluded), +- unorderedEquals(['noSuchClass', 'suchClass', 'class'])); +- // TODO(scheglov) This test does not work. +- // In "p.NoSuchClass" the identifier "p" is not resolved to a PrefixElement. +-// expect( +-// getVariableNameSuggestionsForExpression( +-// null, +-// findNodeAtString('new p.NoSuchClass()'), +-// excluded), +-// unorderedEquals(['noSuchClass', 'suchClass', 'class'])); +- } +- +- test_forExpression_invocationArgument_named() async { +- await resolveTestUnit(''' +-foo({a, b, c}) {} +-main() { +- foo(a: 111, c: 333, b: 222); +-} +-'''); +- var excluded = new Set.from([]); +- { +- var expr = findNodeAtString('111'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['a'])); +- } +- { +- var expr = findNodeAtString('222'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['b'])); +- } +- { +- var expr = findNodeAtString('333'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['c'])); +- } +- } +- +- test_forExpression_invocationArgument_optional() async { +- await resolveTestUnit(''' +-foo(a, [b = 2, c = 3]) {} +-main() { +- foo(111, 222, 333); +-} +-'''); +- var excluded = new Set.from([]); +- { +- var expr = findNodeAtString('111'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['a'])); +- } +- { +- var expr = findNodeAtString('222'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['b'])); +- } +- { +- var expr = findNodeAtString('333'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['c'])); +- } +- } +- +- test_forExpression_invocationArgument_positional() async { +- await resolveTestUnit(''' +-foo(a, b) {} +-main() { +- foo(111, 222); +-} +-'''); +- var excluded = new Set.from([]); +- { +- var expr = findNodeAtString('111'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['a'])); +- } +- { +- var expr = findNodeAtString('222'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['b'])); +- } +- } +- +- test_forExpression_methodInvocation() async { +- await resolveTestUnit(''' +-main(p) { +- var res = p.getSortedNodes(); +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('p.get', (node) => node is MethodInvocation); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- test_forExpression_inBuildMethod() async { +- await resolveTestUnit(''' +-class A { +- void build() { +- List l = new List(); +- } +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('new List'); +- expect( +- getVariableNameSuggestionsForExpression(null, expr, excluded, +- isMethod: false), +- unorderedEquals(['list'])); +- expect( +- getVariableNameSuggestionsForExpression(null, expr, excluded, +- isMethod: true), +- unorderedEquals(['buildList'])); +- } +- +- test_forExpression_methodInvocation_noPrefix() async { +- await resolveTestUnit(''' +-main(p) { +- var res = p.sortedNodes(); +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('p.sorted', (node) => node is MethodInvocation); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- test_forExpression_name_get() async { +- await resolveTestUnit(''' +-main(p) { +- var res = p.get(); +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('p.get', (node) => node is MethodInvocation); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals([])); +- } +- +- test_forExpression_prefixedIdentifier() async { +- await resolveTestUnit(''' +-main(p) { +- var res = p.sortedNodes; +-} +-'''); +- var excluded = new Set.from([]); +- expect( +- getVariableNameSuggestionsForExpression( +- null, +- findNodeAtString('p.sorted', (node) => node is PrefixedIdentifier), +- excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- test_forExpression_privateName() async { +- await resolveTestUnit(''' +-main(p) { +- p._name; +- p._computeSuffix(); +-} +-'''); +- var excluded = new Set.from([]); +- expect( +- getVariableNameSuggestionsForExpression( +- null, +- findNodeAtString('p._name', (node) => node is PrefixedIdentifier), +- excluded), +- unorderedEquals(['name'])); +- expect( +- getVariableNameSuggestionsForExpression( +- null, +- findNodeAtString('p._compute', (node) => node is MethodInvocation), +- excluded), +- unorderedEquals(['computeSuffix', 'suffix'])); +- } +- +- test_forExpression_propertyAccess() async { +- await resolveTestUnit(''' +-main(p) { +- var res = p.q.sortedNodes; +-} +-'''); +- var excluded = new Set.from([]); +- PropertyAccess expression = +- findNodeAtString('p.q.sorted', (node) => node is PropertyAccess); +- expect(getVariableNameSuggestionsForExpression(null, expression, excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- test_forExpression_simpleName() async { +- await resolveTestUnit(''' +-main(p) { +- var sortedNodes = null; +- var res = sortedNodes; +-} +-'''); +- var excluded = new Set.from([]); +- var expr = findNodeAtString('sortedNodes;'); +- expect(getVariableNameSuggestionsForExpression(null, expr, excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- test_forExpression_unqualifiedInvocation() async { +- await resolveTestUnit(''' +-getSortedNodes() => []; +-main(p) { +- var res = getSortedNodes(); +-} +-'''); +- var excluded = new Set.from([]); +- expect( +- getVariableNameSuggestionsForExpression( +- null, +- findNodeAtString( +- 'getSortedNodes();', (node) => node is MethodInvocation), +- excluded), +- unorderedEquals(['sortedNodes', 'nodes'])); +- } +- +- void test_forText() { +- { +- Set excluded = new Set.from([]); +- List suggestions = +- getVariableNameSuggestionsForText('Goodbye, cruel world!', excluded); +- expect(suggestions, +- unorderedEquals(['goodbyeCruelWorld', 'cruelWorld', 'world'])); +- } +- { +- Set excluded = new Set.from(['world']); +- List suggestions = +- getVariableNameSuggestionsForText('Goodbye, cruel world!', excluded); +- expect(suggestions, +- unorderedEquals(['goodbyeCruelWorld', 'cruelWorld', 'world2'])); +- } +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart +deleted file mode 100644 +index 665cad67c04..00000000000 +--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart ++++ /dev/null +@@ -1,321 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/organize_directives.dart'; +-import 'package:analyzer/error/error.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- hide AnalysisError; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(OrganizeDirectivesTest); +- }); +-} +- +-@reflectiveTest +-class OrganizeDirectivesTest extends AbstractSingleUnitTest { +- List testErrors; +- +- test_keep_duplicateImports_withDifferentPrefix() async { +- await _computeUnitAndErrors(r''' +-import 'dart:async' as async1; +-import 'dart:async' as async2; +- +-main() { +- async1.Future f; +- async2.Stream s; +-}'''); +- // validate change +- _assertOrganize(r''' +-import 'dart:async' as async1; +-import 'dart:async' as async2; +- +-main() { +- async1.Future f; +- async2.Stream s; +-}''', removeUnresolved: true, removeUnused: true); +- } +- +- test_remove_duplicateImports() async { +- await _computeUnitAndErrors(r''' +-import 'dart:async'; +-import 'dart:async'; +- +-main() { +- Future f; +-}'''); +- // validate change +- _assertOrganize(r''' +-import 'dart:async'; +- +-main() { +- Future f; +-}''', removeUnresolved: true, removeUnused: true); +- } +- +- test_remove_duplicateImports_differentText_uri() async { +- await _computeUnitAndErrors(r''' +-import 'dart:async' as async; +-import "dart:async" as async; +- +-main() { +- async.Future f; +-}'''); +- // validate change +- _assertOrganize(r''' +-import 'dart:async' as async; +- +-main() { +- async.Future f; +-}''', removeUnresolved: true, removeUnused: true); +- } +- +- test_remove_duplicateImports_withSamePrefix() async { +- await _computeUnitAndErrors(r''' +-import 'dart:async' as async; +-import 'dart:async' as async; +- +-main() { +- async.Future f; +-}'''); +- // validate change +- _assertOrganize(r''' +-import 'dart:async' as async; +- +-main() { +- async.Future f; +-}''', removeUnresolved: true, removeUnused: true); +- } +- +- test_remove_unresolvedDirectives() async { +- addSource('/existing_part1.dart', 'part of lib;'); +- addSource('/existing_part2.dart', 'part of lib;'); +- await _computeUnitAndErrors(r''' +-library lib; +- +-import 'dart:async'; +-import 'dart:noSuchImportSdkLibrary'; +-import 'dart:math'; +-import 'package:noSuchImportPackage/andLib.dart'; +- +-export 'dart:noSuchExportSdkLibrary'; +-export 'dart:async'; +-export 'package:noSuchExportPackage/andLib.dart'; +-export 'dart:math'; +- +-part 'existing_part1.dart'; +-part 'no_such_part.dart'; +-part 'existing_part2.dart'; +- +-main() { +-} +-'''); +- // validate change +- _assertOrganize(r''' +-library lib; +- +-import 'dart:async'; +-import 'dart:math'; +- +-export 'dart:async'; +-export 'dart:math'; +- +-part 'existing_part1.dart'; +-part 'existing_part2.dart'; +- +-main() { +-} +-''', removeUnresolved: true); +- } +- +- test_remove_unusedImports() async { +- await _computeUnitAndErrors(r''' +-library lib; +- +-import 'dart:async'; +-import 'dart:math'; +-import 'dart:convert'; +-import 'dart:collection'; +- +-main() { +- print(PI); +- new HashMap(); +-} +-'''); +- // validate change +- _assertOrganize(r''' +-library lib; +- +-import 'dart:collection'; +-import 'dart:math'; +- +-main() { +- print(PI); +- new HashMap(); +-} +-''', removeUnused: true); +- } +- +- test_remove_unusedImports2() async { +- await _computeUnitAndErrors(r''' +-import 'dart:async'; +-import 'dart:math'; +- +-class A {} +- +-main() { +- Future f; +-}'''); +- // validate change +- _assertOrganize(r''' +-import 'dart:async'; +- +-class A {} +- +-main() { +- Future f; +-}''', removeUnresolved: true, removeUnused: true); +- } +- +- test_sort() async { +- await _computeUnitAndErrors(r''' +-library lib; +- +-export 'dart:bbb'; +-import 'dart:bbb'; +-export 'package:bbb/bbb.dart'; +-export 'http://bbb.com'; +-import 'bbb/bbb.dart'; +-export 'http://aaa.com'; +-import 'http://bbb.com'; +-export 'dart:aaa'; +-export 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +-export 'aaa/aaa.dart'; +-export 'bbb/bbb.dart'; +-import 'dart:aaa'; +-import 'package:aaa/aaa.dart'; +-import 'aaa/aaa.dart'; +-import 'http://aaa.com'; +-part 'bbb/bbb.dart'; +-part 'aaa/aaa.dart'; +- +-main() { +-} +-'''); +- // validate change +- _assertOrganize(r''' +-library lib; +- +-import 'dart:aaa'; +-import 'dart:bbb'; +- +-import 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +- +-import 'http://aaa.com'; +-import 'http://bbb.com'; +- +-import 'aaa/aaa.dart'; +-import 'bbb/bbb.dart'; +- +-export 'dart:aaa'; +-export 'dart:bbb'; +- +-export 'package:aaa/aaa.dart'; +-export 'package:bbb/bbb.dart'; +- +-export 'http://aaa.com'; +-export 'http://bbb.com'; +- +-export 'aaa/aaa.dart'; +-export 'bbb/bbb.dart'; +- +-part 'aaa/aaa.dart'; +-part 'bbb/bbb.dart'; +- +-main() { +-} +-'''); +- } +- +- test_sort_hasComments() async { +- await _computeUnitAndErrors(r''' +-// header +-library lib; +- +-import 'c.dart';// c +-import 'a.dart';// aa +-import 'b.dart';// bbb +- +-/** doc */ +-main() { +-} +-'''); +- // validate change +- _assertOrganize(r''' +-// header +-library lib; +- +-import 'a.dart'; +-import 'b.dart'; +-import 'c.dart'; +-// c +-// aa +-// bbb +- +-/** doc */ +-main() { +-} +-'''); +- } +- +- test_sort_imports_packageAndPath() async { +- await _computeUnitAndErrors(r''' +-library lib; +- +-import 'package:product.ui.api.bbb/manager1.dart'; +-import 'package:product.ui.api/entity2.dart'; +-import 'package:product.ui/entity.dart'; +-import 'package:product.ui.api.aaa/manager2.dart'; +-import 'package:product.ui.api/entity1.dart'; +-import 'package:product2.client/entity.dart'; +-'''); +- // validate change +- _assertOrganize(r''' +-library lib; +- +-import 'package:product.ui/entity.dart'; +-import 'package:product.ui.api/entity1.dart'; +-import 'package:product.ui.api/entity2.dart'; +-import 'package:product.ui.api.aaa/manager2.dart'; +-import 'package:product.ui.api.bbb/manager1.dart'; +-import 'package:product2.client/entity.dart'; +-'''); +- } +- +- void _assertOrganize(String expectedCode, +- {bool removeUnresolved: false, bool removeUnused: false}) { +- DirectiveOrganizer organizer = new DirectiveOrganizer( +- testCode, testUnit, testErrors, +- removeUnresolved: removeUnresolved, removeUnused: removeUnused); +- List edits = organizer.organize(); +- String result = SourceEdit.applySequence(testCode, edits); +- expect(result, expectedCode); +- } +- +- Future _computeUnitAndErrors(String code) async { +- addTestSource(code); +- AnalysisResult result = await driver.getResult(testSource.fullName); +- testUnit = result.unit; +- testErrors = result.errors; +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/sort_members_test.dart b/pkg/analysis_server/test/services/correction/sort_members_test.dart +deleted file mode 100644 +index 341cb3b315a..00000000000 +--- a/pkg/analysis_server/test/services/correction/sort_members_test.dart ++++ /dev/null +@@ -1,810 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/sort_members.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SortMembersTest); +- }); +-} +- +-@reflectiveTest +-class SortMembersTest extends AbstractSingleUnitTest { +- test_classMembers_accessor() async { +- await _parseTestUnit(r''' +-class A { +- set c(x) {} +- set a(x) {} +- get a => null; +- get b => null; +- set b(x) {} +- get c => null; +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- get a => null; +- set a(x) {} +- get b => null; +- set b(x) {} +- get c => null; +- set c(x) {} +-} +-'''); +- } +- +- test_classMembers_accessor_static() async { +- await _parseTestUnit(r''' +-class A { +- get a => null; +- set a(x) {} +- static get b => null; +- static set b(x) {} +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- static get b => null; +- static set b(x) {} +- get a => null; +- set a(x) {} +-} +-'''); +- } +- +- test_classMembers_constructor() async { +- await _parseTestUnit(r''' +-class A { +- A.c() { } +- A.a() { } +- A() {} +- A.b(); +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- A() {} +- A.a() { } +- A.b(); +- A.c() { } +-} +-'''); +- } +- +- test_classMembers_external_constructorMethod() async { +- await _parseTestUnit(r''' +-class Chart { +- external Pie(); +- external Chart(); +-} +-'''); +- // validate change +- _assertSort(r''' +-class Chart { +- external Chart(); +- external Pie(); +-} +-'''); +- } +- +- test_classMembers_field() async { +- await _parseTestUnit(r''' +-class A { +- String c; +- int a; +- void toString() => null; +- double b; +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- String c; +- int a; +- double b; +- void toString() => null; +-} +-'''); +- } +- +- test_classMembers_field_static() async { +- await _parseTestUnit(r''' +-class A { +- int b; +- int a; +- static int d; +- static int c; +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- static int d; +- static int c; +- int b; +- int a; +-} +-'''); +- } +- +- test_classMembers_method() async { +- await _parseTestUnit(r''' +-class A { +- c() {} +- a() {} +- b() {} +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- a() {} +- b() {} +- c() {} +-} +-'''); +- } +- +- test_classMembers_method_emptyLine() async { +- await _parseTestUnit(r''' +-class A { +- b() {} +- +- a() {} +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- a() {} +- +- b() {} +-} +-'''); +- } +- +- test_classMembers_method_ignoreCase() async { +- await _parseTestUnit(r''' +-class A { +- m_C() {} +- m_a() {} +- m_B() {} +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- m_a() {} +- m_B() {} +- m_C() {} +-} +-'''); +- } +- +- test_classMembers_method_static() async { +- await _parseTestUnit(r''' +-class A { +- static a() {} +- b() {} +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- b() {} +- static a() {} +-} +-'''); +- } +- +- test_classMembers_mix() async { +- await _parseTestUnit(r''' +-class A { +- /// static field public +- static int nnn; +- /// static field private +- static int _nnn; +- /// instance getter public +- int get nnn => null; +- /// instance setter public +- set nnn(x) {} +- /// instance getter private +- int get _nnn => null; +- /// instance setter private +- set _nnn(x) {} +- /// instance method public +- nnn() {} +- /// instance method private +- _nnn() {} +- /// static method public +- static nnn() {} +- /// static method private +- static _nnn() {} +- /// static getter public +- static int get nnn => null; +- /// static setter public +- static set nnn(x) {} +- /// static getter private +- static int get _nnn => null; +- /// static setter private +- static set _nnn(x) {} +- /// instance field public +- int nnn; +- /// instance field private +- int _nnn; +- /// constructor generative unnamed +- A(); +- /// constructor factory unnamed +- factory A() => null; +- /// constructor generative public +- A.nnn(); +- /// constructor factory public +- factory A.ooo() => null; +- /// constructor generative private +- A._nnn(); +- /// constructor factory private +- factory A._ooo() => null; +-} +-'''); +- // validate change +- _assertSort(r''' +-class A { +- /// static field public +- static int nnn; +- /// static field private +- static int _nnn; +- /// static getter public +- static int get nnn => null; +- /// static setter public +- static set nnn(x) {} +- /// static getter private +- static int get _nnn => null; +- /// static setter private +- static set _nnn(x) {} +- /// instance field public +- int nnn; +- /// instance field private +- int _nnn; +- /// constructor generative unnamed +- A(); +- /// constructor factory unnamed +- factory A() => null; +- /// constructor generative public +- A.nnn(); +- /// constructor factory public +- factory A.ooo() => null; +- /// constructor generative private +- A._nnn(); +- /// constructor factory private +- factory A._ooo() => null; +- /// instance getter public +- int get nnn => null; +- /// instance setter public +- set nnn(x) {} +- /// instance getter private +- int get _nnn => null; +- /// instance setter private +- set _nnn(x) {} +- /// instance method public +- nnn() {} +- /// instance method private +- _nnn() {} +- /// static method public +- static nnn() {} +- /// static method private +- static _nnn() {} +-} +-'''); +- } +- +- test_directives() async { +- await _parseTestUnit(r''' +-library lib; +- +-export 'dart:bbb'; +-import 'dart:bbb'; +-export 'package:bbb/bbb.dart'; +-export 'http://bbb.com'; +-import 'bbb/bbb.dart'; +-export 'http://aaa.com'; +-import 'http://bbb.com'; +-export 'dart:aaa'; +-export 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +-export 'aaa/aaa.dart'; +-export 'bbb/bbb.dart'; +-import 'dart:aaa'; +-import 'package:aaa/aaa.dart'; +-import 'aaa/aaa.dart'; +-import 'http://aaa.com'; +-part 'bbb/bbb.dart'; +-part 'aaa/aaa.dart'; +- +-main() { +-} +-'''); +- // validate change +- _assertSort(r''' +-library lib; +- +-import 'dart:aaa'; +-import 'dart:bbb'; +- +-import 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +- +-import 'http://aaa.com'; +-import 'http://bbb.com'; +- +-import 'aaa/aaa.dart'; +-import 'bbb/bbb.dart'; +- +-export 'dart:aaa'; +-export 'dart:bbb'; +- +-export 'package:aaa/aaa.dart'; +-export 'package:bbb/bbb.dart'; +- +-export 'http://aaa.com'; +-export 'http://bbb.com'; +- +-export 'aaa/aaa.dart'; +-export 'bbb/bbb.dart'; +- +-part 'aaa/aaa.dart'; +-part 'bbb/bbb.dart'; +- +-main() { +-} +-'''); +- } +- +- test_directives_docComment_hasLibrary_lines() async { +- await _parseTestUnit(r''' +-/// Library documentation comment A. +-/// Library documentation comment B. +-library foo.bar; +- +-/// bbb1 +-/// bbb2 +-/// bbb3 +-import 'b.dart'; +-/// aaa1 +-/// aaa2 +-import 'a.dart'; +-'''); +- // validate change +- _assertSort(r''' +-/// Library documentation comment A. +-/// Library documentation comment B. +-library foo.bar; +- +-/// aaa1 +-/// aaa2 +-import 'a.dart'; +-/// bbb1 +-/// bbb2 +-/// bbb3 +-import 'b.dart'; +-'''); +- } +- +- test_directives_docComment_hasLibrary_stars() async { +- await _parseTestUnit(r''' +-/** +- * Library documentation comment A. +- * Library documentation comment B. +- */ +-library foo.bar; +- +-/** +- * bbb +- */ +-import 'b.dart'; +-/** +- * aaa +- * aaa +- */ +-import 'a.dart'; +-'''); +- // validate change +- _assertSort(r''' +-/** +- * Library documentation comment A. +- * Library documentation comment B. +- */ +-library foo.bar; +- +-/** +- * aaa +- * aaa +- */ +-import 'a.dart'; +-/** +- * bbb +- */ +-import 'b.dart'; +-'''); +- } +- +- test_directives_docComment_noLibrary_lines() async { +- await _parseTestUnit(r''' +-/// Library documentation comment A +-/// Library documentation comment B +-import 'b.dart'; +-/// aaa1 +-/// aaa2 +-import 'a.dart'; +-'''); +- // validate change +- _assertSort(r''' +-/// aaa1 +-/// aaa2 +-/// Library documentation comment A +-/// Library documentation comment B +-import 'a.dart'; +-import 'b.dart'; +-'''); +- } +- +- test_directives_docComment_noLibrary_stars() async { +- await _parseTestUnit(r''' +-/** +- * Library documentation comment A. +- * Library documentation comment B. +- */ +-import 'b.dart'; +-/** +- * aaa +- * aaa +- */ +-import 'a.dart'; +-'''); +- // validate change +- _assertSort(r''' +-/** +- * aaa +- * aaa +- */ +-/** +- * Library documentation comment A. +- * Library documentation comment B. +- */ +-import 'a.dart'; +-import 'b.dart'; +-'''); +- } +- +- test_directives_imports_packageAndPath() async { +- await _parseTestUnit(r''' +-library lib; +- +-import 'package:product.ui.api.bbb/manager1.dart'; +-import 'package:product.ui.api/entity2.dart'; +-import 'package:product.ui/entity.dart'; +-import 'package:product.ui.api.aaa/manager2.dart'; +-import 'package:product.ui.api/entity1.dart'; +-import 'package:product2.client/entity.dart'; +-'''); +- // validate change +- _assertSort(r''' +-library lib; +- +-import 'package:product.ui/entity.dart'; +-import 'package:product.ui.api/entity1.dart'; +-import 'package:product.ui.api/entity2.dart'; +-import 'package:product.ui.api.aaa/manager2.dart'; +-import 'package:product.ui.api.bbb/manager1.dart'; +-import 'package:product2.client/entity.dart'; +-'''); +- } +- +- test_unitMembers_class() async { +- await _parseTestUnit(r''' +-class C {} +-class A {} +-class B {} +-'''); +- // validate change +- _assertSort(r''' +-class A {} +-class B {} +-class C {} +-'''); +- } +- +- test_unitMembers_class_ignoreCase() async { +- await _parseTestUnit(r''' +-class C {} +-class a {} +-class B {} +-'''); +- // validate change +- _assertSort(r''' +-class a {} +-class B {} +-class C {} +-'''); +- } +- +- test_unitMembers_classTypeAlias() async { +- await _parseTestUnit(r''' +-class M {} +-class C = Object with M; +-class A = Object with M; +-class B = Object with M; +-'''); +- // validate change +- _assertSort(r''' +-class A = Object with M; +-class B = Object with M; +-class C = Object with M; +-class M {} +-'''); +- } +- +- test_unitMembers_directive_hasDirective() async { +- await _parseTestUnit(r''' +-library lib; +-class C {} +-class A {} +-class B {} +-'''); +- // validate change +- _assertSort(r''' +-library lib; +-class A {} +-class B {} +-class C {} +-'''); +- } +- +- test_unitMembers_directive_noDirective_hasComment_line() async { +- await _parseTestUnit(r''' +-// Some comment +- +-class B {} +- +-class A {} +-'''); +- // validate change +- _assertSort(r''' +-// Some comment +- +-class A {} +- +-class B {} +-'''); +- } +- +- test_unitMembers_directive_noDirective_noComment() async { +- await _parseTestUnit(r''' +- +-class B {} +- +-class A {} +-'''); +- // validate change +- _assertSort(r''' +- +-class A {} +- +-class B {} +-'''); +- } +- +- test_unitMembers_enum() async { +- await _parseTestUnit(r''' +-enum C {x, y} +-enum A {x, y} +-enum B {x, y} +-'''); +- // validate change +- _assertSort(r''' +-enum A {x, y} +-enum B {x, y} +-enum C {x, y} +-'''); +- } +- +- test_unitMembers_enumClass() async { +- await _parseTestUnit(r''' +-enum C {x, y} +-class A {} +-class D {} +-enum B {x, y} +-'''); +- // validate change +- _assertSort(r''' +-class A {} +-enum B {x, y} +-enum C {x, y} +-class D {} +-'''); +- } +- +- test_unitMembers_function() async { +- await _parseTestUnit(r''' +-fc() {} +-fa() {} +-fb() {} +-'''); +- // validate change +- _assertSort(r''' +-fa() {} +-fb() {} +-fc() {} +-'''); +- } +- +- test_unitMembers_functionTypeAlias() async { +- await _parseTestUnit(r''' +-typedef FC(); +-typedef FA(); +-typedef FB(); +-'''); +- // validate change +- _assertSort(r''' +-typedef FA(); +-typedef FB(); +-typedef FC(); +-'''); +- } +- +- test_unitMembers_importsAndDeclarations() async { +- await _parseTestUnit(r''' +-import 'dart:a'; +-import 'package:b'; +- +-foo() { +-} +- +-f() => null; +-'''); +- // validate change +- _assertSort(r''' +-import 'dart:a'; +- +-import 'package:b'; +- +-f() => null; +- +-foo() { +-} +-'''); +- } +- +- test_unitMembers_mainFirst() async { +- await _parseTestUnit(r''' +-class C {} +-aaa() {} +-get bbb() {} +-class A {} +-main() {} +-class B {} +-'''); +- // validate change +- _assertSort(r''' +-main() {} +-get bbb() {} +-aaa() {} +-class A {} +-class B {} +-class C {} +-'''); +- } +- +- test_unitMembers_mix() async { +- await _parseTestUnit(r''' +-_mmm() {} +-typedef nnn(); +-_nnn() {} +-typedef mmm(); +-typedef _nnn(); +-typedef _mmm(); +-class mmm {} +-get _nnn => null; +-class nnn {} +-class _mmm {} +-class _nnn {} +-var mmm; +-var nnn; +-var _mmm; +-var _nnn; +-set nnn(x) {} +-get mmm => null; +-set mmm(x) {} +-get nnn => null; +-get _mmm => null; +-set _mmm(x) {} +-set _nnn(x) {} +-mmm() {} +-nnn() {} +-'''); +- // validate change +- _assertSort(r''' +-var mmm; +-var nnn; +-var _mmm; +-var _nnn; +-get mmm => null; +-set mmm(x) {} +-get nnn => null; +-set nnn(x) {} +-get _mmm => null; +-set _mmm(x) {} +-get _nnn => null; +-set _nnn(x) {} +-mmm() {} +-nnn() {} +-_mmm() {} +-_nnn() {} +-typedef mmm(); +-typedef nnn(); +-typedef _mmm(); +-typedef _nnn(); +-class mmm {} +-class nnn {} +-class _mmm {} +-class _nnn {} +-'''); +- } +- +- test_unitMembers_topLevelVariable() async { +- await _parseTestUnit(r''' +-int c; +-int a; +-int b; +-'''); +- // validate change +- _assertSort(r''' +-int a; +-int b; +-int c; +-'''); +- } +- +- test_unitMembers_topLevelVariable_withConst() async { +- await _parseTestUnit(r''' +-int c; +-int a; +-const B = 2; +-int b; +-const A = 1; +-'''); +- // validate change +- _assertSort(r''' +-const A = 1; +-const B = 2; +-int a; +-int b; +-int c; +-'''); +- } +- +- void _assertSort(String expectedCode) { +- MemberSorter sorter = new MemberSorter(testCode, testUnit); +- List edits = sorter.sort(); +- String result = SourceEdit.applySequence(testCode, edits); +- expect(result, expectedCode); +- } +- +- Future _parseTestUnit(String code) async { +- addTestSource(code); +- ParseResult result = await driver.parseFile(testSource.fullName); +- testUnit = result.unit; +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart +deleted file mode 100644 +index 041ee1e1704..00000000000 +--- a/pkg/analysis_server/test/services/correction/status_test.dart ++++ /dev/null +@@ -1,235 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/utilities/range_factory.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RefactoringLocationTest); +- defineReflectiveTests(RefactoringStatusTest); +- }); +-} +- +-@reflectiveTest +-class RefactoringLocationTest extends AbstractSingleUnitTest { +- test_createLocation_forElement() async { +- await resolveTestUnit('class MyClass {}'); +- Element element = findElement('MyClass'); +- // check +- Location location = newLocation_fromElement(element); +- expect(location.file, '/test.dart'); +- expect(location.offset, 6); +- expect(location.length, 7); +- expect(location.startLine, 1); +- expect(location.startColumn, 7); +- } +- +- test_createLocation_forMatch() async { +- await resolveTestUnit('class MyClass {}'); +- Element element = findElement('MyClass'); +- SourceRange sourceRange = range.elementName(element); +- SearchMatch match = new SearchMatchImpl( +- element.source.fullName, +- element.library.source, +- element.source, +- element.library, +- element, +- true, +- false, +- MatchKind.DECLARATION, +- sourceRange); +- // check +- Location location = newLocation_fromMatch(match); +- expect(location.file, '/test.dart'); +- expect(location.offset, sourceRange.offset); +- expect(location.length, sourceRange.length); +- } +- +- test_createLocation_forNode() async { +- await resolveTestUnit(''' +-main() { +-} +-'''); +- AstNode node = findNodeAtString('main'); +- // check +- Location location = newLocation_fromNode(node); +- expect(location.file, '/test.dart'); +- expect(location.offset, node.offset); +- expect(location.length, node.length); +- } +- +- test_createLocation_forUnit() async { +- await resolveTestUnit(''); +- SourceRange sourceRange = new SourceRange(10, 20); +- // check +- Location location = newLocation_fromUnit(testUnit, sourceRange); +- expect(location.file, '/test.dart'); +- expect(location.offset, sourceRange.offset); +- expect(location.length, sourceRange.length); +- } +-} +- +-@reflectiveTest +-class RefactoringStatusTest { +- void test_addError() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- // initial state +- expect(refactoringStatus.severity, null); +- // add ERROR +- refactoringStatus.addError('msg'); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR); +- expect(refactoringStatus.isOK, isFalse); +- expect(refactoringStatus.hasFatalError, isFalse); +- expect(refactoringStatus.hasError, isTrue); +- // problems +- List problems = refactoringStatus.problems; +- expect(problems, hasLength(1)); +- expect(problems[0].message, 'msg'); +- } +- +- void test_addFatalError_withLocation() { +- Location location = new Location('/test.dart', 1, 2, 3, 4); +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- // initial state +- expect(refactoringStatus.severity, null); +- // add FATAL +- refactoringStatus.addFatalError('msg', location); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.FATAL); +- expect(refactoringStatus.isOK, isFalse); +- expect(refactoringStatus.hasFatalError, isTrue); +- expect(refactoringStatus.hasError, isTrue); +- // problems +- List problems = refactoringStatus.problems; +- expect(problems, hasLength(1)); +- expect(problems[0].message, 'msg'); +- expect(problems[0].location.file, '/test.dart'); +- expect(problems[0].location.offset, 1); +- expect(problems[0].location.length, 2); +- // add WARNING, resulting severity is still FATAL +- refactoringStatus.addWarning("warning"); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.FATAL); +- } +- +- void test_addFatalError_withoutContext() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- // initial state +- expect(refactoringStatus.severity, null); +- // add FATAL +- refactoringStatus.addFatalError('msg'); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.FATAL); +- expect(refactoringStatus.isOK, isFalse); +- expect(refactoringStatus.hasFatalError, isTrue); +- expect(refactoringStatus.hasError, isTrue); +- // problems +- List problems = refactoringStatus.problems; +- expect(problems, hasLength(1)); +- expect(problems[0].message, 'msg'); +- expect(problems[0].location, isNull); +- } +- +- void test_addStatus_Error_withWarning() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- refactoringStatus.addError("err"); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR); +- // merge with OK +- { +- RefactoringStatus other = new RefactoringStatus(); +- other.addWarning("warn"); +- refactoringStatus.addStatus(other); +- } +- expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR); +- expect(refactoringStatus.message, 'err'); +- } +- +- void test_addStatus_Warning_null() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- refactoringStatus.addWarning("warn"); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.WARNING); +- // merge with "null" +- refactoringStatus.addStatus(null); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.WARNING); +- } +- +- void test_addStatus_Warning_withError() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- refactoringStatus.addWarning("warn"); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.WARNING); +- // merge with OK +- { +- RefactoringStatus other = new RefactoringStatus(); +- other.addError("err"); +- refactoringStatus.addStatus(other); +- } +- expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR); +- expect(refactoringStatus.message, 'err'); +- } +- +- void test_addWarning() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- // initial state +- expect(refactoringStatus.severity, null); +- // add WARNING +- refactoringStatus.addWarning('msg'); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.WARNING); +- expect(refactoringStatus.isOK, isFalse); +- expect(refactoringStatus.hasFatalError, isFalse); +- expect(refactoringStatus.hasError, isFalse); +- expect(refactoringStatus.hasWarning, isTrue); +- // problems +- List problems = refactoringStatus.problems; +- expect(problems, hasLength(1)); +- expect(problems[0].message, 'msg'); +- } +- +- void test_get_problem() { +- RefactoringStatus refactoringStatus = new RefactoringStatus(); +- // no entries +- expect(refactoringStatus.problem, isNull); +- expect(refactoringStatus.message, isNull); +- // add entries +- refactoringStatus.addError('msgError'); +- refactoringStatus.addWarning('msgWarning'); +- refactoringStatus.addFatalError('msgFatalError'); +- // get entry +- { +- RefactoringProblem problem = refactoringStatus.problem; +- expect(problem.severity, RefactoringProblemSeverity.FATAL); +- expect(problem.message, 'msgFatalError'); +- } +- // get message +- expect(refactoringStatus.problem.message, 'msgFatalError'); +- } +- +- void test_newError() { +- Location location = new Location('/test.dart', 1, 2, 3, 4); +- RefactoringStatus refactoringStatus = +- new RefactoringStatus.error('msg', location); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR); +- expect(refactoringStatus.problem.message, 'msg'); +- expect(refactoringStatus.problem.location.file, '/test.dart'); +- } +- +- void test_newFatalError() { +- RefactoringStatus refactoringStatus = new RefactoringStatus.fatal('msg'); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.FATAL); +- expect(refactoringStatus.message, 'msg'); +- } +- +- void test_newWarning() { +- RefactoringStatus refactoringStatus = new RefactoringStatus.warning('msg'); +- expect(refactoringStatus.severity, RefactoringProblemSeverity.WARNING); +- expect(refactoringStatus.message, 'msg'); +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/strings_test.dart b/pkg/analysis_server/test/services/correction/strings_test.dart +deleted file mode 100644 +index abd449379e1..00000000000 +--- a/pkg/analysis_server/test/services/correction/strings_test.dart ++++ /dev/null +@@ -1,175 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/strings.dart'; +-import 'package:test/test.dart' hide isEmpty; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(StringsTest); +- }); +-} +- +-@reflectiveTest +-class StringsTest { +- void test_capitalize() { +- expect(capitalize(''), ''); +- expect(capitalize('a'), 'A'); +- expect(capitalize('abc'), 'Abc'); +- expect(capitalize('abc def'), 'Abc def'); +- expect(capitalize('ABC'), 'ABC'); +- } +- +- void test_compareStrings() { +- expect(compareStrings(null, null), 0); +- expect(compareStrings(null, 'b'), 1); +- expect(compareStrings('a', null), -1); +- expect(compareStrings('a', 'b'), -1); +- expect(compareStrings('b', 'a'), 1); +- } +- +- void test_computeSimpleDiff() { +- assertDiff(String oldStr, String newStr) { +- SimpleDiff diff = computeSimpleDiff(oldStr, newStr); +- expect(diff.offset, isNonNegative); +- expect(diff.length, isNonNegative); +- String applied = oldStr.substring(0, diff.offset) + +- diff.replacement + +- oldStr.substring(diff.offset + diff.length); +- expect(applied, newStr); +- } +- +- assertDiff('', ''); +- assertDiff('', 'a'); +- assertDiff('abc', ''); +- assertDiff('abcd', 'acd'); +- assertDiff('a', 'b'); +- assertDiff('12345xyz', '12345abcxyz'); +- assertDiff('12345xyz', '12345xyzabc'); +- assertDiff('abbc', 'abbbc'); +- assertDiff('abbbbc', 'abbbbbbc'); +- } +- +- void test_countMatches() { +- expect(countMatches(null, null), 0); +- expect(countMatches('abc', null), 0); +- expect(countMatches(null, 'abc'), 0); +- expect(countMatches('ababa', 'a'), 3); +- expect(countMatches('ababa', 'ab'), 2); +- expect(countMatches('aaabaa', 'aa'), 2); +- } +- +- void test_findCommonPrefix() { +- expect(findCommonPrefix('abc', 'xyz'), 0); +- expect(findCommonPrefix('1234abcdef', '1234xyz'), 4); +- expect(findCommonPrefix('123', '123xyz'), 3); +- } +- +- void test_findCommonSuffix() { +- expect(findCommonSuffix('abc', 'xyz'), 0); +- expect(findCommonSuffix('abcdef1234', 'xyz1234'), 4); +- expect(findCommonSuffix('123', 'xyz123'), 3); +- } +- +- void test_isBlank() { +- expect(isBlank(null), isTrue); +- expect(isBlank(''), isTrue); +- expect(isBlank(' '), isTrue); +- expect(isBlank('\t'), isTrue); +- expect(isBlank(' '), isTrue); +- expect(isBlank('X'), isFalse); +- } +- +- void test_isDigit() { +- for (int c in '0123456789'.codeUnits) { +- expect(isDigit(c), isTrue); +- } +- expect(isDigit(' '.codeUnitAt(0)), isFalse); +- expect(isDigit('A'.codeUnitAt(0)), isFalse); +- } +- +- void test_isLetter() { +- for (int c in 'abcdefghijklmnopqrstuvwxyz'.codeUnits) { +- expect(isLetter(c), isTrue); +- } +- for (int c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.codeUnits) { +- expect(isLetter(c), isTrue); +- } +- expect(isLetter(' '.codeUnitAt(0)), isFalse); +- expect(isLetter('0'.codeUnitAt(0)), isFalse); +- } +- +- void test_isLetterOrDigit() { +- for (int c in 'abcdefghijklmnopqrstuvwxyz'.codeUnits) { +- expect(isLetterOrDigit(c), isTrue); +- } +- for (int c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.codeUnits) { +- expect(isLetterOrDigit(c), isTrue); +- } +- for (int c in '0123456789'.codeUnits) { +- expect(isLetterOrDigit(c), isTrue); +- } +- expect(isLetterOrDigit(' '.codeUnitAt(0)), isFalse); +- expect(isLetterOrDigit('.'.codeUnitAt(0)), isFalse); +- } +- +- void test_isSpace() { +- expect(isSpace(' '.codeUnitAt(0)), isTrue); +- expect(isSpace('\t'.codeUnitAt(0)), isTrue); +- expect(isSpace('\r'.codeUnitAt(0)), isFalse); +- expect(isSpace('\n'.codeUnitAt(0)), isFalse); +- expect(isSpace('0'.codeUnitAt(0)), isFalse); +- expect(isSpace('A'.codeUnitAt(0)), isFalse); +- } +- +- void test_isWhitespace() { +- expect(isWhitespace(' '.codeUnitAt(0)), isTrue); +- expect(isWhitespace('\t'.codeUnitAt(0)), isTrue); +- expect(isWhitespace('\r'.codeUnitAt(0)), isTrue); +- expect(isWhitespace('\n'.codeUnitAt(0)), isTrue); +- expect(isWhitespace('0'.codeUnitAt(0)), isFalse); +- expect(isWhitespace('A'.codeUnitAt(0)), isFalse); +- } +- +- void test_remove() { +- expect(remove(null, 'x'), null); +- expect(remove('abc', null), 'abc'); +- expect(remove('abc abbc abbbc', 'b'), 'ac ac ac'); +- expect(remove('abc abbc abbbc', 'bc'), 'a ab abb'); +- } +- +- void test_removeEnd() { +- expect(removeEnd(null, 'x'), null); +- expect(removeEnd('abc', null), 'abc'); +- expect(removeEnd('www.domain.com', '.com.'), 'www.domain.com'); +- expect(removeEnd('www.domain.com', 'domain'), 'www.domain.com'); +- expect(removeEnd('www.domain.com', '.com'), 'www.domain'); +- } +- +- void test_repeat() { +- expect(repeat('x', 0), ''); +- expect(repeat('x', 5), 'xxxxx'); +- expect(repeat('abc', 3), 'abcabcabc'); +- } +- +- void test_shorten() { +- expect(shorten('', 10), ''); +- expect(shorten('0', 10), '0'); +- expect(shorten('012', 10), '012'); +- expect(shorten('0123456789', 10), '0123456789'); +- expect(shorten('0123456789abcd', 10), '0123...bcd'); +- expect(shorten('0123456789abcde', 10), '0123...cde'); +- expect(shorten('0123456789abcdef', 10), '0123...def'); +- expect(shorten('0123456789abcdef', 11), '0123...cdef'); +- expect(shorten('0123456789abcdef', 12), '01234...cdef'); +- } +- +- void test_substringAfterLast() { +- expect(substringAfterLast('', '/'), ''); +- expect(substringAfterLast('abc', ''), ''); +- expect(substringAfterLast('abc', 'd'), 'abc'); +- expect(substringAfterLast('abcbde', 'b'), 'de'); +- } +-} +diff --git a/pkg/analysis_server/test/services/correction/test_all.dart b/pkg/analysis_server/test/services/correction/test_all.dart +deleted file mode 100644 +index 4183ef1a9d3..00000000000 +--- a/pkg/analysis_server/test/services/correction/test_all.dart ++++ /dev/null +@@ -1,32 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'assist_test.dart' as assist_test; +-import 'change_test.dart' as change_test; +-import 'fix_test.dart' as fix_test; +-import 'levenshtein_test.dart' as levenshtein_test; +-import 'name_suggestion_test.dart' as name_suggestion_test; +-import 'organize_directives_test.dart' as organize_directives_test; +-import 'sort_members_test.dart' as sort_members_test; +-import 'status_test.dart' as status_test; +-import 'strings_test.dart' as strings_test; +-import 'util_test.dart' as util_test; +- +-/// Utility for manually running all tests. +-main() { +- defineReflectiveSuite(() { +- assist_test.main(); +- change_test.main(); +- fix_test.main(); +- levenshtein_test.main(); +- name_suggestion_test.main(); +- organize_directives_test.main(); +- sort_members_test.main(); +- status_test.main(); +- strings_test.main(); +- util_test.main(); +- }, name: 'correction'); +-} +diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart +deleted file mode 100644 +index 1589df0d629..00000000000 +--- a/pkg/analysis_server/test/services/correction/util_test.dart ++++ /dev/null +@@ -1,252 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/util.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/src/utilities/string_utilities.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(UtilTest); +- }); +-} +- +-@reflectiveTest +-class UtilTest extends AbstractSingleUnitTest { +- test_addLibraryImports_dart_hasImports_between() async { +- await resolveTestUnit(''' +-import 'dart:async'; +-import 'dart:math'; +-'''); +- Source newLibrary = _getDartSource('dart:collection'); +- _assertAddLibraryImport([newLibrary], ''' +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:math'; +-'''); +- } +- +- test_addLibraryImports_dart_hasImports_first() async { +- await resolveTestUnit(''' +-import 'dart:collection'; +-import 'dart:math'; +-'''); +- Source newLibrary = _getDartSource('dart:async'); +- _assertAddLibraryImport([newLibrary], ''' +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:math'; +-'''); +- } +- +- test_addLibraryImports_dart_hasImports_last() async { +- await resolveTestUnit(''' +-import 'dart:async'; +-import 'dart:collection'; +-'''); +- Source newLibrary = _getDartSource('dart:math'); +- _assertAddLibraryImport([newLibrary], ''' +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:math'; +-'''); +- } +- +- test_addLibraryImports_dart_hasImports_multiple() async { +- await resolveTestUnit(''' +-import 'dart:collection'; +-import 'dart:math'; +-'''); +- Source newLibrary1 = _getDartSource('dart:async'); +- Source newLibrary2 = _getDartSource('dart:html'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:html'; +-import 'dart:math'; +-'''); +- } +- +- test_addLibraryImports_dart_hasImports_multiple_first() async { +- await resolveTestUnit(''' +-import 'dart:html'; +-import 'dart:math'; +-'''); +- Source newLibrary1 = _getDartSource('dart:async'); +- Source newLibrary2 = _getDartSource('dart:collection'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:html'; +-import 'dart:math'; +-'''); +- } +- +- test_addLibraryImports_dart_hasImports_multiple_last() async { +- await resolveTestUnit(''' +-import 'dart:async'; +-import 'dart:collection'; +-'''); +- Source newLibrary1 = _getDartSource('dart:html'); +- Source newLibrary2 = _getDartSource('dart:math'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:html'; +-import 'dart:math'; +-'''); +- } +- +- test_addLibraryImports_dart_hasLibraryDirective() async { +- await resolveTestUnit(''' +-library test; +- +-class A {} +-'''); +- Source newLibrary1 = _getDartSource('dart:math'); +- Source newLibrary2 = _getDartSource('dart:async'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-library test; +- +-import 'dart:async'; +-import 'dart:math'; +- +-class A {} +-'''); +- } +- +- test_addLibraryImports_dart_noDirectives_hasComment() async { +- await resolveTestUnit(''' +-/// Comment. +- +-class A {} +-'''); +- Source newLibrary1 = _getDartSource('dart:math'); +- Source newLibrary2 = _getDartSource('dart:async'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-/// Comment. +- +-import 'dart:async'; +-import 'dart:math'; +- +-class A {} +-'''); +- } +- +- test_addLibraryImports_dart_noDirectives_hasShebang() async { +- await resolveTestUnit(''' +-#!/bin/dart +- +-class A {} +-'''); +- Source newLibrary1 = _getDartSource('dart:math'); +- Source newLibrary2 = _getDartSource('dart:async'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-#!/bin/dart +- +-import 'dart:async'; +-import 'dart:math'; +- +-class A {} +-'''); +- } +- +- test_addLibraryImports_dart_noDirectives_noShebang() async { +- await resolveTestUnit(''' +-class A {} +-'''); +- Source newLibrary1 = _getDartSource('dart:math'); +- Source newLibrary2 = _getDartSource('dart:async'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-import 'dart:async'; +-import 'dart:math'; +- +-class A {} +-'''); +- } +- +- test_addLibraryImports_package_hasDart_hasPackages_insertAfter() async { +- addPackageSource('aaa', 'aaa.dart', ''); +- await resolveTestUnit(''' +-import 'dart:async'; +- +-import 'package:aaa/aaa.dart'; +-'''); +- Source newLibrary = _getSource('/lib/bbb.dart', 'package:bbb/bbb.dart'); +- _assertAddLibraryImport([newLibrary], ''' +-import 'dart:async'; +- +-import 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +-'''); +- } +- +- test_addLibraryImports_package_hasDart_hasPackages_insertBefore() async { +- addPackageSource('bbb', 'bbb.dart', ''); +- await resolveTestUnit(''' +-import 'dart:async'; +- +-import 'package:bbb/bbb.dart'; +-'''); +- Source newLibrary = _getSource('/lib/aaa.dart', 'package:aaa/aaa.dart'); +- _assertAddLibraryImport([newLibrary], ''' +-import 'dart:async'; +- +-import 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +-'''); +- } +- +- test_addLibraryImports_package_hasImports_between() async { +- addPackageSource('aaa', 'aaa.dart', ''); +- addPackageSource('ddd', 'ddd.dart', ''); +- await resolveTestUnit(''' +-import 'package:aaa/aaa.dart'; +-import 'package:ddd/ddd.dart'; +-'''); +- Source newLibrary1 = _getSource('/lib/bbb.dart', 'package:bbb/bbb.dart'); +- Source newLibrary2 = _getSource('/lib/ccc.dart', 'package:ccc/ccc.dart'); +- _assertAddLibraryImport([newLibrary1, newLibrary2], ''' +-import 'package:aaa/aaa.dart'; +-import 'package:bbb/bbb.dart'; +-import 'package:ccc/ccc.dart'; +-import 'package:ddd/ddd.dart'; +-'''); +- } +- +- void _assertAddLibraryImport(List newLibraries, String expectedCode) { +- SourceChange change = new SourceChange(''); +- addLibraryImports(change, testLibraryElement, newLibraries.toSet()); +- SourceFileEdit testEdit = change.getFileEdit(testFile); +- expect(testEdit, isNotNull); +- String resultCode = SourceEdit.applySequence(testCode, testEdit.edits); +- expect(resultCode, expectedCode); +- } +- +- Source _getDartSource(String uri) { +- String path = removeStart(uri, 'dart:'); +- return new _SourceMock('/sdk/lib/$path.dart', Uri.parse(uri)); +- } +- +- Source _getSource(String path, String uri) { +- return new _SourceMock(path, Uri.parse(uri)); +- } +-} +- +-class _SourceMock implements Source { +- @override +- final String fullName; +- +- @override +- final Uri uri; +- +- _SourceMock(this.fullName, this.uri); +- +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +-} +diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart +deleted file mode 100644 +index c88c48a5dec..00000000000 +--- a/pkg/analysis_server/test/services/linter/linter_test.dart ++++ /dev/null +@@ -1,79 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/analyzer.dart'; +-import 'package:analyzer/source/analysis_options_provider.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/lint/options_rule_validator.dart'; +-import 'package:linter/src/rules.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(LinterRuleOptionsValidatorTest); +- }); +-} +- +-@reflectiveTest +-class LinterRuleOptionsValidatorTest { +- final LinterRuleOptionsValidator validator = new LinterRuleOptionsValidator(); +- final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider(); +- +- RecordingErrorListener recorder; +- ErrorReporter reporter; +- +- List get errors => recorder.errors; +- +- setUp() { +- registerLintRules(); +- recorder = new RecordingErrorListener(); +- reporter = new ErrorReporter(recorder, new _TestSource()); +- } +- +- test_linter_defined_rules() { +- validate(''' +-linter: +- rules: +- - camel_case_types +- ''', []); +- } +- +- test_linter_no_rules() { +- validate(''' +-linter: +- rules: +- ''', []); +- } +- +- test_linter_null_rule() { +- validate(''' +-linter: +- rules: +- - +- +- ''', []); +- } +- +- test_linter_undefined_rule() { +- validate(''' +-linter: +- rules: +- - undefined +- ''', [UNDEFINED_LINT_WARNING]); +- } +- +- validate(String source, List expected) { +- var options = optionsProvider.getOptionsFromString(source); +- validator.validate(reporter, options); +- expect(errors.map((AnalysisError e) => e.errorCode), +- unorderedEquals(expected)); +- } +-} +- +-class _TestSource implements Source { +- @override +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +-} +diff --git a/pkg/analysis_server/test/services/linter/test_all.dart b/pkg/analysis_server/test/services/linter/test_all.dart +deleted file mode 100644 +index 270b1a41391..00000000000 +--- a/pkg/analysis_server/test/services/linter/test_all.dart ++++ /dev/null +@@ -1,13 +0,0 @@ +-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'linter_test.dart' as linter_test; +- +-main() { +- defineReflectiveSuite(() { +- linter_test.main(); +- }, name: 'linter'); +-} +diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart +deleted file mode 100644 +index afdd053c871..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart ++++ /dev/null +@@ -1,175 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart' show Element; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart'; +-import 'package:analyzer/src/dart/element/ast_provider.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show +- RefactoringProblem, +- RefactoringProblemSeverity, +- SourceChange, +- SourceEdit, +- SourceFileEdit; +-import 'package:test/test.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-int findIdentifierLength(String search) { +- int length = 0; +- while (length < search.length) { +- int c = search.codeUnitAt(length); +- if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) || +- c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) || +- c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) { +- break; +- } +- length++; +- } +- return length; +-} +- +-/** +- * The base class for all [Refactoring] tests. +- */ +-abstract class RefactoringTest extends AbstractSingleUnitTest { +- SearchEngine searchEngine; +- AstProvider astProvider; +- +- SourceChange refactoringChange; +- +- Refactoring get refactoring; +- +- /** +- * Asserts that [refactoringChange] contains a [FileEdit] for the file +- * with the given [path], and it results the [expectedCode]. +- */ +- void assertFileChangeResult(String path, String expectedCode) { +- // prepare FileEdit +- SourceFileEdit fileEdit = refactoringChange.getFileEdit(path); +- expect(fileEdit, isNotNull, reason: 'No file edit for $path'); +- // validate resulting code +- File file = provider.getResource(path); +- String ini = file.readAsStringSync(); +- String actualCode = SourceEdit.applySequence(ini, fileEdit.edits); +- expect(actualCode, expectedCode); +- } +- +- /** +- * Asserts that [refactoringChange] does not contain a [FileEdit] for the file +- * with the given [path]. +- */ +- void assertNoFileChange(String path) { +- SourceFileEdit fileEdit = refactoringChange.getFileEdit(path); +- expect(fileEdit, isNull); +- } +- +- /** +- * Asserts that [refactoring] initial/final conditions status is OK. +- */ +- Future assertRefactoringConditionsOK() async { +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatusOK(status); +- status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- /** +- * Asserts that [refactoring] final conditions status is OK. +- */ +- Future assertRefactoringFinalConditionsOK() async { +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- /** +- * Asserts that [status] has expected severity and message. +- */ +- void assertRefactoringStatus( +- RefactoringStatus status, RefactoringProblemSeverity expectedSeverity, +- {String expectedMessage, +- SourceRange expectedContextRange, +- String expectedContextSearch}) { +- expect(status.severity, expectedSeverity, reason: status.toString()); +- if (expectedSeverity != null) { +- RefactoringProblem problem = status.problem; +- expect(problem.severity, expectedSeverity); +- if (expectedMessage != null) { +- expect(problem.message, expectedMessage); +- } +- if (expectedContextRange != null) { +- expect(problem.location.offset, expectedContextRange.offset); +- expect(problem.location.length, expectedContextRange.length); +- } +- if (expectedContextSearch != null) { +- int expectedOffset = findOffset(expectedContextSearch); +- int expectedLength = findIdentifierLength(expectedContextSearch); +- expect(problem.location.offset, expectedOffset); +- expect(problem.location.length, expectedLength); +- } +- } +- } +- +- /** +- * Asserts that [refactoring] status is OK. +- */ +- void assertRefactoringStatusOK(RefactoringStatus status) { +- assertRefactoringStatus(status, null); +- } +- +- /** +- * Checks that all conditions of [refactoring] are OK and the result of +- * applying the [Change] to [testUnit] is [expectedCode]. +- */ +- Future assertSuccessfulRefactoring(String expectedCode) async { +- await assertRefactoringConditionsOK(); +- SourceChange change = await refactoring.createChange(); +- this.refactoringChange = change; +- assertTestChangeResult(expectedCode); +- } +- +- /** +- * Asserts that [refactoringChange] contains a [FileEdit] for [testFile], and +- * it results the [expectedCode]. +- */ +- void assertTestChangeResult(String expectedCode) { +- // prepare FileEdit +- SourceFileEdit fileEdit = refactoringChange.getFileEdit(testFile); +- expect(fileEdit, isNotNull); +- // validate resulting code +- String actualCode = SourceEdit.applySequence(testCode, fileEdit.edits); +- expect(actualCode, expectedCode); +- } +- +- /** +- * Completes with a fully resolved unit that contains the [element]. +- */ +- Future getResolvedUnitWithElement(Element element) async { +- return element.context +- .resolveCompilationUnit(element.source, element.library); +- } +- +- Future indexTestUnit(String code) async { +- await resolveTestUnit(code); +- } +- +- Future indexUnit(String file, String code) async { +- addSource(file, code); +- } +- +- void setUp() { +- super.setUp(); +- searchEngine = new SearchEngineImpl([driver]); +- astProvider = new AstProviderForDriver(driver); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart +deleted file mode 100644 +index 3d8633cf3a3..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart ++++ /dev/null +@@ -1,75 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/namespace.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +-import 'package:test/test.dart'; +- +-import 'abstract_refactoring.dart'; +- +-/** +- * The base class for all [RenameRefactoring] tests. +- */ +-class RenameRefactoringTest extends RefactoringTest { +- RenameRefactoring refactoring; +- +- /** +- * Asserts that [refactoring] has potential edits in [testFile] at offset +- * of the given [searches]. +- */ +- void assertPotentialEdits(List searches) { +- Set expectedOffsets = new Set(); +- for (String search in searches) { +- int offset = findOffset(search); +- expectedOffsets.add(offset); +- } +- // remove offset marked as potential +- for (String potentialId in refactoring.potentialEditIds) { +- SourceEdit edit = findEditById(potentialId); +- expect(edit, isNotNull); +- expectedOffsets.remove(edit.offset); +- } +- // all potential offsets are marked as such +- expect(expectedOffsets, isEmpty); +- } +- +- /** +- * Creates a new [RenameRefactoring] in [refactoring] for the [Element] of +- * the [SimpleIdentifier] at the given [search] pattern. +- */ +- void createRenameRefactoringAtString(String search) { +- SimpleIdentifier identifier = findIdentifier(search); +- Element element = identifier.bestElement; +- if (element is PrefixElement) { +- element = getImportElement(identifier); +- } +- createRenameRefactoringForElement(element); +- } +- +- /** +- * Creates a new [RenameRefactoring] in [refactoring] for [element]. +- * Fails if no [RenameRefactoring] can be created. +- */ +- void createRenameRefactoringForElement(Element element) { +- refactoring = new RenameRefactoring(searchEngine, astProvider, element); +- expect(refactoring, isNotNull, reason: "No refactoring for '$element'."); +- } +- +- /** +- * Returns the [Edit] with the given [id], maybe `null`. +- */ +- SourceEdit findEditById(String id) { +- for (SourceFileEdit fileEdit in refactoringChange.edits) { +- for (SourceEdit edit in fileEdit.edits) { +- if (edit.id == id) { +- return edit; +- } +- } +- } +- return null; +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart +deleted file mode 100644 +index 7712c7dbd6c..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart ++++ /dev/null +@@ -1,163 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide ElementKind; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ConvertGetterToMethodTest); +- }); +-} +- +-@reflectiveTest +-class ConvertGetterToMethodTest extends RefactoringTest { +- ConvertGetterToMethodRefactoring refactoring; +- +- test_change_function() async { +- await indexTestUnit(''' +-int get test => 42; +-main() { +- var a = test; +- var b = test; +-} +-'''); +- _createRefactoring('test'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int test() => 42; +-main() { +- var a = test(); +- var b = test(); +-} +-'''); +- } +- +- test_change_method() async { +- await indexTestUnit(''' +-class A { +- int get test => 1; +-} +-class B extends A { +- int get test => 2; +-} +-class C extends B { +- int get test => 3; +-} +-class D extends A { +- int get test => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test; +- var vb = b.test; +- var vc = c.test; +- var vd = d.test; +-} +-'''); +- _createRefactoringForString('test => 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- int test() => 1; +-} +-class B extends A { +- int test() => 2; +-} +-class C extends B { +- int test() => 3; +-} +-class D extends A { +- int test() => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test(); +- var vb = b.test(); +- var vc = c.test(); +- var vd = d.test(); +-} +-'''); +- } +- +- test_change_multipleFiles() async { +- await indexUnit('/other.dart', r''' +-class A { +- int get test => 1; +-} +-'''); +- await indexTestUnit(''' +-import 'other.dart'; +-class B extends A { +- int get test => 2; +-} +-main(A a, B b) { +- a.test; +- b.test; +-} +-'''); +- _createRefactoringForString('test => 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'other.dart'; +-class B extends A { +- int test() => 2; +-} +-main(A a, B b) { +- a.test(); +- b.test(); +-} +-'''); +- } +- +- test_checkInitialConditions_syntheticGetter() async { +- await indexTestUnit(''' +-int test = 42; +-main() { +-} +-'''); +- _createRefactoring('test'); +- // check conditions +- _assertInitialConditions_fatal( +- 'Only explicit getters can be converted to methods.'); +- } +- +- Future _assertInitialConditions_fatal(String message) async { +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: message); +- } +- +- /** +- * Checks that all conditions are OK and the result of applying [refactoring] +- * change to [testUnit] is [expectedCode]. +- */ +- Future _assertSuccessfulRefactoring(String expectedCode) async { +- await assertRefactoringConditionsOK(); +- SourceChange refactoringChange = await refactoring.createChange(); +- this.refactoringChange = refactoringChange; +- assertTestChangeResult(expectedCode); +- } +- +- void _createRefactoring(String elementName) { +- PropertyAccessorElement element = +- findElement(elementName, ElementKind.GETTER); +- _createRefactoringForElement(element); +- } +- +- void _createRefactoringForElement(ExecutableElement element) { +- refactoring = new ConvertGetterToMethodRefactoring( +- searchEngine, astProvider, element); +- } +- +- void _createRefactoringForString(String search) { +- ExecutableElement element = findNodeElementAtString(search); +- _createRefactoringForElement(element); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart +deleted file mode 100644 +index e9cb4d892eb..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart ++++ /dev/null +@@ -1,215 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/src/generated/testing/element_search.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show RefactoringProblemSeverity, SourceChange; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ConvertMethodToGetterTest); +- }); +-} +- +-@reflectiveTest +-class ConvertMethodToGetterTest extends RefactoringTest { +- ConvertMethodToGetterRefactoring refactoring; +- +- test_change_function() async { +- await indexTestUnit(''' +-int test() => 42; +-main() { +- var a = test(); +- var b = test(); +-} +-'''); +- _createRefactoring('test'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int get test => 42; +-main() { +- var a = test; +- var b = test; +-} +-'''); +- } +- +- test_change_method() async { +- await indexTestUnit(''' +-class A { +- int test() => 1; +-} +-class B extends A { +- int test() => 2; +-} +-class C extends B { +- int test() => 3; +-} +-class D extends A { +- int test() => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test(); +- var vb = b.test(); +- var vc = c.test(); +- var vd = d.test(); +-} +-'''); +- _createRefactoringForString('test() => 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- int get test => 1; +-} +-class B extends A { +- int get test => 2; +-} +-class C extends B { +- int get test => 3; +-} +-class D extends A { +- int get test => 4; +-} +-main(A a, B b, C c, D d) { +- var va = a.test; +- var vb = b.test; +- var vc = c.test; +- var vd = d.test; +-} +-'''); +- } +- +- test_change_multipleFiles() async { +- await indexUnit('/other.dart', r''' +-class A { +- int test() => 1; +-} +-'''); +- await indexTestUnit(''' +-import 'other.dart'; +-class B extends A { +- int test() => 2; +-} +-main(A a, B b) { +- a.test(); +- b.test(); +-} +-'''); +- _createRefactoringForString('test() => 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'other.dart'; +-class B extends A { +- int get test => 2; +-} +-main(A a, B b) { +- a.test; +- b.test; +-} +-'''); +- } +- +- test_checkInitialConditions_alreadyGetter() async { +- await indexTestUnit(''' +-int get test => 42; +-main() { +- var a = test; +- var b = test; +-} +-'''); +- ExecutableElement element = findElement('test', ElementKind.GETTER); +- _createRefactoringForElement(element); +- // check conditions +- _assertInitialConditions_fatal( +- 'Only class methods or top-level functions can be converted to getters.'); +- } +- +- test_checkInitialConditions_hasParameters() async { +- await indexTestUnit(''' +-int test(x) => x * 2; +-main() { +- var v = test(1); +-} +-'''); +- _createRefactoring('test'); +- // check conditions +- _assertInitialConditions_fatal( +- 'Only methods without parameters can be converted to getters.'); +- } +- +- test_checkInitialConditions_localFunction() async { +- await indexTestUnit(''' +-main() { +- test() {} +- var v = test(); +-} +-'''); +- ExecutableElement element = findElementsByName(testUnit, 'test').single; +- _createRefactoringForElement(element); +- // check conditions +- _assertInitialConditions_fatal( +- 'Only top-level functions can be converted to getters.'); +- } +- +- test_checkInitialConditions_notFunctionOrMethod() async { +- await indexTestUnit(''' +-class A { +- A.test(); +-} +-'''); +- _createRefactoring('test'); +- // check conditions +- _assertInitialConditions_fatal( +- 'Only class methods or top-level functions can be converted to getters.'); +- } +- +- test_checkInitialConditions_returnTypeVoid() async { +- await indexTestUnit(''' +-void test() {} +-'''); +- _createRefactoring('test'); +- // check conditions +- _assertInitialConditions_fatal('Cannot convert function returning void.'); +- } +- +- Future _assertInitialConditions_fatal(String message) async { +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: message); +- } +- +- /** +- * Checks that all conditions are OK and the result of applying the [Change] +- * to [testUnit] is [expectedCode]. +- */ +- Future _assertSuccessfulRefactoring(String expectedCode) async { +- await assertRefactoringConditionsOK(); +- SourceChange refactoringChange = await refactoring.createChange(); +- this.refactoringChange = refactoringChange; +- assertTestChangeResult(expectedCode); +- } +- +- void _createRefactoring(String elementName) { +- ExecutableElement element = findElement(elementName); +- _createRefactoringForElement(element); +- } +- +- void _createRefactoringForElement(ExecutableElement element) { +- refactoring = new ConvertMethodToGetterRefactoring( +- searchEngine, astProvider, element); +- } +- +- void _createRefactoringForString(String search) { +- ExecutableElement element = findNodeElementAtString(search); +- _createRefactoringForElement(element); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart +deleted file mode 100644 +index 03a65f233b3..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart ++++ /dev/null +@@ -1,1346 +0,0 @@ +-// Copyright (c) 2014, 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:convert'; +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/extract_local.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ExtractLocalTest); +- }); +-} +- +-@reflectiveTest +-class ExtractLocalTest extends RefactoringTest { +- ExtractLocalRefactoringImpl refactoring; +- +- test_checkFinalConditions_sameVariable_after() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +- var res; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // conflicting name +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "The name 'res' is already used in the scope."); +- } +- +- test_checkFinalConditions_sameVariable_before() async { +- await indexTestUnit(''' +-main() { +- var res; +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // conflicting name +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "The name 'res' is already used in the scope."); +- } +- +- test_checkInitialConditions_assignmentLeftHandSize() async { +- await indexTestUnit(''' +-main() { +- var v = 0; +- v = 1; +-} +-'''); +- _createRefactoringWithSuffix('v', ' = 1;'); +- // check conditions +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: 'Cannot extract the left-hand side of an assignment.'); +- } +- +- test_checkInitialConditions_namePartOfDeclaration_function() async { +- await indexTestUnit(''' +-main() { +-} +-'''); +- _createRefactoringWithSuffix('main', '()'); +- // check conditions +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: 'Cannot extract the name part of a declaration.'); +- } +- +- test_checkInitialConditions_namePartOfDeclaration_variable() async { +- await indexTestUnit(''' +-main() { +- int vvv = 0; +-} +-'''); +- _createRefactoringWithSuffix('vvv', ' = 0;'); +- // check conditions +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: 'Cannot extract the name part of a declaration.'); +- } +- +- test_checkInitialConditions_noExpression() async { +- await indexTestUnit(''' +-main() { +- // abc +-} +-'''); +- _createRefactoringForString('abc'); +- // check conditions +- _assertInitialConditions_fatal_selection(); +- } +- +- test_checkInitialConditions_notPartOfFunction() async { +- await indexTestUnit(''' +-int a = 1 + 2; +-'''); +- _createRefactoringForString('1 + 2'); +- // check conditions +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: 'An expression inside a function must be selected ' +- 'to activate this refactoring.'); +- } +- +- test_checkInitialConditions_stringSelection_leadingQuote() async { +- await indexTestUnit(''' +-main() { +- var vvv = 'abc'; +-} +-'''); +- _createRefactoringForString("'a"); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 'abc'; +- var vvv = res; +-} +-'''); +- } +- +- test_checkInitialConditions_stringSelection_trailingQuote() async { +- await indexTestUnit(''' +-main() { +- var vvv = 'abc'; +-} +-'''); +- _createRefactoringForString("c'"); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 'abc'; +- var vvv = res; +-} +-'''); +- } +- +- test_checkInitialConditions_voidExpression() async { +- await indexTestUnit(''' +-main() { +- print(42); +-} +-'''); +- _createRefactoringForString('print'); +- // check conditions +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: 'Cannot extract the void expression.'); +- } +- +- test_checkName() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- expect(refactoring.refactoringName, 'Extract Local Variable'); +- // null +- refactoring.name = null; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be null."); +- // empty +- refactoring.name = ''; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be empty."); +- // OK +- refactoring.name = 'res'; +- assertRefactoringStatusOK(refactoring.checkName()); +- } +- +- test_checkName_conflict_withInvokedFunction() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +- res(); +-} +- +-void res() {} +-'''); +- _createRefactoringForString('1 + 2'); +- await refactoring.checkInitialConditions(); +- refactoring.name = 'res'; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.ERROR, +- expectedMessage: "The name 'res' is already used in the scope."); +- } +- +- test_checkName_conflict_withOtherLocal() async { +- await indexTestUnit(''' +-main() { +- var res; +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- await refactoring.checkInitialConditions(); +- refactoring.name = 'res'; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.ERROR, +- expectedMessage: "The name 'res' is already used in the scope."); +- } +- +- test_checkName_conflict_withTypeName() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +- Res b = null; +-} +- +-class Res {} +-'''); +- _createRefactoringForString('1 + 2'); +- await refactoring.checkInitialConditions(); +- refactoring.name = 'Res'; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.ERROR, +- expectedMessage: "The name 'Res' is already used in the scope."); +- } +- +- test_completeStatementExpression() async { +- await indexTestUnit(''' +-main(p) { +- p.toString(); +-} +-'''); +- _createRefactoringForString('p.toString()'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(p) { +- var res = p.toString(); +-} +-'''); +- } +- +- test_const_argument_inConstInstanceCreation() async { +- await indexTestUnit(''' +-class A { +- const A(int a, int b); +-} +-main() { +- const A(1, 2); +-} +-'''); +- _createRefactoringForString('1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- const A(int a, int b); +-} +-main() { +- const res = 1; +- const A(res, 2); +-} +-'''); +- } +- +- test_const_inList() async { +- await indexTestUnit(''' +-main() { +- const [1, 2]; +-} +-'''); +- _createRefactoringForString('1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = 1; +- const [res, 2]; +-} +-'''); +- } +- +- test_const_inList_inBinaryExpression() async { +- await indexTestUnit(''' +-main() { +- const [1 + 2, 3]; +-} +-'''); +- _createRefactoringForString('1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = 1; +- const [res + 2, 3]; +-} +-'''); +- } +- +- test_const_inList_inConditionalExpression() async { +- await indexTestUnit(''' +-main() { +- const [true ? 1 : 2, 3]; +-} +-'''); +- _createRefactoringForString('1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = 1; +- const [true ? res : 2, 3]; +-} +-'''); +- } +- +- test_const_inList_inParenthesis() async { +- await indexTestUnit(''' +-main() { +- const [(1), 2]; +-} +-'''); +- _createRefactoringForString('1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = 1; +- const [(res), 2]; +-} +-'''); +- } +- +- test_const_inList_inPrefixExpression() async { +- await indexTestUnit(''' +-main() { +- const [!true, 2]; +-} +-'''); +- _createRefactoringForString('true'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = true; +- const [!res, 2]; +-} +-'''); +- } +- +- test_const_inMap_key() async { +- await indexTestUnit(''' +-main() { +- const {1: 2}; +-} +-'''); +- _createRefactoringForString('1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = 1; +- const {res: 2}; +-} +-'''); +- } +- +- test_const_inMap_value() async { +- await indexTestUnit(''' +-main() { +- const {1: 2}; +-} +-'''); +- _createRefactoringForString('2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- const res = 2; +- const {1: res}; +-} +-'''); +- } +- +- test_coveringExpressions() async { +- await indexTestUnit(''' +-main() { +- int aaa = 1; +- int bbb = 2; +- var c = aaa + bbb * 2 + 3; +-} +-'''); +- _createRefactoring(testCode.indexOf('bb * 2'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, +- ['bbb', 'bbb * 2', 'aaa + bbb * 2', 'aaa + bbb * 2 + 3']); +- } +- +- test_coveringExpressions_inArgumentList() async { +- await indexTestUnit(''' +-main() { +- foo(111 + 222); +-} +-int foo(int x) => x; +-'''); +- _createRefactoring(testCode.indexOf('11 +'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['111', '111 + 222', 'foo(111 + 222)']); +- } +- +- test_coveringExpressions_inInvocationOfVoidFunction() async { +- await indexTestUnit(''' +-main() { +- foo(111 + 222); +-} +-void foo(int x) {} +-'''); +- _createRefactoring(testCode.indexOf('11 +'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['111', '111 + 222']); +- } +- +- test_coveringExpressions_namedExpression_value() async { +- await indexTestUnit(''' +-main() { +- foo(ppp: 42); +-} +-int foo({int ppp: 0}) => ppp + 1; +-'''); +- _createRefactoring(testCode.indexOf('42'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['42', 'foo(ppp: 42)']); +- } +- +- test_coveringExpressions_skip_assignment() async { +- await indexTestUnit(''' +-main() { +- int v; +- foo(v = 111 + 222); +-} +-int foo(x) => 42; +-'''); +- _createRefactoring(testCode.indexOf('11 +'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['111', '111 + 222', 'foo(v = 111 + 222)']); +- } +- +- test_coveringExpressions_skip_constructorName() async { +- await indexTestUnit(''' +-class AAA { +- AAA.name() {} +-} +-main() { +- var v = new AAA.name(); +-} +-'''); +- _createRefactoring(testCode.indexOf('AA.name();'), 5); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['new AAA.name()']); +- } +- +- test_coveringExpressions_skip_constructorName_name() async { +- await indexTestUnit(''' +-class A { +- A.name() {} +-} +-main() { +- var v = new A.name(); +-} +-'''); +- _createRefactoring(testCode.indexOf('ame();'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['new A.name()']); +- } +- +- test_coveringExpressions_skip_constructorName_type() async { +- await indexTestUnit(''' +-class A {} +-main() { +- var v = new A(); +-} +-'''); +- _createRefactoring(testCode.indexOf('A();'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['new A()']); +- } +- +- test_coveringExpressions_skip_constructorName_typeArgument() async { +- await indexTestUnit(''' +-class A {} +-main() { +- var v = new A(); +-} +-'''); +- _createRefactoring(testCode.indexOf('ring>'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['new A()']); +- } +- +- test_coveringExpressions_skip_namedExpression() async { +- await indexTestUnit(''' +-main() { +- foo(ppp: 42); +-} +-int foo({int ppp: 0}) => ppp + 1; +-'''); +- _createRefactoring(testCode.indexOf('pp: 42'), 0); +- // check conditions +- await refactoring.checkInitialConditions(); +- List subExpressions = _getCoveringExpressions(); +- expect(subExpressions, ['foo(ppp: 42)']); +- } +- +- test_fragmentExpression() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString('2 + 3'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2 + 3; +- int a = res + 4; +-} +-'''); +- } +- +- test_fragmentExpression_leadingNotWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString('+ 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2; +- int a = res + 3 + 4; +-} +-'''); +- } +- +- test_fragmentExpression_leadingPartialSelection() async { +- await indexTestUnit(''' +-main() { +- int a = 111 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString('11 + 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 111 + 2; +- int a = res + 3 + 4; +-} +-'''); +- } +- +- test_fragmentExpression_leadingWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString(' 2 + 3'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2 + 3; +- int a = res + 4; +-} +-'''); +- } +- +- test_fragmentExpression_notAssociativeOperator() async { +- await indexTestUnit(''' +-main() { +- int a = 1 - 2 - 3 - 4; +-} +-'''); +- _createRefactoringForString('2 - 3'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 - 2 - 3; +- int a = res - 4; +-} +-'''); +- } +- +- test_fragmentExpression_trailingNotWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString('1 + 2 +'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2 + 3; +- int a = res + 4; +-} +-'''); +- } +- +- test_fragmentExpression_trailingPartialSelection() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 333 + 4; +-} +-'''); +- _createRefactoringForString('2 + 33'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2 + 333; +- int a = res + 4; +-} +-'''); +- } +- +- test_fragmentExpression_trailingWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString('2 + 3 '); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2 + 3; +- int a = res + 4; +-} +-'''); +- } +- +- test_guessNames_fragmentExpression() async { +- await indexTestUnit(''' +-main() { +- var a = 111 + 222 + 333 + 444; +-} +-'''); +- _createRefactoringForString('222 + 333'); +- // check guesses +- await refactoring.checkInitialConditions(); +- expect(refactoring.names, unorderedEquals(['i'])); +- } +- +- test_guessNames_singleExpression() async { +- await indexTestUnit(''' +-class TreeItem {} +-TreeItem getSelectedItem() => null; +-process(my) {} +-main() { +- process(getSelectedItem()); // marker +-} +-'''); +- _createRefactoringWithSuffix('getSelectedItem()', '); // marker'); +- // check guesses +- await refactoring.checkInitialConditions(); +- expect(refactoring.names, +- unorderedEquals(['selectedItem', 'item', 'my', 'treeItem'])); +- } +- +- test_guessNames_stringPart() async { +- await indexTestUnit(''' +-main() { +- var s = 'Hello Bob... welcome to Dart!'; +-} +-'''); +- _createRefactoringForString('Hello Bob'); +- // check guesses +- await refactoring.checkInitialConditions(); +- expect(refactoring.names, unorderedEquals(['helloBob', 'bob'])); +- } +- +- test_occurrences_differentVariable() async { +- await indexTestUnit(''' +-main() { +- { +- int v = 1; +- print(v + 1); // marker +- print(v + 1); +- } +- { +- int v = 2; +- print(v + 1); +- } +-} +-'''); +- _createRefactoringWithSuffix('v + 1', '); // marker'); +- // apply refactoring +- await _assertSuccessfulRefactoring(''' +-main() { +- { +- int v = 1; +- var res = v + 1; +- print(res); // marker +- print(res); +- } +- { +- int v = 2; +- print(v + 1); +- } +-} +-'''); +- _assertSingleLinkedEditGroup( +- length: 3, offsets: [36, 59, 85], names: ['object', 'i']); +- } +- +- test_occurrences_disableOccurrences() async { +- await indexTestUnit(''' +-int foo() => 42; +-main() { +- int a = 1 + foo(); +- int b = 2 + foo(); // marker +-} +-'''); +- _createRefactoringWithSuffix('foo()', '; // marker'); +- refactoring.extractAll = false; +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int foo() => 42; +-main() { +- int a = 1 + foo(); +- var res = foo(); +- int b = 2 + res; // marker +-} +-'''); +- } +- +- test_occurrences_ignore_assignmentLeftHandSize() async { +- await indexTestUnit(''' +-main() { +- int v = 1; +- v = 2; +- print(() {v = 2;}); +- print(1 + (() {v = 2; return 3;})()); +- print(v); // marker +-} +-'''); +- _createRefactoringWithSuffix('v', '); // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v = 1; +- v = 2; +- print(() {v = 2;}); +- print(1 + (() {v = 2; return 3;})()); +- var res = v; +- print(res); // marker +-} +-'''); +- } +- +- test_occurrences_ignore_nameOfVariableDeclaration() async { +- await indexTestUnit(''' +-main() { +- int v = 1; +- print(v); // marker +-} +-'''); +- _createRefactoringWithSuffix('v', '); // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v = 1; +- var res = v; +- print(res); // marker +-} +-'''); +- } +- +- test_occurrences_singleExpression() async { +- await indexTestUnit(''' +-int foo() => 42; +-main() { +- int a = 1 + foo(); +- int b = 2 + foo(); // marker +-} +-'''); +- _createRefactoringWithSuffix('foo()', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int foo() => 42; +-main() { +- var res = foo(); +- int a = 1 + res; +- int b = 2 + res; // marker +-} +-'''); +- } +- +- test_occurrences_useDominator() async { +- await indexTestUnit(''' +-main() { +- if (true) { +- print(42); +- } else { +- print(42); +- } +-} +-'''); +- _createRefactoringForString('42'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 42; +- if (true) { +- print(res); +- } else { +- print(res); +- } +-} +-'''); +- } +- +- test_occurrences_whenComment() async { +- await indexTestUnit(''' +-int foo() => 42; +-main() { +- /*int a = 1 + foo();*/ +- int b = 2 + foo(); // marker +-} +-'''); +- _createRefactoringWithSuffix('foo()', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int foo() => 42; +-main() { +- /*int a = 1 + foo();*/ +- var res = foo(); +- int b = 2 + res; // marker +-} +-'''); +- } +- +- test_occurrences_withSpace() async { +- await indexTestUnit(''' +-int foo(String s) => 42; +-main() { +- int a = 1 + foo('has space'); +- int b = 2 + foo('has space'); // marker +-} +-'''); +- _createRefactoringWithSuffix("foo('has space')", '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int foo(String s) => 42; +-main() { +- var res = foo('has space'); +- int a = 1 + res; +- int b = 2 + res; // marker +-} +-'''); +- } +- +- test_offsets_lengths() async { +- await indexTestUnit(''' +-int foo() => 42; +-main() { +- int a = 1 + foo(); // marker +- int b = 2 + foo( ); +-} +-'''); +- _createRefactoringWithSuffix('foo()', '; // marker'); +- // check offsets +- await refactoring.checkInitialConditions(); +- expect(refactoring.offsets, +- unorderedEquals([findOffset('foo();'), findOffset('foo( );')])); +- expect(refactoring.lengths, unorderedEquals([5, 6])); +- } +- +- test_singleExpression() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2; +- int a = res; +-} +-'''); +- } +- +- test_singleExpression_getter() async { +- await indexTestUnit(''' +-class A { +- int get foo => 42; +-} +-main() { +- A a = new A(); +- int b = 1 + a.foo; // marker +-} +-'''); +- _createRefactoringWithSuffix('a.foo', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- int get foo => 42; +-} +-main() { +- A a = new A(); +- var res = a.foo; +- int b = 1 + res; // marker +-} +-'''); +- } +- +- test_singleExpression_hasParseError_expectedSemicolon() async { +- verifyNoTestUnitErrors = false; +- await indexTestUnit(''' +-main(p) { +- foo +- p.bar.baz; +-} +-'''); +- _createRefactoringForString('p.bar'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(p) { +- foo +- var res = p.bar; +- res.baz; +-} +-'''); +- } +- +- test_singleExpression_inExpressionBody_ofClosure() async { +- await indexTestUnit(''' +-main() { +- print((x) => x.y * x.y + 1); +-} +-'''); +- _createRefactoringForString('x.y'); +- // apply refactoring +- await _assertSuccessfulRefactoring(''' +-main() { +- print((x) { +- var res = x.y; +- return res * res + 1; +- }); +-} +-'''); +- _assertSingleLinkedEditGroup( +- length: 3, offsets: [31, 53, 59], names: ['y']); +- } +- +- test_singleExpression_inExpressionBody_ofFunction() async { +- await indexTestUnit(''' +-foo(Point p) => p.x * p.x + p.y * p.y; +-class Point {int x; int y;} +-'''); +- _createRefactoringForString('p.x'); +- // apply refactoring +- await _assertSuccessfulRefactoring(''' +-foo(Point p) { +- var res = p.x; +- return res * res + p.y * p.y; +-} +-class Point {int x; int y;} +-'''); +- _assertSingleLinkedEditGroup( +- length: 3, offsets: [21, 41, 47], names: ['x', 'i']); +- } +- +- test_singleExpression_inExpressionBody_ofMethod() async { +- await indexTestUnit(''' +-class A { +- foo(Point p) => p.x * p.x + p.y * p.y; +-} +-class Point {int x; int y;} +-'''); +- _createRefactoringForString('p.x'); +- // apply refactoring +- await _assertSuccessfulRefactoring(''' +-class A { +- foo(Point p) { +- var res = p.x; +- return res * res + p.y * p.y; +- } +-} +-class Point {int x; int y;} +-'''); +- _assertSingleLinkedEditGroup( +- length: 3, offsets: [35, 57, 63], names: ['x', 'i']); +- } +- +- test_singleExpression_inIfElseIf() async { +- await indexTestUnit(''' +-main(int p) { +- if (p == 1) { +- print(1); +- } else if (p == 2) { +- print(2); +- } +-} +-'''); +- _createRefactoringForString('2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(int p) { +- var res = 2; +- if (p == 1) { +- print(1); +- } else if (p == res) { +- print(res); +- } +-} +-'''); +- } +- +- test_singleExpression_inMethod() async { +- await indexTestUnit(''' +-class A { +- main() { +- print(1 + 2); +- } +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- main() { +- var res = 1 + 2; +- print(res); +- } +-} +-'''); +- } +- +- test_singleExpression_leadingNotWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 12 + 345; +-} +-'''); +- _createRefactoringForString('+ 345'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 12 + 345; +- int a = res; +-} +-'''); +- } +- +- test_singleExpression_leadingWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 1 /*abc*/ + 2 + 345; +-} +-'''); +- _createRefactoringForString('1 /*abc*/'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 /*abc*/ + 2; +- int a = res + 345; +-} +-'''); +- } +- +- test_singleExpression_methodName_reference() async { +- await indexTestUnit(''' +-main() { +- var v = foo().length; +-} +-String foo() => ''; +-'''); +- _createRefactoringWithSuffix('foo', '().'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = foo(); +- var v = res.length; +-} +-String foo() => ''; +-'''); +- } +- +- test_singleExpression_nameOfProperty_prefixedIdentifier() async { +- await indexTestUnit(''' +-main(p) { +- var v = p.value; // marker +-} +-'''); +- _createRefactoringWithSuffix('value', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(p) { +- var res = p.value; +- var v = res; // marker +-} +-'''); +- } +- +- test_singleExpression_nameOfProperty_propertyAccess() async { +- await indexTestUnit(''' +-main() { +- var v = foo().length; // marker +-} +-String foo() => ''; +-'''); +- _createRefactoringWithSuffix('length', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = foo().length; +- var v = res; // marker +-} +-String foo() => ''; +-'''); +- } +- +- /** +- * Here we use knowledge how exactly `1 + 2 + 3 + 4` is parsed. We know that +- * `1 + 2` will be a separate and complete binary expression, so it can be +- * handled as a single expression. +- */ +- test_singleExpression_partOfBinaryExpression() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 + 3 + 4; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2; +- int a = res + 3 + 4; +-} +-'''); +- } +- +- test_singleExpression_string() async { +- await indexTestUnit(''' +-void main() { +- print("1234"); +-} +-'''); +- _createRefactoringAtString('34"'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-void main() { +- var res = "1234"; +- print(res); +-} +-'''); +- } +- +- test_singleExpression_trailingNotWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 12 + 345; +-} +-'''); +- _createRefactoringForString('12 +'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 12 + 345; +- int a = res; +-} +-'''); +- } +- +- test_singleExpression_trailingWhitespace() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2 ; +-} +-'''); +- _createRefactoringForString('1 + 2 '); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var res = 1 + 2; +- int a = res ; +-} +-'''); +- } +- +- test_stringLiteral_part() async { +- await indexTestUnit(''' +-main() { +- print('abcdefgh'); +-} +-'''); +- _createRefactoringForString('cde'); +- // apply refactoring +- await _assertSuccessfulRefactoring(r''' +-main() { +- var res = 'cde'; +- print('ab${res}fgh'); +-} +-'''); +- _assertSingleLinkedEditGroup(length: 3, offsets: [15, 41], names: ['cde']); +- } +- +- test_stringLiteral_whole() async { +- await indexTestUnit(''' +-main() { +- print('abc'); +-} +-'''); +- _createRefactoringForString("'abc'"); +- // apply refactoring +- await _assertSuccessfulRefactoring(''' +-main() { +- var res = 'abc'; +- print(res); +-} +-'''); +- _assertSingleLinkedEditGroup( +- length: 3, offsets: [15, 36], names: ['object', 's']); +- } +- +- test_stringLiteralPart() async { +- await indexTestUnit(r''' +-main() { +- int x = 1; +- int y = 2; +- print('$x+$y=${x+y}'); +-} +-'''); +- _createRefactoringForString(r'$x+$y'); +- // apply refactoring +- await _assertSuccessfulRefactoring(r''' +-main() { +- int x = 1; +- int y = 2; +- var res = '$x+$y'; +- print('${res}=${x+y}'); +-} +-'''); +- _assertSingleLinkedEditGroup(length: 3, offsets: [41, 67], names: ['xy']); +- } +- +- Future _assertInitialConditions_fatal_selection() async { +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- 'Expression must be selected to activate this refactoring.'); +- } +- +- void _assertSingleLinkedEditGroup( +- {int length, List offsets, List names}) { +- String positionsString = offsets +- .map((offset) => '{"file": "$testFile", "offset": $offset}') +- .join(','); +- String suggestionsString = +- names.map((name) => '{"value": "$name", "kind": "VARIABLE"}').join(','); +- _assertSingleLinkedEditGroupJson(''' +-{ +- "length": $length, +- "positions": [$positionsString], +- "suggestions": [$suggestionsString] +-}'''); +- } +- +- void _assertSingleLinkedEditGroupJson(String expectedJsonString) { +- List editGroups = refactoringChange.linkedEditGroups; +- expect(editGroups, hasLength(1)); +- expect(editGroups.first.toJson(), JSON.decode(expectedJsonString)); +- } +- +- /** +- * Checks that all conditions are OK and the result of applying the +- * [SourceChange] to [testUnit] is [expectedCode]. +- */ +- Future _assertSuccessfulRefactoring(String expectedCode) async { +- await assertRefactoringConditionsOK(); +- SourceChange refactoringChange = await refactoring.createChange(); +- this.refactoringChange = refactoringChange; +- assertTestChangeResult(expectedCode); +- } +- +- void _createRefactoring(int offset, int length) { +- refactoring = new ExtractLocalRefactoring(testUnit, offset, length); +- refactoring.name = 'res'; +- } +- +- /** +- * Creates a new refactoring in [refactoring] at the offset of the given +- * [search] pattern, and with the length `0`. +- */ +- void _createRefactoringAtString(String search) { +- int offset = findOffset(search); +- int length = 0; +- _createRefactoring(offset, length); +- } +- +- /** +- * Creates a new refactoring in [refactoring] for the selection range of the +- * given [search] pattern. +- */ +- void _createRefactoringForString(String search) { +- int offset = findOffset(search); +- int length = search.length; +- _createRefactoring(offset, length); +- } +- +- void _createRefactoringWithSuffix(String selectionSearch, String suffix) { +- int offset = findOffset(selectionSearch + suffix); +- int length = selectionSearch.length; +- _createRefactoring(offset, length); +- } +- +- List _getCoveringExpressions() { +- List subExpressions = []; +- for (int i = 0; i < refactoring.coveringExpressionOffsets.length; i++) { +- int offset = refactoring.coveringExpressionOffsets[i]; +- int length = refactoring.coveringExpressionLengths[i]; +- subExpressions.add(testCode.substring(offset, offset + length)); +- } +- return subExpressions; +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart +deleted file mode 100644 +index a5363ec4ec4..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart ++++ /dev/null +@@ -1,2886 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/extract_method.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ExtractMethodTest); +- }); +-} +- +-@reflectiveTest +-class ExtractMethodTest extends RefactoringTest { +- ExtractMethodRefactoringImpl refactoring; +- +- test_bad_assignmentLeftHandSide() async { +- await indexTestUnit(''' +-main() { +- int aaa; +- aaa = 0; +-} +-'''); +- _createRefactoringForString('aaa '); +- return _assertConditionsFatal( +- 'Cannot extract the left-hand side of an assignment.'); +- } +- +- test_bad_comment_selectionEndsInside() async { +- await indexTestUnit(''' +-main() { +-// start +- print(0); +-/* +-// end +-*/ +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal('Selection ends inside a comment.'); +- } +- +- test_bad_comment_selectionStartsInside() async { +- await indexTestUnit(''' +-main() { +-/* +-// start +-*/ +- print(0); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal('Selection begins inside a comment.'); +- } +- +- test_bad_conflict_method_alreadyDeclaresMethod() async { +- await indexTestUnit(''' +-class A { +- void res() {} +- main() { +-// start +- print(0); +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsError( +- "Class 'A' already declares method with name 'res'."); +- } +- +- test_bad_conflict_method_shadowsSuperDeclaration() async { +- await indexTestUnit(''' +-class A { +- void res() {} // marker +-} +-class B extends A { +- main() { +- res(); +-// start +- print(0); +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsError("Created method will shadow method 'A.res'."); +- } +- +- test_bad_conflict_topLevel_alreadyDeclaresFunction() async { +- await indexTestUnit(''' +-library my.lib; +- +-void res() {} +-main() { +-// start +- print(0); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsError( +- "Library already declares function with name 'res'."); +- } +- +- test_bad_conflict_topLevel_willHideInheritedMemberUsage() async { +- await indexTestUnit(''' +-class A { +- void res() {} +-} +-class B extends A { +- foo() { +- res(); // marker +- } +-} +-main() { +-// start +- print(0); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsError( +- "Created function will shadow method 'A.res'."); +- } +- +- test_bad_constructor_initializer() async { +- await indexTestUnit(''' +-class A { +- int f; +- A() : f = 0 {} +-} +-'''); +- _createRefactoringForString('f = 0'); +- return _assertConditionsFatal( +- 'Cannot extract a constructor initializer. Select expression part of initializer.'); +- } +- +- test_bad_constructor_redirectingConstructor() async { +- await indexTestUnit(''' +-class A { +- A() : this.named(); +- A.named() {} +-} +-'''); +- _createRefactoringForString('this.named()'); +- return _assertConditionsFatal( +- 'Cannot extract a constructor initializer. Select expression part of initializer.'); +- } +- +- test_bad_constructor_superConstructor() async { +- await indexTestUnit(''' +-class A {} +-class B extends A { +- B() : super(); +-} +-'''); +- _createRefactoringForString('super()'); +- return _assertConditionsFatal( +- 'Cannot extract a constructor initializer. Select expression part of initializer.'); +- } +- +- test_bad_doWhile_body() async { +- await indexTestUnit(''' +-main() { +- do +-// start +- { +- } +-// end +- while (true); +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Operation not applicable to a 'do' statement's body and expression."); +- } +- +- test_bad_emptySelection() async { +- await indexTestUnit(''' +-main() { +-// start +-// end +- print(0); +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Can only extract a single expression or a set of statements."); +- } +- +- test_bad_forLoop_conditionAndUpdaters() async { +- await indexTestUnit(''' +-main() { +- for ( +- int i = 0; +-// start +- i < 10; +- i++ +-// end +- ) {} +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Operation not applicable to a 'for' statement's condition and updaters."); +- } +- +- test_bad_forLoop_init() async { +- await indexTestUnit(''' +-main() { +- for ( +-// start +- int i = 0 +-// end +- ; i < 10; +- i++ +- ) {} +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Cannot extract initialization part of a 'for' statement."); +- } +- +- test_bad_forLoop_initAndCondition() async { +- await indexTestUnit(''' +-main() { +- for ( +-// start +- int i = 0; +- i < 10; +-// end +- i++ +- ) {} +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Operation not applicable to a 'for' statement's initializer and condition."); +- } +- +- test_bad_forLoop_updaters() async { +- await indexTestUnit(''' +-main() { +- for ( +- int i = 0; +- i < 10; +-// start +- i++ +-// end +- ) {} +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Cannot extract increment part of a 'for' statement."); +- } +- +- test_bad_forLoop_updatersAndBody() async { +- await indexTestUnit(''' +-main() { +- for ( +- int i = 0; +- i < 10; +-// start +- i++ +- ) {} +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Operation not applicable to a 'for' statement's updaters and body."); +- } +- +- test_bad_methodName_reference() async { +- await indexTestUnit(''' +-main() { +- main(); +-} +-'''); +- _createRefactoringWithSuffix('main', '();'); +- return _assertConditionsFatal("Cannot extract a single method name."); +- } +- +- test_bad_namePartOfDeclaration_function() async { +- await indexTestUnit(''' +-main() { +-} +-'''); +- _createRefactoringForString('main'); +- return _assertConditionsFatal( +- "Cannot extract the name part of a declaration."); +- } +- +- test_bad_namePartOfDeclaration_variable() async { +- await indexTestUnit(''' +-main() { +- int vvv = 0; +-} +-'''); +- _createRefactoringForString('vvv'); +- return _assertConditionsFatal( +- "Cannot extract the name part of a declaration."); +- } +- +- test_bad_namePartOfQualified() async { +- await indexTestUnit(''' +-class A { +- var fff; +-} +-main() { +- A a; +- a.fff = 1; +-} +-'''); +- _createRefactoringWithSuffix('fff', ' = 1'); +- return _assertConditionsFatal( +- "Can not extract name part of a property access."); +- } +- +- test_bad_newMethodName_notIdentifier() async { +- await indexTestUnit(''' +-main() { +-// start +- print(0); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- refactoring.name = 'bad-name'; +- // check conditions +- return _assertConditionsFatal("Method name must not contain '-'."); +- } +- +- test_bad_notSameParent() async { +- await indexTestUnit(''' +-main() { +- while (false) +-// start +- { +- } +- print(0); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- 'Not all selected statements are enclosed by the same parent statement.'); +- } +- +- test_bad_parameterName_duplicate() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +-// start +- int a = v1 + v2; // marker +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // update parameters +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(2)); +- parameters[0].name = 'dup'; +- parameters[1].name = 'dup'; +- refactoring.parameters = parameters; +- } +- return _assertFinalConditionsError("Parameter 'dup' already exists"); +- } +- +- test_bad_parameterName_inUse_function() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +-// start +- f(v1, v2); +-// end +-} +-f(a, b) {} +-'''); +- _createRefactoringForStartEndComments(); +- // update parameters +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(2)); +- parameters[0].name = 'f'; +- refactoring.parameters = parameters; +- } +- return _assertFinalConditionsError( +- "'f' is already used as a name in the selected code"); +- } +- +- test_bad_parameterName_inUse_localVariable() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +-// start +- int a = v1 + v2; // marker +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // update parameters +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(2)); +- parameters[0].name = 'a'; +- refactoring.parameters = parameters; +- } +- return _assertFinalConditionsError( +- "'a' is already used as a name in the selected code"); +- } +- +- test_bad_parameterName_inUse_method() async { +- await indexTestUnit(''' +-class A { +- main() { +- int v1 = 1; +- int v2 = 2; +- // start +- m(v1, v2); +- // end +- } +- m(a, b) {} +-} +-'''); +- _createRefactoringForStartEndComments(); +- // update parameters +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(2)); +- parameters[0].name = 'm'; +- refactoring.parameters = parameters; +- } +- return _assertFinalConditionsError( +- "'m' is already used as a name in the selected code"); +- } +- +- test_bad_selectionEndsInSomeNode() async { +- await indexTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _createRefactoringForStartEndString('print(0', 'rint(1)'); +- return _assertConditionsFatal( +- "The selection does not cover a set of statements or an expression. " +- "Extend selection to a valid range."); +- } +- +- test_bad_statements_exit_notAllExecutionFlows() async { +- await indexTestUnit(''' +-main(int p) { +-// start +- if (p == 0) { +- return; +- } +-// end +- print(p); +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsError(ExtractMethodRefactoringImpl.ERROR_EXITS); +- } +- +- test_bad_statements_return_andAssignsVariable() async { +- await indexTestUnit(''' +-main() { +-// start +- var v = 0; +- return 42; +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Ambiguous return value: Selected block contains assignment(s) to " +- "local variables and return statement."); +- } +- +- test_bad_switchCase() async { +- await indexTestUnit(''' +-main() { +- switch (1) { +-// start +- case 0: break; +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Selection must either cover whole switch statement " +- "or parts of a single case block."); +- } +- +- test_bad_tokensBetweenLastNodeAndSelectionEnd() async { +- await indexTestUnit(''' +-main() { +-// start +- print(0); +- print(1); +-} +-// end +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "The end of the selection contains characters that do not belong to a statement."); +- } +- +- test_bad_tokensBetweenSelectionStartAndFirstNode() async { +- await indexTestUnit(''' +-main() { +-// start +- print(0); // marker +- print(1); +-// end +-} +-'''); +- _createRefactoringForStartEndString('); // marker', '// end'); +- return _assertConditionsFatal( +- "The beginning of the selection contains characters that do not belong to a statement."); +- } +- +- test_bad_try_catchBlock_block() async { +- await indexTestUnit(''' +-main() { +- try +- {} +- catch (e) +-// start +- {} +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Selection must either cover whole try statement or " +- "parts of try, catch, or finally block."); +- } +- +- test_bad_try_catchBlock_complete() async { +- await indexTestUnit(''' +-main() { +- try +- {} +-// start +- catch (e) +- {} +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Selection must either cover whole try statement or " +- "parts of try, catch, or finally block."); +- } +- +- test_bad_try_catchBlock_exception() async { +- await indexTestUnit(''' +-main() { +- try { +- } catch ( +-// start +- e +-// end +- ) { +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- 'Cannot extract the name part of a declaration.'); +- } +- +- test_bad_try_finallyBlock() async { +- await indexTestUnit(''' +-main() { +- try +- {} +- finally +-// start +- {} +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Selection must either cover whole try statement or " +- "parts of try, catch, or finally block."); +- } +- +- test_bad_try_tryBlock() async { +- await indexTestUnit(''' +-main() { +- try +-// start +- {} +-// end +- finally +- {} +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Selection must either cover whole try statement or " +- "parts of try, catch, or finally block."); +- } +- +- test_bad_typeReference() async { +- await indexTestUnit(''' +-main() { +- int a = 0; +-} +-'''); +- _createRefactoringForString("int"); +- return _assertConditionsFatal("Cannot extract a single type reference."); +- } +- +- test_bad_variableDeclarationFragment() async { +- await indexTestUnit(''' +-main() { +- int +-// start +- a = 1 +-// end +- ,b = 2; +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Cannot extract a variable declaration fragment. Select whole declaration statement."); +- } +- +- test_bad_while_conditionAndBody() async { +- await indexTestUnit(''' +-main() { +- while +-// start +- (false) +- { +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- return _assertConditionsFatal( +- "Operation not applicable to a while statement's expression and body."); +- } +- +- test_canExtractGetter_false_closure() async { +- await indexTestUnit(''' +-main() { +- useFunction((_) => true); +-} +-useFunction(filter(String p)) {} +-'''); +- _createRefactoringForString('(_) => true'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, false); +- expect(refactoring.createGetter, false); +- } +- +- test_canExtractGetter_false_fieldAssignment() async { +- await indexTestUnit(''' +-class A { +- var f; +- main() { +-// start +- f = 1; +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, false); +- expect(refactoring.createGetter, false); +- } +- +- test_canExtractGetter_false_hasParameters() async { +- await indexTestUnit(''' +-main(int p) { +- int a = p + 1; +-} +-'''); +- _createRefactoringForString('p + 1'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, false); +- expect(refactoring.createGetter, false); +- } +- +- test_canExtractGetter_false_returnNotUsed_assignment() async { +- await indexTestUnit(''' +-var topVar = 0; +-f(int p) { +- topVar = 5; +-} +-'''); +- _createRefactoringForString('topVar = 5'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, false); +- expect(refactoring.createGetter, false); +- } +- +- test_canExtractGetter_false_returnNotUsed_noReturn() async { +- await indexTestUnit(''' +-var topVar = 0; +-main() { +-// start +- int a = 1; +- int b = 2; +- topVar = a + b; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, false); +- expect(refactoring.createGetter, false); +- } +- +- test_canExtractGetter_true() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, true); +- expect(refactoring.createGetter, true); +- } +- +- test_checkName() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // null +- refactoring.name = null; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be null."); +- // empty +- refactoring.name = ''; +- assertRefactoringStatus( +- refactoring.checkName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be empty."); +- // OK +- refactoring.name = 'res'; +- assertRefactoringStatusOK(refactoring.checkName()); +- } +- +- test_closure_asFunction_singleExpression() async { +- await indexTestUnit(''' +-process(f(x)) {} +-main() { +- process((x) => x * 2); +-} +-'''); +- _createRefactoringForString('(x) => x * 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-process(f(x)) {} +-main() { +- process(res); +-} +- +-res(x) => x * 2; +-'''); +- } +- +- test_closure_asFunction_statements() async { +- await indexTestUnit(''' +-process(f(x)) {} +-main() { +- process((x) { +- print(x); +- return x * 2; +- }); // marker +-} +-'''); +- _createRefactoringForStartEndString('(x) {', '); // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-process(f(x)) {} +-main() { +- process(res); // marker +-} +- +-res(x) { +- print(x); +- return x * 2; +-} +-'''); +- } +- +- test_closure_asMethod_statements() async { +- await indexTestUnit(''' +-process(f(x)) {} +-class A { +- int k = 2; +- main() { +- process((x) { +- print(x); +- return x * k; +- }); // marker +- } +-} +-'''); +- _createRefactoringForStartEndString('(x) {', '); // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-process(f(x)) {} +-class A { +- int k = 2; +- main() { +- process(res); // marker +- } +- +- res(x) { +- print(x); +- return x * k; +- } +-} +-'''); +- } +- +- test_closure_atArgumentName() async { +- await indexTestUnit(''' +-void process({int fff(int x)}) {} +-class C { +- main() { +- process(fff: (int x) => x * 2); +- } +-} +-'''); +- _createRefactoring(findOffset('ff: (int x)'), 0); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-void process({int fff(int x)}) {} +-class C { +- main() { +- process(fff: res); +- } +- +- int res(int x) => x * 2; +-} +-'''); +- } +- +- test_closure_atParameters() async { +- await indexTestUnit(''' +-void process(num f(int x)) {} +-class C { +- main() { +- process((int x) => x * 2); +- } +-} +-'''); +- _createRefactoring(findOffset('x) =>'), 0); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-void process(num f(int x)) {} +-class C { +- main() { +- process(res); +- } +- +- num res(int x) => x * 2; +-} +-'''); +- } +- +- test_closure_bad_referencesLocalVariable() async { +- await indexTestUnit(''' +-process(f(x)) {} +-main() { +- int k = 2; +- process((x) => x * k); +-} +-'''); +- _createRefactoringForString('(x) => x * k'); +- // check +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- 'Cannot extract closure as method, it references 1 external variable(s).'); +- } +- +- test_closure_bad_referencesParameter() async { +- await indexTestUnit(''' +-process(f(x)) {} +-main(int k) { +- process((x) => x * k); +-} +-'''); +- _createRefactoringForString('(x) => x * k'); +- // check +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- 'Cannot extract closure as method, it references 1 external variable(s).'); +- } +- +- test_fromTopLevelVariableInitializerClosure() async { +- await indexTestUnit(''' +-var X = 1; +- +-dynamic Y = () { +- return 1 + X; +-}; +-'''); +- _createRefactoringForString('1 + X'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-var X = 1; +- +-dynamic Y = () { +- return res(); +-}; +- +-int res() => 1 + X; +-'''); +- } +- +- test_getExtractGetter_expression_true_binaryExpression() async { +- await indexTestUnit(''' +-main() { +- print(1 + 2); +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.createGetter, true); +- } +- +- test_getExtractGetter_expression_true_literal() async { +- await indexTestUnit(''' +-main() { +- print(42); +-} +-'''); +- _createRefactoringForString('42'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.createGetter, true); +- } +- +- test_getExtractGetter_expression_true_prefixedExpression() async { +- await indexTestUnit(''' +-main() { +- print(!true); +-} +-'''); +- _createRefactoringForString('!true'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.createGetter, true); +- } +- +- test_getExtractGetter_expression_true_prefixedIdentifier() async { +- await indexTestUnit(''' +-main() { +- print(myValue.isEven); +-} +-int get myValue => 42; +-'''); +- _createRefactoringForString('myValue.isEven'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.createGetter, true); +- } +- +- test_getExtractGetter_expression_true_propertyAccess() async { +- await indexTestUnit(''' +-main() { +- print(1.isEven); +-} +-'''); +- _createRefactoringForString('1.isEven'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.createGetter, true); +- } +- +- test_getExtractGetter_statements() async { +- await indexTestUnit(''' +-main() { +-// start +- int v = 0; +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.createGetter, false); +- } +- +- test_getRefactoringName_function() async { +- await indexTestUnit(''' +-main() { +- print(1 + 2); +-} +-'''); +- _createRefactoringForString('1 + 2'); +- expect(refactoring.refactoringName, 'Extract Function'); +- } +- +- test_getRefactoringName_method() async { +- await indexTestUnit(''' +-class A { +- main() { +- print(1 + 2); +- } +-} +-'''); +- _createRefactoringForString('1 + 2'); +- expect(refactoring.refactoringName, 'Extract Method'); +- } +- +- test_names_singleExpression() async { +- await indexTestUnit(''' +-class TreeItem {} +-TreeItem getSelectedItem() => null; +-process(my) {} +-main() { +- process(getSelectedItem()); // marker +- int treeItem = 0; +-} +-'''); +- _createRefactoringWithSuffix('getSelectedItem()', '); // marker'); +- // check names +- await refactoring.checkInitialConditions(); +- expect(refactoring.names, +- unorderedEquals(['selectedItem', 'item', 'my', 'treeItem2'])); +- } +- +- test_offsets_lengths() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +- int b = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- await refactoring.checkInitialConditions(); +- expect(refactoring.offsets, +- unorderedEquals([findOffset('1 + 2'), findOffset('1 + 2')])); +- expect(refactoring.lengths, unorderedEquals([5, 6])); +- } +- +- test_returnType_closure() async { +- await indexTestUnit(''' +-process(f(x)) {} +-main() { +- process((x) => x * 2); +-} +-'''); +- _createRefactoringForString('(x) => x * 2'); +- // do check +- await refactoring.checkInitialConditions(); +- expect(refactoring.returnType, ''); +- } +- +- test_returnType_expression() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // do check +- await refactoring.checkInitialConditions(); +- expect(refactoring.returnType, 'int'); +- } +- +- test_returnType_mixInterfaceFunction() async { +- await indexTestUnit(''' +-main() { +-// start +- if (true) { +- return 1; +- } else { +- return () {}; +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // do check +- await refactoring.checkInitialConditions(); +- expect(refactoring.returnType, 'Object'); +- } +- +- test_returnType_statements() async { +- await indexTestUnit(''' +-main() { +-// start +- double v = 5.0; +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // do check +- await refactoring.checkInitialConditions(); +- expect(refactoring.returnType, 'double'); +- } +- +- test_returnType_statements_nullMix() async { +- await indexTestUnit(''' +-main(bool p) { +-// start +- if (p) { +- return 42; +- } +- return null; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // do check +- await refactoring.checkInitialConditions(); +- expect(refactoring.returnType, 'int'); +- } +- +- test_returnType_statements_void() async { +- await indexTestUnit(''' +-main() { +-// start +- print(42); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // do check +- await refactoring.checkInitialConditions(); +- expect(refactoring.returnType, 'void'); +- } +- +- test_setExtractGetter() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- await assertRefactoringConditionsOK(); +- expect(refactoring.canCreateGetter, true); +- expect(refactoring.createGetter, true); +- refactoringChange = await refactoring.createChange(); +- assertTestChangeResult(''' +-main() { +- int a = res; +-} +- +-int get res => 1 + 2; +-'''); +- } +- +- test_singleExpression() async { +- await indexTestUnit(''' +-main() { +- int a = 1 + 2; +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int a = res(); +-} +- +-int res() => 1 + 2; +-'''); +- } +- +- test_singleExpression_cascade() async { +- await indexTestUnit(''' +-main() { +- String s = ''; +- var v = s..length; +-} +-'''); +- _createRefactoringForString('s..length'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- String s = ''; +- var v = res(s); +-} +- +-String res(String s) => s..length; +-'''); +- } +- +- test_singleExpression_dynamic() async { +- await indexTestUnit(''' +-dynaFunction() {} +-main() { +- var v = dynaFunction(); // marker +-} +-'''); +- _createRefactoringWithSuffix('dynaFunction()', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-dynaFunction() {} +-main() { +- var v = res(); // marker +-} +- +-res() => dynaFunction(); +-'''); +- } +- +- test_singleExpression_hasAwait() async { +- await indexTestUnit(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +- int v = await getValue(); +- print(v); +-} +-'''); +- _createRefactoringForString('await getValue()'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +- int v = await res(); +- print(v); +-} +- +-Future res() async => await getValue(); +-'''); +- } +- +- test_singleExpression_ignore_assignmentLeftHandSize() async { +- await indexTestUnit(''' +-main() { +- getButton().text = 'txt'; +- print(getButton().text); // marker +-} +-getButton() {} +-'''); +- _createRefactoringWithSuffix('getButton().text', '); // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- getButton().text = 'txt'; +- print(res()); // marker +-} +- +-res() => getButton().text; +-getButton() {} +-'''); +- } +- +- test_singleExpression_occurrences() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int positiveA = v1 + v2; // marker +- int positiveB = v2 + v3; +- int positiveC = v1 + v2; +- int positiveD = v1/*abc*/ + v2; +- int negA = 1 + 2; +- int negB = 1 + v2; +- int negC = v1 + 2; +- int negD = v1 * v2; +-} +-'''); +- _createRefactoringWithSuffix('v1 + v2', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int positiveA = res(v1, v2); // marker +- int positiveB = res(v2, v3); +- int positiveC = res(v1, v2); +- int positiveD = res(v1, v2); +- int negA = 1 + 2; +- int negB = 1 + v2; +- int negC = v1 + 2; +- int negD = v1 * v2; +-} +- +-int res(int v1, int v2) => v1 + v2; +-'''); +- } +- +- test_singleExpression_occurrences_disabled() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = v1 + v2; // marker +- int b = v2 + v3; +-} +-'''); +- _createRefactoringWithSuffix('v1 + v2', '; // marker'); +- refactoring.extractAll = false; +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = res(v1, v2); // marker +- int b = v2 + v3; +-} +- +-int res(int v1, int v2) => v1 + v2; +-'''); +- } +- +- test_singleExpression_occurrences_inClassOnly() async { +- await indexTestUnit(''' +-class A { +- myMethod() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = v1 + v2; // marker +- } +-} +-main() { +- int v1 = 1; +- int v2 = 2; +- int negA = v1 + v2; +-} +-'''); +- _createRefactoringWithSuffix('v1 + v2', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- myMethod() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = res(v1, v2); // marker +- } +- +- int res(int v1, int v2) => v1 + v2; +-} +-main() { +- int v1 = 1; +- int v2 = 2; +- int negA = v1 + v2; +-} +-'''); +- } +- +- test_singleExpression_occurrences_incompatibleTypes() async { +- await indexTestUnit(''' +-main() { +- int x = 1; +- String y = 'foo'; +- print(x.toString()); +- print(y.toString()); +-} +-'''); +- _createRefactoringForString('x.toString()'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int x = 1; +- String y = 'foo'; +- print(res(x)); +- print(y.toString()); +-} +- +-String res(int x) => x.toString(); +-'''); +- } +- +- test_singleExpression_occurrences_inWholeUnit() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = v1 + v2; // marker +-} +-class A { +- myMethod() { +- int v1 = 1; +- int v2 = 2; +- int positiveB = v1 + v2; +- } +-} +-'''); +- _createRefactoringWithSuffix('v1 + v2', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = res(v1, v2); // marker +-} +- +-int res(int v1, int v2) => v1 + v2; +-class A { +- myMethod() { +- int v1 = 1; +- int v2 = 2; +- int positiveB = res(v1, v2); +- } +-} +-'''); +- } +- +- test_singleExpression_parameter_functionTypeAlias() async { +- await indexTestUnit(''' +-typedef R Foo(S s); +-void main(Foo foo, String s) { +- int a = foo(s); +-} +-'''); +- _createRefactoringForString('foo(s)'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-typedef R Foo(S s); +-void main(Foo foo, String s) { +- int a = res(foo, s); +-} +- +-int res(Foo foo, String s) => foo(s); +-'''); +- } +- +- test_singleExpression_returnType_importLibrary() async { +- _addLibraryReturningAsync(); +- await indexTestUnit(''' +-import 'asyncLib.dart'; +-main() { +- var a = newFuture(); +-} +-'''); +- _createRefactoringForString('newFuture()'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'asyncLib.dart'; +-import 'dart:async'; +-main() { +- var a = res(); +-} +- +-Future res() => newFuture(); +-'''); +- } +- +- test_singleExpression_returnTypeGeneric() async { +- await indexTestUnit(''' +-main() { +- var v = new List(); +-} +-'''); +- _createRefactoringForString('new List()'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var v = res(); +-} +- +-List res() => new List(); +-'''); +- } +- +- test_singleExpression_returnTypePrefix() async { +- await indexTestUnit(''' +-import 'dart:math' as pref; +-main() { +- var v = new pref.Random(); +-} +-'''); +- _createRefactoringForString('new pref.Random()'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'dart:math' as pref; +-main() { +- var v = res(); +-} +- +-pref.Random res() => new pref.Random(); +-'''); +- } +- +- test_singleExpression_staticContext_extractFromInitializer() async { +- await indexTestUnit(''' +-class A { +- A(int v) {} +-} +-class B extends A { +- B() : super(1 + 2) {} +-} +-'''); +- _createRefactoringForString('1 + 2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- A(int v) {} +-} +-class B extends A { +- B() : super(res()) {} +- +- static int res() => 1 + 2; +-} +-'''); +- } +- +- test_singleExpression_staticContext_extractFromInstance() async { +- await indexTestUnit(''' +-class A { +- instanceMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = v1 + v2; // marker +- } +- instanceMethodB() { +- int v1 = 1; +- int v2 = 2; +- int positiveB = v1 + v2; +- } +- static staticMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = v1 + v2; +- } +-} +-'''); +- _createRefactoringWithSuffix('v1 + v2', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- instanceMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = res(v1, v2); // marker +- } +- +- static int res(int v1, int v2) => v1 + v2; +- instanceMethodB() { +- int v1 = 1; +- int v2 = 2; +- int positiveB = res(v1, v2); +- } +- static staticMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = res(v1, v2); +- } +-} +-'''); +- } +- +- test_singleExpression_staticContext_extractFromStatic() async { +- await indexTestUnit(''' +-class A { +- static staticMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = v1 + v2; // marker +- } +- static staticMethodB() { +- int v1 = 1; +- int v2 = 2; +- int positiveB = v1 + v2; +- } +- instanceMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = v1 + v2; +- } +-} +-'''); +- _createRefactoringWithSuffix('v1 + v2', '; // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- static staticMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = res(v1, v2); // marker +- } +- +- static int res(int v1, int v2) => v1 + v2; +- static staticMethodB() { +- int v1 = 1; +- int v2 = 2; +- int positiveB = res(v1, v2); +- } +- instanceMethodA() { +- int v1 = 1; +- int v2 = 2; +- int positiveA = res(v1, v2); +- } +-} +-'''); +- } +- +- test_singleExpression_staticContext_hasInInitializer() async { +- await indexTestUnit(''' +-class A { +- A(int v) {} +-} +-class B extends A { +- B() : super(1 + 2) {} +- foo() { +- print(1 + 2); // marker +- } +-} +-'''); +- _createRefactoringWithSuffix('1 + 2', '); // marker'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- A(int v) {} +-} +-class B extends A { +- B() : super(res()) {} +- foo() { +- print(res()); // marker +- } +- +- static int res() => 1 + 2; +-} +-'''); +- } +- +- test_singleExpression_usesParameter() async { +- await indexTestUnit(''' +-fooA(int a1) { +- int a2 = 2; +- int a = a1 + a2; +-} +-fooB(int b1) { +- int b2 = 2; +- int b = b1 + b2; +-} +-'''); +- _createRefactoringForString('a1 + a2'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-fooA(int a1) { +- int a2 = 2; +- int a = res(a1, a2); +-} +- +-int res(int a1, int a2) => a1 + a2; +-fooB(int b1) { +- int b2 = 2; +- int b = res(b1, b2); +-} +-'''); +- } +- +- test_singleExpression_withVariables() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int a = v1 + v2 + v1; +-} +-'''); +- _createRefactoringForString('v1 + v2 + v1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int a = res(v1, v2); +-} +- +-int res(int v1, int v2) => v1 + v2 + v1; +-'''); +- } +- +- test_singleExpression_withVariables_doRename() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = v1 + v2 + v1; // marker +- int b = v2 + v3 + v2; +-} +-'''); +- _createRefactoringForString('v1 + v2 + v1'); +- // apply refactoring +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(2)); +- expect(parameters[0].name, 'v1'); +- expect(parameters[1].name, 'v2'); +- parameters[0].name = 'par1'; +- parameters[1].name = 'param2'; +- refactoring.parameters = parameters; +- } +- await assertRefactoringFinalConditionsOK(); +- refactoring.createGetter = false; +- return _assertRefactoringChange(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = res(v1, v2); // marker +- int b = res(v2, v3); +-} +- +-int res(int par1, int param2) => par1 + param2 + par1; +-'''); +- } +- +- test_singleExpression_withVariables_doReorder() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = v1 + v2; // marker +- int b = v2 + v3; +-} +-'''); +- _createRefactoringForString('v1 + v2'); +- // apply refactoring +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(2)); +- expect(parameters[0].name, 'v1'); +- expect(parameters[1].name, 'v2'); +- var parameter = parameters.removeAt(1); +- parameters.insert(0, parameter); +- refactoring.parameters = parameters; +- } +- await assertRefactoringFinalConditionsOK(); +- refactoring.createGetter = false; +- return _assertRefactoringChange(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = res(v2, v1); // marker +- int b = res(v3, v2); +-} +- +-int res(int v2, int v1) => v1 + v2; +-'''); +- } +- +- test_singleExpression_withVariables_namedExpression() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int a = process(arg: v1 + v2); +-} +-process({arg}) {} +-'''); +- _createRefactoringForString('process(arg: v1 + v2)'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int a = res(v1, v2); +-} +- +-res(int v1, int v2) => process(arg: v1 + v2); +-process({arg}) {} +-'''); +- } +- +- test_singleExpression_withVariables_newType() async { +- await indexTestUnit(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = v1 + v2 + v3; +-} +-'''); +- _createRefactoringForString('v1 + v2 + v3'); +- // apply refactoring +- await refactoring.checkInitialConditions(); +- { +- List parameters = _getParametersCopy(); +- expect(parameters, hasLength(3)); +- expect(parameters[0].name, 'v1'); +- expect(parameters[1].name, 'v2'); +- expect(parameters[2].name, 'v3'); +- parameters[0].type = 'num'; +- parameters[1].type = 'dynamic'; +- parameters[2].type = ''; +- refactoring.parameters = parameters; +- } +- await assertRefactoringFinalConditionsOK(); +- refactoring.createGetter = false; +- return _assertRefactoringChange(''' +-main() { +- int v1 = 1; +- int v2 = 2; +- int v3 = 3; +- int a = res(v1, v2, v3); +-} +- +-int res(num v1, v2, v3) => v1 + v2 + v3; +-'''); +- } +- +- test_singleExpression_withVariables_useBestType() async { +- await indexTestUnit(''' +-main() { +- var v1 = 1; +- var v2 = 2; +- var a = v1 + v2 + v1; // marker +-} +-'''); +- _createRefactoringForString('v1 + v2 + v1'); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- var v1 = 1; +- var v2 = 2; +- var a = res(v1, v2); // marker +-} +- +-int res(int v1, int v2) => v1 + v2 + v1; +-'''); +- } +- +- test_statements_assignment() async { +- await indexTestUnit(''' +-main() { +- int v; +-// start +- v = 5; +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int v; +-// start +- v = res(v); +-// end +- print(v); +-} +- +-int res(int v) { +- v = 5; +- return v; +-} +-'''); +- } +- +- test_statements_changeIndentation() async { +- await indexTestUnit(''' +-main() { +- { +-// start +- if (true) { +- print(0); +- } +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- { +-// start +- res(); +-// end +- } +-} +- +-void res() { +- if (true) { +- print(0); +- } +-} +-'''); +- } +- +- test_statements_changeIndentation_multilineString() async { +- await indexTestUnit(''' +-main() { +- { +-// start +- print(""" +-first line +-second line +- """); +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- { +-// start +- res(); +-// end +- } +-} +- +-void res() { +- print(""" +-first line +-second line +- """); +-} +-'''); +- } +- +- test_statements_definesVariable_notUsedOutside() async { +- await indexTestUnit(''' +-main() { +- int a = 1; +- int b = 1; +-// start +- int v = a + b; +- print(v); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int a = 1; +- int b = 1; +-// start +- res(a, b); +-// end +-} +- +-void res(int a, int b) { +- int v = a + b; +- print(v); +-} +-'''); +- } +- +- test_statements_definesVariable_oneUsedOutside_assignment() async { +- await indexTestUnit(''' +-myFunctionA() { +- int a = 1; +-// start +- a += 10; +-// end +- print(a); +-} +-myFunctionB() { +- int b = 2; +- b += 10; +- print(b); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-myFunctionA() { +- int a = 1; +-// start +- a = res(a); +-// end +- print(a); +-} +- +-int res(int a) { +- a += 10; +- return a; +-} +-myFunctionB() { +- int b = 2; +- b = res(b); +- print(b); +-} +-'''); +- } +- +- test_statements_definesVariable_oneUsedOutside_declaration() async { +- await indexTestUnit(''' +-myFunctionA() { +- int a = 1; +- int b = 2; +-// start +- int v1 = a + b; +-// end +- print(v1); +-} +-myFunctionB() { +- int a = 3; +- int b = 4; +- int v2 = a + b; +- print(v2); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-myFunctionA() { +- int a = 1; +- int b = 2; +-// start +- int v1 = res(a, b); +-// end +- print(v1); +-} +- +-int res(int a, int b) { +- int v1 = a + b; +- return v1; +-} +-myFunctionB() { +- int a = 3; +- int b = 4; +- int v2 = res(a, b); +- print(v2); +-} +-'''); +- } +- +- test_statements_definesVariable_twoUsedOutside() async { +- await indexTestUnit(''' +-main() { +-// start +- int varA = 1; +- int varB = 2; +-// end +- int v = varA + varB; +-} +-'''); +- _createRefactoringForStartEndComments(); +- // check conditions +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL); +- } +- +- test_statements_duplicate_absolutelySame() async { +- await indexTestUnit(''' +-myFunctionA() { +- print(0); +- print(1); +-} +-myFunctionB() { +-// start +- print(0); +- print(1); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-myFunctionA() { +- res(); +-} +-myFunctionB() { +-// start +- res(); +-// end +-} +- +-void res() { +- print(0); +- print(1); +-} +-'''); +- } +- +- test_statements_duplicate_declaresDifferentlyNamedVariable() async { +- await indexTestUnit(''' +-myFunctionA() { +- int varA = 1; +- print(varA); +-} +-myFunctionB() { +-// start +- int varB = 1; +- print(varB); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-myFunctionA() { +- res(); +-} +-myFunctionB() { +-// start +- res(); +-// end +-} +- +-void res() { +- int varB = 1; +- print(varB); +-} +-'''); +- } +- +- test_statements_dynamic() async { +- await indexTestUnit(''' +-dynaFunction(p) => 0; +-main() { +-// start +- var a = 1; +- var v = dynaFunction(a); +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-dynaFunction(p) => 0; +-main() { +-// start +- var v = res(); +-// end +- print(v); +-} +- +-res() { +- var a = 1; +- var v = dynaFunction(a); +- return v; +-} +-'''); +- } +- +- /** +- * We should always add ";" when invoke method with extracted statements. +- */ +- test_statements_endsWithBlock() async { +- await indexTestUnit(''' +-main() { +-// start +- if (true) { +- print(0); +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +-// start +- res(); +-// end +-} +- +-void res() { +- if (true) { +- print(0); +- } +-} +-'''); +- } +- +- test_statements_exit_throws() async { +- await indexTestUnit(''' +-main(int p) { +-// start +- if (p == 0) { +- return; +- } +- throw 'boo!'; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- await assertRefactoringConditionsOK(); +- } +- +- test_statements_hasAwait_dynamicReturnType() async { +- await indexTestUnit(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +-// start +- var v = await getValue(); +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +-// start +- var v = await res(); +-// end +- print(v); +-} +- +-Future res() async { +- var v = await getValue(); +- return v; +-} +-'''); +- } +- +- test_statements_hasAwait_expression() async { +- await indexTestUnit(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +-// start +- int v = await getValue(); +- v += 2; +-// end +- print(v); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +-// start +- int v = await res(); +-// end +- print(v); +-} +- +-Future res() async { +- int v = await getValue(); +- v += 2; +- return v; +-} +-'''); +- } +- +- test_statements_hasAwait_forEach() async { +- await indexTestUnit(''' +-import 'dart:async'; +-Stream getValueStream() => null; +-main() async { +-// start +- int sum = 0; +- await for (int v in getValueStream()) { +- sum += v; +- } +-// end +- print(sum); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'dart:async'; +-Stream getValueStream() => null; +-main() async { +-// start +- int sum = await res(); +-// end +- print(sum); +-} +- +-Future res() async { +- int sum = 0; +- await for (int v in getValueStream()) { +- sum += v; +- } +- return sum; +-} +-'''); +- } +- +- test_statements_hasAwait_voidReturnType() async { +- await indexTestUnit(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +-// start +- int v = await getValue(); +- print(v); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'dart:async'; +-Future getValue() async => 42; +-main() async { +-// start +- await res(); +-// end +-} +- +-Future res() async { +- int v = await getValue(); +- print(v); +-} +-'''); +- } +- +- test_statements_inSwitchMember() async { +- await indexTestUnit(''' +-class A { +- foo(int p) { +- switch (p) { +- case 0: +-// start +- print(0); +-// end +- break; +- default: +- break; +- } +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- foo(int p) { +- switch (p) { +- case 0: +-// start +- res(); +-// end +- break; +- default: +- break; +- } +- } +- +- void res() { +- print(0); +- } +-} +-'''); +- } +- +- test_statements_method() async { +- await indexTestUnit(''' +-class A { +- foo() { +-// start +- print(0); +-// end +- } +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class A { +- foo() { +-// start +- res(); +-// end +- } +- +- void res() { +- print(0); +- } +-} +-'''); +- } +- +- test_statements_noDuplicates() async { +- await indexTestUnit(''' +-main() { +- int a = 1; +- int b = 1; +-// start +- print(a); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +- int a = 1; +- int b = 1; +-// start +- res(a); +-// end +-} +- +-void res(int a) { +- print(a); +-} +-'''); +- } +- +- test_statements_parameters_ignoreInnerPropagatedType() async { +- await indexTestUnit(''' +-main(Object x) { +-// start +- if (x is int) { +- print('int'); +- } +- if (x is bool) { +- print('bool'); +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(Object x) { +-// start +- res(x); +-// end +-} +- +-void res(Object x) { +- if (x is int) { +- print('int'); +- } +- if (x is bool) { +- print('bool'); +- } +-} +-'''); +- } +- +- test_statements_parameters_importType() async { +- _addLibraryReturningAsync(); +- await indexTestUnit(''' +-import 'asyncLib.dart'; +-main() { +- var v = newFuture(); +-// start +- print(v); +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-import 'asyncLib.dart'; +-import 'dart:async'; +-main() { +- var v = newFuture(); +-// start +- res(v); +-// end +-} +- +-void res(Future v) { +- print(v); +-} +-'''); +- } +- +- test_statements_parameters_localFunction() async { +- _addLibraryReturningAsync(); +- await indexTestUnit(''' +-class C { +- int f(int a) { +- int callback(int x, int y) => x + a; +- int b = a + 1; +-// start +- int c = callback(b, 2); +-// end +- int d = c + 1; +- return d; +- } +-}'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-class C { +- int f(int a) { +- int callback(int x, int y) => x + a; +- int b = a + 1; +-// start +- int c = res(callback, b); +-// end +- int d = c + 1; +- return d; +- } +- +- int res(int callback(int x, int y), int b) { +- int c = callback(b, 2); +- return c; +- } +-}'''); +- } +- +- test_statements_parameters_noLocalVariableConflict() async { +- await indexTestUnit(''' +-int f(int x) { +- int y = x + 1; +-// start +- if (y % 2 == 0) { +- int y = x + 2; +- return y; +- } else { +- return y; +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- await assertRefactoringConditionsOK(); +- } +- +- test_statements_return_last() async { +- await indexTestUnit(''' +-main() { +-// start +- int v = 5; +- return v + 1; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +-// start +- return res(); +-// end +-} +- +-int res() { +- int v = 5; +- return v + 1; +-} +-'''); +- } +- +- test_statements_return_multiple_ifElse() async { +- await indexTestUnit(''' +-num main(bool b) { +-// start +- if (b) { +- return 1; +- } else { +- return 2.0; +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-num main(bool b) { +-// start +- return res(b); +-// end +-} +- +-num res(bool b) { +- if (b) { +- return 1; +- } else { +- return 2.0; +- } +-} +-'''); +- } +- +- test_statements_return_multiple_ifThen() async { +- await indexTestUnit(''' +-num main(bool b) { +-// start +- if (b) { +- return 1; +- } +- return 2.0; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-num main(bool b) { +-// start +- return res(b); +-// end +-} +- +-num res(bool b) { +- if (b) { +- return 1; +- } +- return 2.0; +-} +-'''); +- } +- +- test_statements_return_multiple_ignoreInFunction() async { +- await indexTestUnit(''' +-int main() { +-// start +- localFunction() { +- return 'abc'; +- } +- return 42; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-int main() { +-// start +- return res(); +-// end +-} +- +-int res() { +- localFunction() { +- return 'abc'; +- } +- return 42; +-} +-'''); +- } +- +- test_statements_return_multiple_interfaceFunction() async { +- await indexTestUnit(''' +-main(bool b) { +-// start +- if (b) { +- return 1; +- } +- return () {}; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(bool b) { +-// start +- return res(b); +-// end +-} +- +-Object res(bool b) { +- if (b) { +- return 1; +- } +- return () {}; +-} +-'''); +- } +- +- test_statements_return_multiple_sameElementDifferentTypeArgs() async { +- await indexTestUnit(''' +-main(bool b) { +-// start +- if (b) { +- print(true); +- return []; +- } else { +- print(false); +- return []; +- } +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main(bool b) { +-// start +- return res(b); +-// end +-} +- +-List res(bool b) { +- if (b) { +- print(true); +- return []; +- } else { +- print(false); +- return []; +- } +-} +-'''); +- } +- +- test_statements_return_single() async { +- await indexTestUnit(''' +-main() { +-// start +- return 42; +-// end +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +-// start +- return res(); +-// end +-} +- +-int res() { +- return 42; +-} +-'''); +- } +- +- /** +- * We have 3 identical statements, but select only 2. +- * This should not cause problems. +- */ +- test_statements_twoOfThree() async { +- await indexTestUnit(''' +-main() { +-// start +- print(0); +- print(0); +-// end +- print(0); +-} +-'''); +- _createRefactoringForStartEndComments(); +- // apply refactoring +- return _assertSuccessfulRefactoring(''' +-main() { +-// start +- res(); +-// end +- print(0); +-} +- +-void res() { +- print(0); +- print(0); +-} +-'''); +- } +- +- void _addLibraryReturningAsync() { +- addSource('/asyncLib.dart', r''' +-library asyncLib; +-import 'dart:async'; +-Future newFuture() => null; +-'''); +- } +- +- Future _assertConditionsError(String message) async { +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: message); +- } +- +- Future _assertConditionsFatal(String message) async { +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: message); +- } +- +- Future _assertFinalConditionsError(String message) async { +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: message); +- } +- +- Future _assertRefactoringChange(String expectedCode) async { +- SourceChange refactoringChange = await refactoring.createChange(); +- this.refactoringChange = refactoringChange; +- assertTestChangeResult(expectedCode); +- } +- +- /** +- * Checks that all conditions are OK and the result of applying the [Change] +- * to [testUnit] is [expectedCode]. +- */ +- Future _assertSuccessfulRefactoring(String expectedCode) async { +- await assertRefactoringConditionsOK(); +- refactoring.createGetter = false; +- return _assertRefactoringChange(expectedCode); +- } +- +- void _createRefactoring(int offset, int length) { +- refactoring = new ExtractMethodRefactoring( +- searchEngine, astProvider, testUnit, offset, length); +- refactoring.name = 'res'; +- } +- +- void _createRefactoringForStartEndComments() { +- int offset = findEnd('// start') + '\n'.length; +- int end = findOffset('// end'); +- _createRefactoring(offset, end - offset); +- } +- +- void _createRefactoringForStartEndString( +- String startSearch, String endSearch) { +- int offset = findOffset(startSearch); +- int end = findOffset(endSearch); +- _createRefactoring(offset, end - offset); +- } +- +- /** +- * Creates a new refactoring in [refactoring] for the selection range of the +- * given [search] pattern. +- */ +- void _createRefactoringForString(String search) { +- int offset = findOffset(search); +- int length = search.length; +- _createRefactoring(offset, length); +- } +- +- void _createRefactoringWithSuffix(String selectionSearch, String suffix) { +- int offset = findOffset(selectionSearch + suffix); +- int length = selectionSearch.length; +- _createRefactoring(offset, length); +- } +- +- /** +- * Returns a deep copy of [refactoring] parameters. +- * There was a bug masked by updating parameter instances shared between the +- * refactoring and the test. +- */ +- List _getParametersCopy() { +- return refactoring.parameters.map((p) { +- return new RefactoringMethodParameter(p.kind, p.type, p.name, id: p.id); +- }).toList(); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart +deleted file mode 100644 +index 3c224eea170..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart ++++ /dev/null +@@ -1,639 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/inline_local.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(InlineLocalTest); +- }); +-} +- +-@reflectiveTest +-class InlineLocalTest extends RefactoringTest { +- InlineLocalRefactoringImpl refactoring; +- +- test_access() async { +- await indexTestUnit(''' +-main() { +- int test = 1 + 2; +- print(test); +- print(test); +-} +-'''); +- _createRefactoring('test ='); +- expect(refactoring.refactoringName, 'Inline Local Variable'); +- // check initial conditions and access +- await refactoring.checkInitialConditions(); +- expect(refactoring.variableName, 'test'); +- expect(refactoring.referenceCount, 2); +- } +- +- test_bad_selectionMethod() async { +- await indexTestUnit(r''' +-main() { +-} +-'''); +- _createRefactoring('main() {'); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- _assert_fatalError_selection(status); +- } +- +- test_bad_selectionParameter() async { +- await indexTestUnit(r''' +-main(int test) { +-} +-'''); +- _createRefactoring('test) {'); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- _assert_fatalError_selection(status); +- } +- +- test_bad_selectionVariable_hasAssignments_1() async { +- await indexTestUnit(r''' +-main() { +- int test = 0; +- test = 1; +-} +-'''); +- _createRefactoring('test = 0'); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedContextSearch: 'test = 1'); +- } +- +- test_bad_selectionVariable_hasAssignments_2() async { +- await indexTestUnit(r''' +-main() { +- int test = 0; +- test += 1; +-} +-'''); +- _createRefactoring('test = 0'); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedContextSearch: 'test += 1'); +- } +- +- test_bad_selectionVariable_notInBlock() async { +- await indexTestUnit(r''' +-main() { +- if (true) +- int test = 0; +-} +-'''); +- _createRefactoring('test = 0'); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL); +- } +- +- test_bad_selectionVariable_notInitialized() async { +- await indexTestUnit(r''' +-main() { +- int test; +-} +-'''); +- _createRefactoring('test;'); +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL); +- } +- +- test_OK_cascade_intoCascade() async { +- await indexTestUnit(r''' +-class A { +- foo() {} +- bar() {} +-} +-main() { +- A test = new A()..foo(); +- test..bar(); +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-class A { +- foo() {} +- bar() {} +-} +-main() { +- new A()..foo()..bar(); +-} +-'''); +- } +- +- test_OK_cascade_intoNotCascade() async { +- await indexTestUnit(r''' +-class A { +- foo() {} +- bar() {} +-} +-main() { +- A test = new A()..foo(); +- test.bar(); +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-class A { +- foo() {} +- bar() {} +-} +-main() { +- (new A()..foo()).bar(); +-} +-'''); +- } +- +- test_OK_inSwitchCase() async { +- await indexTestUnit(''' +-main(int p) { +- switch (p) { +- case 0: +- int test = 42; +- print(test); +- break; +- } +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main(int p) { +- switch (p) { +- case 0: +- print(42); +- break; +- } +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_binaryExpression() async { +- await indexTestUnit(r''' +-main() { +- int test = 1 + 2; +- print('test = $test'); +- print('test = ${test}'); +- print('test = ${process(test)}'); +-} +-process(x) {} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- print('test = ${1 + 2}'); +- print('test = ${1 + 2}'); +- print('test = ${process(1 + 2)}'); +-} +-process(x) {} +-'''); +- } +- +- test_OK_intoStringInterpolation_simpleIdentifier() async { +- await indexTestUnit(r''' +-main() { +- int foo = 1 + 2; +- int test = foo; +- print('test = $test'); +- print('test = ${test}'); +- print('test = ${process(test)}'); +-} +-process(x) {} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- int foo = 1 + 2; +- print('test = $foo'); +- print('test = ${foo}'); +- print('test = ${process(foo)}'); +-} +-process(x) {} +-'''); +- } +- +- test_OK_intoStringInterpolation_string_differentQuotes() async { +- await indexTestUnit(r''' +-main() { +- String a = "aaa"; +- String b = '$a bbb'; +-} +-'''); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- String b = '${"aaa"} bbb'; +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_string_doubleQuotes() async { +- await indexTestUnit(r''' +-main() { +- String a = "aaa"; +- String b = "$a bbb"; +-} +-'''); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- String b = "aaa bbb"; +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_string_multiLineIntoMulti_leadingSpaces() async { +- await indexTestUnit(r""" +-main() { +- String a = '''\ \ +-a +-a'''; +- String b = ''' +-$a +-bbb'''; +-} +-"""); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r""" +-main() { +- String b = ''' +-a +-a +-bbb'''; +-} +-"""); +- } +- +- test_OK_intoStringInterpolation_string_multiLineIntoMulti_unixEOL() async { +- await indexTestUnit(r""" +-main() { +- String a = ''' +-a +-a +-a'''; +- String b = ''' +-$a +-bbb'''; +-} +-"""); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r""" +-main() { +- String b = ''' +-a +-a +-a +-bbb'''; +-} +-"""); +- } +- +- test_OK_intoStringInterpolation_string_multiLineIntoMulti_windowsEOL() async { +- await indexTestUnit(r""" +-main() { +- String a = ''' +-a +-a +-a'''; +- String b = ''' +-$a +-bbb'''; +-} +-""" +- .replaceAll('\n', '\r\n')); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r""" +-main() { +- String b = ''' +-a +-a +-a +-bbb'''; +-} +-""" +- .replaceAll('\n', '\r\n')); +- } +- +- test_OK_intoStringInterpolation_string_multiLineIntoSingle() async { +- await indexTestUnit(r''' +-main() { +- String a = """aaa"""; +- String b = "$a bbb"; +-} +-'''); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- String b = "${"""aaa"""} bbb"; +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_string_raw() async { +- await indexTestUnit(r''' +-main() { +- String a = r'an $ignored interpolation'; +- String b = '$a bbb'; +-} +-'''); +- _createRefactoring('a ='); +- // we don't unwrap raw strings +- return assertSuccessfulRefactoring(r''' +-main() { +- String b = '${r'an $ignored interpolation'} bbb'; +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_string_singleLineIntoMulti_doubleQuotes() async { +- await indexTestUnit(r''' +-main() { +- String a = "aaa"; +- String b = """$a bbb"""; +-} +-'''); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- String b = """aaa bbb"""; +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_string_singleLineIntoMulti_singleQuotes() async { +- await indexTestUnit(r""" +-main() { +- String a = 'aaa'; +- String b = '''$a bbb'''; +-} +-"""); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r""" +-main() { +- String b = '''aaa bbb'''; +-} +-"""); +- } +- +- test_OK_intoStringInterpolation_string_singleQuotes() async { +- await indexTestUnit(r''' +-main() { +- String a = 'aaa'; +- String b = '$a bbb'; +-} +-'''); +- _createRefactoring('a ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- String b = 'aaa bbb'; +-} +-'''); +- } +- +- test_OK_intoStringInterpolation_stringInterpolation() async { +- await indexTestUnit(r''' +-main() { +- String a = 'aaa'; +- String b = '$a bbb'; +- String c = '$b ccc'; +-} +-'''); +- _createRefactoring('b ='); +- // validate change +- return assertSuccessfulRefactoring(r''' +-main() { +- String a = 'aaa'; +- String c = '$a bbb ccc'; +-} +-'''); +- } +- +- /** +- *

    +- * https://code.google.com/p/dart/issues/detail?id=18587 +- */ +- test_OK_keepNextCommentedLine() async { +- await indexTestUnit(''' +-main() { +- int test = 1 + 2; +- // foo +- print(test); +- // bar +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- // foo +- print(1 + 2); +- // bar +-} +-'''); +- } +- +- test_OK_noUsages_1() async { +- await indexTestUnit(''' +-main() { +- int test = 1 + 2; +- print(0); +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- print(0); +-} +-'''); +- } +- +- test_OK_noUsages_2() async { +- await indexTestUnit(''' +-main() { +- int test = 1 + 2; +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +-} +-'''); +- } +- +- test_OK_oneUsage() async { +- await indexTestUnit(''' +-main() { +- int test = 1 + 2; +- print(test); +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- print(1 + 2); +-} +-'''); +- } +- +- test_OK_parenthesis_decrement_intoNegate() async { +- await indexTestUnit(''' +-main() { +- var a = 1; +- var test = --a; +- var b = -test; +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- var a = 1; +- var b = -(--a); +-} +-'''); +- } +- +- test_OK_parenthesis_instanceCreation_intoList() async { +- await indexTestUnit(''' +-class A {} +-main() { +- var test = new A(); +- var list = [test]; +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-class A {} +-main() { +- var list = [new A()]; +-} +-'''); +- } +- +- test_OK_parenthesis_intoIndexExpression_index() async { +- await indexTestUnit(''' +-main() { +- var items = []; +- var test = 1 + 2; +- items[test] * 5; +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- var items = []; +- items[1 + 2] * 5; +-} +-'''); +- } +- +- test_OK_parenthesis_intoParenthesizedExpression() async { +- await indexTestUnit(''' +-f(m, x, y) { +- int test = x as int; +- m[test] = y; +- return m[test]; +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-f(m, x, y) { +- m[x as int] = y; +- return m[x as int]; +-} +-'''); +- } +- +- test_OK_parenthesis_negate_intoNegate() async { +- await indexTestUnit(''' +-main() { +- var a = 1; +- var test = -a; +- var b = -test; +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- var a = 1; +- var b = -(-a); +-} +-'''); +- } +- +- test_OK_parenthesis_plus_intoMultiply() async { +- await indexTestUnit(''' +-main() { +- var test = 1 + 2; +- print(test * 3); +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- print((1 + 2) * 3); +-} +-'''); +- } +- +- test_OK_twoUsages() async { +- await indexTestUnit(''' +-main() { +- int test = 1 + 2; +- print(test); +- print(test); +-} +-'''); +- _createRefactoring('test ='); +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- print(1 + 2); +- print(1 + 2); +-} +-'''); +- } +- +- void _assert_fatalError_selection(RefactoringStatus status) { +- expect(refactoring.variableName, isNull); +- expect(refactoring.referenceCount, 0); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: 'Local variable declaration or reference must be ' +- 'selected to activate this refactoring.'); +- } +- +- void _createRefactoring(String search) { +- int offset = findOffset(search); +- refactoring = +- new InlineLocalRefactoring(searchEngine, astProvider, testUnit, offset); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart +deleted file mode 100644 +index 64c50e08954..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart ++++ /dev/null +@@ -1,1761 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/inline_method.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(InlineMethodTest); +- }); +-} +- +-@reflectiveTest +-class InlineMethodTest extends RefactoringTest { +- InlineMethodRefactoringImpl refactoring; +- bool deleteSource; +- bool inlineAll; +- +- test_access_FunctionElement() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res = test(1, 2); +-} +-'''); +- _createRefactoring('test(1, 2)'); +- // validate state +- await refactoring.checkInitialConditions(); +- expect(refactoring.refactoringName, 'Inline Function'); +- expect(refactoring.className, isNull); +- expect(refactoring.methodName, 'test'); +- expect(refactoring.isDeclaration, isFalse); +- } +- +- test_access_MethodElement() async { +- await indexTestUnit(r''' +-class A { +- test(a, b) { +- return a + b; +- } +- main() { +- var res = test(1, 2); +- } +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate state +- await refactoring.checkInitialConditions(); +- expect(refactoring.refactoringName, 'Inline Method'); +- expect(refactoring.className, 'A'); +- expect(refactoring.methodName, 'test'); +- expect(refactoring.isDeclaration, isTrue); +- } +- +- test_bad_async_intoSyncStar() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future get test async => 42; +- Iterable> foo() sync* { +- yield test; +- } +-} +-'''); +- _createRefactoring('test async'); +- // error +- return _assertConditionsFatal('Cannot inline async into sync*.'); +- } +- +- test_bad_async_targetIsSync_doesNotReturnFuture() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future get test async => 42; +- double foo() { +- test; +- return 1.2; +- } +-} +-'''); +- _createRefactoring('test async'); +- // error +- return _assertConditionsFatal( +- 'Cannot inline async into a function that does not return a Future.'); +- } +- +- test_bad_asyncStar() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Stream test() async* { +- yield 1; +- yield 2; +- } +- foo() { +- test(); +- } +-} +-'''); +- _createRefactoring('test() async*'); +- // error +- return _assertConditionsFatal('Cannot inline a generator.'); +- } +- +- test_bad_cascadeInvocation() async { +- await indexTestUnit(r''' +-class A { +- foo() {} +- bar() {} +- test() {} +-} +-main() { +- A a = new A(); +- a..foo()..test()..bar(); +-} +-'''); +- _createRefactoring('test() {'); +- // error +- RefactoringStatus status = await refactoring.checkAllConditions(); +- var location = new SourceRange(findOffset('..test()'), '..test()'.length); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: 'Cannot inline cascade invocation.', +- expectedContextRange: location); +- } +- +- test_bad_constructor() async { +- await indexTestUnit(r''' +-class A { +- A.named() {} +-} +-'''); +- _createRefactoring('named() {}'); +- // error +- return _assertInvalidSelection(); +- } +- +- test_bad_deleteSource_inlineOne() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res1 = test(1, 2); +- var res2 = test(10, 20); +-} +-'''); +- _createRefactoring('test(1, 2)'); +- // initial conditions +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatusOK(status); +- refactoring.deleteSource = true; +- refactoring.inlineAll = false; +- // final conditions +- status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- 'All references must be inlined to remove the source.'); +- } +- +- test_bad_notExecutableElement() async { +- await indexTestUnit(r''' +-main() { +-} +-'''); +- _createRefactoring(') {'); +- // error +- return _assertInvalidSelection(); +- } +- +- test_bad_notSimpleIdentifier() async { +- await indexTestUnit(r''' +-main() { +- var test = 42; +- var res = test; +-} +-'''); +- _createRefactoring('test;'); +- // error +- return _assertInvalidSelection(); +- } +- +- test_bad_operator() async { +- await indexTestUnit(r''' +-class A { +- operator -(other) => this; +-} +-'''); +- _createRefactoring('-(other)'); +- // error +- return _assertConditionsFatal('Cannot inline operator.'); +- } +- +- test_bad_propertyAccessor_synthetic() async { +- await indexTestUnit(r''' +-class A { +- int fff; +-} +- +-main(A a) { +- print(a.fff); +-} +-'''); +- _createRefactoring('fff);'); +- // error +- return _assertInvalidSelection(); +- } +- +- test_bad_reference_toClassMethod() async { +- await indexTestUnit(r''' +-class A { +- test(a, b) { +- print(a); +- print(b); +- } +-} +-main() { +- print(new A().test); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // error +- return _assertConditionsFatal('Cannot inline class method reference.'); +- } +- +- test_bad_severalReturns() async { +- await indexTestUnit(r''' +-test() { +- if (true) { +- return 1; +- } +- return 2; +-} +-main() { +- var res = test(); +-} +-'''); +- _createRefactoring('test() {'); +- // error +- return _assertConditionsError('Ambiguous return value.'); +- } +- +- test_cascadeInCascade() async { +- await indexTestUnit(r''' +-class Inner { +- String a; +- String b; +-} +- +-class Outer { +- Inner inner; +-} +- +-void main() { +- Inner createInner() => new Inner() +- ..a = 'a' +- ..b = 'b'; +- +- final value = new Outer() +- ..inner = createInner(); +-} +-'''); +- _createRefactoring('createInner();'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class Inner { +- String a; +- String b; +-} +- +-class Outer { +- Inner inner; +-} +- +-void main() { +- Inner createInner() => new Inner() +- ..a = 'a' +- ..b = 'b'; +- +- final value = new Outer() +- ..inner = (new Inner() +- ..a = 'a' +- ..b = 'b'); +-} +-'''); +- } +- +- test_fieldAccessor_getter() async { +- await indexTestUnit(r''' +-class A { +- var f; +- get foo { +- return f * 2; +- } +-} +-main() { +- A a = new A(); +- print(a.foo); +-} +-'''); +- _createRefactoring('foo {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var f; +-} +-main() { +- A a = new A(); +- print(a.f * 2); +-} +-'''); +- } +- +- test_fieldAccessor_getter_PropertyAccess() async { +- await indexTestUnit(r''' +-class A { +- var f; +- get foo { +- return f * 2; +- } +-} +-class B { +- A a = new A(); +-} +-main() { +- B b = new B(); +- print(b.a.foo); +-} +-'''); +- _createRefactoring('foo {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var f; +-} +-class B { +- A a = new A(); +-} +-main() { +- B b = new B(); +- print(b.a.f * 2); +-} +-'''); +- } +- +- test_fieldAccessor_setter() async { +- await indexTestUnit(r''' +-class A { +- var f; +- set foo(x) { +- f = x; +- } +-} +-main() { +- A a = new A(); +- a.foo = 0; +-} +-'''); +- _createRefactoring('foo(x) {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var f; +-} +-main() { +- A a = new A(); +- a.f = 0; +-} +-'''); +- } +- +- test_fieldAccessor_setter_PropertyAccess() async { +- await indexTestUnit(r''' +-class A { +- var f; +- set foo(x) { +- f = x; +- } +-} +-class B { +- A a = new A(); +-} +-main() { +- B b = new B(); +- b.a.foo = 0; +-} +-'''); +- _createRefactoring('foo(x) {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var f; +-} +-class B { +- A a = new A(); +-} +-main() { +- B b = new B(); +- b.a.f = 0; +-} +-'''); +- } +- +- test_function_expressionFunctionBody() async { +- await indexTestUnit(r''' +-test(a, b) => a + b; +-main() { +- print(test(1, 2)); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(1 + 2); +-} +-'''); +- } +- +- test_function_hasReturn_assign() async { +- await indexTestUnit(r''' +-test(a, b) { +- print(a); +- print(b); +- return a + b; +-} +-main() { +- var v; +- v = test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var v; +- print(1); +- print(2); +- v = 1 + 2; +-} +-'''); +- } +- +- test_function_hasReturn_hasReturnType() async { +- await indexTestUnit(r''' +-int test(a, b) { +- return a + b; +-} +-main() { +- var v = test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var v = 1 + 2; +-} +-'''); +- } +- +- test_function_hasReturn_noVars_oneUsage() async { +- await indexTestUnit(r''' +-test(a, b) { +- print(a); +- print(b); +- return a + b; +-} +-main() { +- var v = test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(1); +- print(2); +- var v = 1 + 2; +-} +-'''); +- } +- +- test_function_multilineString() async { +- await indexTestUnit(r""" +-main() { +- { +- test(); +- } +-} +-test() { +- print(''' +-first line +-second line +- '''); +-} +-"""); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r""" +-main() { +- { +- print(''' +-first line +-second line +- '''); +- } +-} +-"""); +- } +- +- test_function_noReturn_hasVars_hasConflict_fieldSuperClass() async { +- await indexTestUnit(r''' +-class A { +- var c; +-} +-class B extends A { +- foo() { +- test(1, 2); +- } +-} +-test(a, b) { +- var c = a + b; +- print(c); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var c; +-} +-class B extends A { +- foo() { +- var c2 = 1 + 2; +- print(c2); +- } +-} +-'''); +- } +- +- test_function_noReturn_hasVars_hasConflict_fieldThisClass() async { +- await indexTestUnit(r''' +-class A { +- var c; +- foo() { +- test(1, 2); +- } +-} +-test(a, b) { +- var c = a + b; +- print(c); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var c; +- foo() { +- var c2 = 1 + 2; +- print(c2); +- } +-} +-'''); +- } +- +- test_function_noReturn_hasVars_hasConflict_localAfter() async { +- await indexTestUnit(r''' +-test(a, b) { +- var c = a + b; +- print(c); +-} +-main() { +- test(1, 2); +- var c = 0; +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var c2 = 1 + 2; +- print(c2); +- var c = 0; +-} +-'''); +- } +- +- test_function_noReturn_hasVars_hasConflict_localBefore() async { +- await indexTestUnit(r''' +-test(a, b) { +- var c = a + b; +- print(c); +-} +-main() { +- var c = 0; +- test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var c = 0; +- var c2 = 1 + 2; +- print(c2); +-} +-'''); +- } +- +- test_function_noReturn_hasVars_noConflict() async { +- await indexTestUnit(r''' +-test(a, b) { +- var c = a + b; +- print(c); +-} +-main() { +- test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var c = 1 + 2; +- print(c); +-} +-'''); +- } +- +- test_function_noReturn_noVars_oneUsage() async { +- await indexTestUnit(r''' +-test(a, b) { +- print(a); +- print(b); +-} +-main() { +- test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(1); +- print(2); +-} +-'''); +- } +- +- test_function_noReturn_noVars_useIndentation() async { +- await indexTestUnit(r''' +-test(a, b) { +- print(a); +- print(b); +-} +-main() { +- { +- test(1, 2); +- } +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- { +- print(1); +- print(2); +- } +-} +-'''); +- } +- +- test_function_noReturn_voidReturnType() async { +- await indexTestUnit(r''' +-void test(a, b) { +- print(a + b); +-} +-main() { +- test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(1 + 2); +-} +-'''); +- } +- +- test_function_notStatement_oneStatement_assign() async { +- await indexTestUnit(r''' +-test(int p) { +- print(p * 2); +-} +-main() { +- var v; +- v = test(0); +-} +-'''); +- _createRefactoring('test(int p)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var v; +- v = (int p) { +- print(p * 2); +- }(0); +-} +-'''); +- } +- +- test_function_notStatement_oneStatement_variableDeclaration() async { +- await indexTestUnit(r''' +-test(int p) { +- print(p * 2); +-} +-main() { +- var v = test(0); +-} +-'''); +- _createRefactoring('test(int p)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var v = (int p) { +- print(p * 2); +- }(0); +-} +-'''); +- } +- +- test_function_notStatement_severalStatements() async { +- await indexTestUnit(r''' +-test(int p) { +- print(p); +- print(p * 2); +-} +-main() { +- var v = test(0); +-} +-'''); +- _createRefactoring('test(int p)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var v = (int p) { +- print(p); +- print(p * 2); +- }(0); +-} +-'''); +- } +- +- test_function_notStatement_zeroStatements() async { +- await indexTestUnit(r''' +-test(int p) { +-} +-main() { +- var v = test(0); +-} +-'''); +- _createRefactoring('test(int p)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var v = (int p) { +- }(0); +-} +-'''); +- } +- +- test_function_singleStatement() async { +- await indexTestUnit(r''' +-var topLevelField = 0; +-test() { +- print(topLevelField); +-} +-main() { +- test(); +-} +-'''); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-var topLevelField = 0; +-main() { +- print(topLevelField); +-} +-'''); +- } +- +- test_getter_async_targetIsAsync() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future get test async => 42; +- Future foo() async { +- return test; +- } +-} +-'''); +- _createRefactoring('test async'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-import 'dart:async'; +-class A { +- Future foo() async { +- return 42; +- } +-} +-'''); +- } +- +- test_getter_async_targetIsAsyncStar() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future get test async => 42; +- Stream foo() async* { +- yield await test; +- } +-} +-'''); +- _createRefactoring('test async'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-import 'dart:async'; +-class A { +- Stream foo() async* { +- yield await 42; +- } +-} +-'''); +- } +- +- test_getter_async_targetIsSync() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future get test async => 42; +- Future foo() { +- return test; +- } +-} +-'''); +- _createRefactoring('test async'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-import 'dart:async'; +-class A { +- Future foo() async { +- return 42; +- } +-} +-'''); +- } +- +- test_getter_async_targetIsSync2() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future get test async => 42; +- Future foo1() { +- return test; +- } +- Future foo2() { +- return test; +- } +-} +-'''); +- _createRefactoring('test async'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-import 'dart:async'; +-class A { +- Future foo1() async { +- return 42; +- } +- Future foo2() async { +- return 42; +- } +-} +-'''); +- } +- +- test_getter_classMember_instance() async { +- await indexTestUnit(r''' +-class A { +- int f; +- int get result => f + 1; +-} +-main(A a) { +- print(a.result); +-} +-'''); +- _createRefactoring('result =>'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- int f; +-} +-main(A a) { +- print(a.f + 1); +-} +-'''); +- } +- +- test_getter_classMember_static() async { +- await indexTestUnit(r''' +-class A { +- static int get result => 1 + 2; +-} +-main() { +- print(A.result); +-} +-'''); +- _createRefactoring('result =>'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +-} +-main() { +- print(1 + 2); +-} +-'''); +- } +- +- test_getter_topLevel() async { +- await indexTestUnit(r''' +-String get message => 'Hello, World!'; +-main() { +- print(message); +-} +-'''); +- _createRefactoring('message =>'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print('Hello, World!'); +-} +-'''); +- } +- +- test_initialMode_all() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res = test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate state +- await refactoring.checkInitialConditions(); +- expect(refactoring.deleteSource, true); +- expect(refactoring.inlineAll, true); +- } +- +- test_initialMode_single() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res1 = test(1, 2); +- var res2 = test(10, 20); +-} +-'''); +- _createRefactoring('test(1, 2)'); +- deleteSource = false; +- // validate state +- await refactoring.checkInitialConditions(); +- expect(refactoring.deleteSource, false); +- expect(refactoring.inlineAll, false); +- } +- +- test_method_async() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future test() async => 42; +- Future foo() { +- return test(); +- } +-} +-'''); +- _createRefactoring('test() async'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-import 'dart:async'; +-class A { +- Future foo() async { +- return 42; +- } +-} +-'''); +- } +- +- test_method_async2() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-class A { +- Future foo() async => 42; +- Future test() async => await foo(); +- Future bar() { +- return new Future.value([test(), test()]); +- } +-} +-'''); +- _createRefactoring('test() async'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-import 'dart:async'; +-class A { +- Future foo() async => 42; +- Future bar() async { +- return new Future.value([(await foo()), (await foo())]); +- } +-} +-'''); +- } +- +- test_method_emptyBody() async { +- await indexTestUnit(r''' +-abstract class A { +- test(); +-} +-main(A a) { +- print(a.test()); +-} +-'''); +- _createRefactoring('test();'); +- // error +- return _assertConditionsFatal('Cannot inline method without body.'); +- } +- +- test_method_fieldInstance() async { +- await indexTestUnit(r''' +-class A { +- var fA; +-} +-class B extends A { +- var fB; +- test() { +- print(fA); +- print(fB); +- print(this.fA); +- print(this.fB); +- } +-} +-main() { +- B b = new B(); +- b.test(); +-} +-'''); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- var fA; +-} +-class B extends A { +- var fB; +-} +-main() { +- B b = new B(); +- print(b.fA); +- print(b.fB); +- print(b.fA); +- print(b.fB); +-} +-'''); +- } +- +- test_method_fieldStatic() async { +- await indexTestUnit(r''' +-class A { +- static var FA = 1; +-} +-class B extends A { +- static var FB = 2; +- test() { +- print(FB); +- print(A.FA); +- print(B.FB); +- } +-} +-main() { +- B b = new B(); +- b.test(); +-} +-'''); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- static var FA = 1; +-} +-class B extends A { +- static var FB = 2; +-} +-main() { +- B b = new B(); +- print(B.FB); +- print(A.FA); +- print(B.FB); +-} +-'''); +- } +- +- test_method_fieldStatic_sameClass() async { +- await indexTestUnit(r''' +-class A { +- static var F = 1; +- foo() { +- test(); +- } +- test() { +- print(A.F); +- } +-} +-'''); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- static var F = 1; +- foo() { +- print(A.F); +- } +-} +-'''); +- } +- +- test_method_methodInstance() async { +- await indexTestUnit(r''' +-class A { +- ma() {} +-} +-class B extends A { +- test() { +- ma(); +- mb(); +- } +- mb() {} +-} +-main(B b) { +- b.test(); +-} +-'''); +- _createRefactoring('test();'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- ma() {} +-} +-class B extends A { +- test() { +- ma(); +- mb(); +- } +- mb() {} +-} +-main(B b) { +- b.ma(); +- b.mb(); +-} +-'''); +- } +- +- test_method_methodStatic() async { +- await indexTestUnit(r''' +-class A { +- static ma() {} +-} +-class B extends A { +- static mb() {} +- test() { +- mb(); +- A.ma(); +- B.mb(); +- } +-} +-main(B b) { +- b.test(); +-} +-'''); +- _createRefactoring('test();'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- static ma() {} +-} +-class B extends A { +- static mb() {} +- test() { +- mb(); +- A.ma(); +- B.mb(); +- } +-} +-main(B b) { +- B.mb(); +- A.ma(); +- B.mb(); +-} +-'''); +- } +- +- test_method_singleStatement() async { +- await indexTestUnit(r''' +-class A { +- test() { +- print(0); +- } +- foo() { +- test(); +- } +-} +-'''); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- foo() { +- print(0); +- } +-} +-'''); +- } +- +- test_method_this() async { +- await indexTestUnit(r''' +-class A { +- accept(B b) {} +-} +-class B { +- test(A a) { +- print(this); +- a.accept(this); +- } +-} +-main() { +- B b = new B(); +- A a = new A(); +- b.test(a); +-} +-'''); +- _createRefactoring('test(A a) {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- accept(B b) {} +-} +-class B { +-} +-main() { +- B b = new B(); +- A a = new A(); +- print(b); +- a.accept(b); +-} +-'''); +- } +- +- test_method_unqualifiedInvocation() async { +- await indexTestUnit(r''' +-class A { +- test(a, b) { +- print(a); +- print(b); +- return a + b; +- } +- foo() { +- var v = test(1, 2); +- } +-} +-'''); +- _createRefactoring('test(a, b) {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- foo() { +- print(1); +- print(2); +- var v = 1 + 2; +- } +-} +-'''); +- } +- +- test_namedArgument_inBody() async { +- await indexTestUnit(r''' +-fa(pa) => fb(pb: true); +-fb({pb: false}) {} +-main() { +- fa(null); +-} +-'''); +- _createRefactoring('fa(null)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-fa(pa) => fb(pb: true); +-fb({pb: false}) {} +-main() { +- fb(pb: true); +-} +-'''); +- } +- +- test_namedArguments() async { +- await indexTestUnit(r''' +-test({a: 0, b: 2}) { +- print(a + b); +-} +-main() { +- test(a: 10, b: 20); +- test(b: 20, a: 10); +-} +-'''); +- _createRefactoring('test({'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(10 + 20); +- print(10 + 20); +-} +-'''); +- } +- +- test_noArgument_named_hasDefault() async { +- verifyNoTestUnitErrors = false; +- await indexTestUnit(r''' +-test({a: 42}) { +- print(a); +-} +-main() { +- test(); +-} +-'''); +- _createRefactoring('test('); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(42); +-} +-'''); +- } +- +- test_noArgument_positional_hasDefault() async { +- verifyNoTestUnitErrors = false; +- await indexTestUnit(r''' +-test([a = 42]) { +- print(a); +-} +-main() { +- test(); +-} +-'''); +- _createRefactoring('test('); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(42); +-} +-'''); +- } +- +- test_noArgument_positional_noDefault() async { +- verifyNoTestUnitErrors = false; +- await indexTestUnit(r''' +-test([a]) { +- print(a); +-} +-main() { +- test(); +-} +-'''); +- _createRefactoring('test('); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(null); +-} +-'''); +- } +- +- test_noArgument_required() async { +- verifyNoTestUnitErrors = false; +- await indexTestUnit(r''' +-test(a) { +- print(a); +-} +-main() { +- test(); +-} +-'''); +- _createRefactoring('test();'); +- // error +- RefactoringStatus status = await refactoring.checkAllConditions(); +- var location = new SourceRange(findOffset('test();'), 'test()'.length); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: 'No argument for the parameter "a".', +- expectedContextRange: location); +- } +- +- test_reference_expressionBody() async { +- await indexTestUnit(r''' +-String message() => 'Hello, World!'; +-main() { +- print(message); +-} +-'''); +- _createRefactoring('message()'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(() => 'Hello, World!'); +-} +-'''); +- } +- +- test_reference_noStatement() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a || b; +-} +-foo(p1, p2, p3) => p1 && test(p2, p3); +-bar() => { +- 'name' : baz(test) +-}; +-baz(x) {} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-foo(p1, p2, p3) => p1 && (p2 || p3); +-bar() => { +- 'name' : baz((a, b) { +- return a || b; +- }) +-}; +-baz(x) {} +-'''); +- } +- +- test_reference_toLocal() async { +- await indexTestUnit(r''' +-main() { +- test(a, b) { +- print(a); +- print(b); +- } +- print(test); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print((a, b) { +- print(a); +- print(b); +- }); +-} +-'''); +- } +- +- test_reference_toTopLevel() async { +- await indexTestUnit(r''' +-test(a, b) { +- print(a); +- print(b); +-} +-main() { +- print(test); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print((a, b) { +- print(a); +- print(b); +- }); +-} +-'''); +- } +- +- test_removeEmptyLinesBefore_method() async { +- await indexTestUnit(r''' +-class A { +- before() { +- } +- +- +- test() { +- print(0); +- } +- +- foo() { +- test(); +- } +-} +-'''); +- _createRefactoring('test() {'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- before() { +- } +- +- foo() { +- print(0); +- } +-} +-'''); +- } +- +- test_setter_classMember_instance() async { +- await indexTestUnit(r''' +-class A { +- int f; +- void set result(x) { +- f = x + 1; +- } +-} +-main(A a) { +- a.result = 5; +-} +-'''); +- _createRefactoring('result(x)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-class A { +- int f; +-} +-main(A a) { +- a.f = 5 + 1; +-} +-'''); +- } +- +- test_setter_topLevel() async { +- await indexTestUnit(r''' +-void set result(x) { +- print(x + 1); +-} +-main() { +- result = 5; +-} +-'''); +- _createRefactoring('result(x)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- print(5 + 1); +-} +-'''); +- } +- +- test_singleExpression_oneUsage() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res = test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var res = 1 + 2; +-} +-'''); +- } +- +- test_singleExpression_oneUsage_keepMethod() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res = test(1, 2); +-} +-'''); +- _createRefactoring('test(a, b)'); +- deleteSource = false; +- // validate change +- return _assertSuccessfulRefactoring(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res = 1 + 2; +-} +-'''); +- } +- +- test_singleExpression_twoUsages() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res1 = test(1, 2); +- var res2 = test(10, 20); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var res1 = 1 + 2; +- var res2 = 10 + 20; +-} +-'''); +- } +- +- test_singleExpression_twoUsages_inlineOne() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res1 = test(1, 2); +- var res2 = test(10, 20); +-} +-'''); +- _createRefactoring('test(1, 2)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-test(a, b) { +- return a + b; +-} +-main() { +- var res1 = 1 + 2; +- var res2 = test(10, 20); +-} +-'''); +- } +- +- test_singleExpression_wrapIntoParenthesized_alreadyInMethod() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a * (b); +-} +-main() { +- var res = test(1, 2 + 3); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var res = 1 * (2 + 3); +-} +-'''); +- } +- +- test_singleExpression_wrapIntoParenthesized_asNeeded() async { +- await indexTestUnit(r''' +-test(a, b) { +- return a * b; +-} +-main() { +- var res1 = test(1, 2 + 3); +- var res2 = test(1, (2 + 3)); +-} +-'''); +- _createRefactoring('test(a, b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main() { +- var res1 = 1 * (2 + 3); +- var res2 = 1 * (2 + 3); +-} +-'''); +- } +- +- test_singleExpression_wrapIntoParenthesized_bool() async { +- await indexTestUnit(r''' +-test(bool a, bool b) { +- return a || b; +-} +-main(bool p, bool p2, bool p3) { +- var res1 = p && test(p2, p3); +- var res2 = p || test(p2, p3); +-} +-'''); +- _createRefactoring('test(bool a, bool b)'); +- // validate change +- return _assertSuccessfulRefactoring(r''' +-main(bool p, bool p2, bool p3) { +- var res1 = p && (p2 || p3); +- var res2 = p || p2 || p3; +-} +-'''); +- } +- +- Future _assertConditionsError(String message) async { +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: message); +- } +- +- Future _assertConditionsFatal(String message) async { +- RefactoringStatus status = await refactoring.checkAllConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: message); +- } +- +- Future _assertInvalidSelection() { +- return _assertConditionsFatal( +- 'Method declaration or reference must be selected to activate this refactoring.'); +- } +- +- Future _assertSuccessfulRefactoring(String expectedCode) async { +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatusOK(status); +- // configure +- if (deleteSource != null) { +- refactoring.deleteSource = deleteSource; +- } +- if (inlineAll != null) { +- refactoring.inlineAll = inlineAll; +- } +- // final conditions +- status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- // change +- SourceChange change = await refactoring.createChange(); +- this.refactoringChange = change; +- assertTestChangeResult(expectedCode); +- } +- +- void _createRefactoring(String search) { +- int offset = findOffset(search); +- refactoring = new InlineMethodRefactoring( +- searchEngine, astProvider, testUnit, offset); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart +deleted file mode 100644 +index 736448b01c5..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart ++++ /dev/null +@@ -1,754 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/refactoring/naming_conventions.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart' +- show RefactoringProblemSeverity; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_refactoring.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(NamingConventionsTest); +- }); +-} +- +-@reflectiveTest +-class NamingConventionsTest extends RefactoringTest { +- @override +- Refactoring get refactoring => null; +- +- void test_validateClassName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateClassName("newName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: "Class name should start with an uppercase letter."); +- } +- +- void test_validateClassName_empty() { +- assertRefactoringStatus( +- validateClassName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not be empty."); +- } +- +- void test_validateClassName_leadingBlanks() { +- assertRefactoringStatus( +- validateClassName(" NewName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not start or end with a blank."); +- } +- +- void test_validateClassName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateClassName("New-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not contain '-'."); +- } +- +- void test_validateClassName_notIdentifierStart() { +- assertRefactoringStatus( +- validateClassName("-NewName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Class name must begin with an uppercase letter or underscore."); +- } +- +- void test_validateClassName_null() { +- assertRefactoringStatus( +- validateClassName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not be null."); +- } +- +- void test_validateClassName_OK() { +- assertRefactoringStatusOK(validateClassName("NewName")); +- } +- +- void test_validateClassName_OK_leadingDollar() { +- assertRefactoringStatusOK(validateClassName("\$NewName")); +- } +- +- void test_validateClassName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateClassName("_NewName")); +- } +- +- void test_validateClassName_OK_middleDollar() { +- assertRefactoringStatusOK(validateClassName("New\$Name")); +- } +- +- void test_validateClassName_trailingBlanks() { +- assertRefactoringStatus( +- validateClassName("NewName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not start or end with a blank."); +- } +- +- void test_validateConstructorName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateConstructorName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: +- "Constructor name should start with a lowercase letter."); +- } +- +- void test_validateConstructorName_empty() { +- assertRefactoringStatusOK(validateConstructorName("")); +- } +- +- void test_validateConstructorName_leadingBlanks() { +- assertRefactoringStatus( +- validateConstructorName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Constructor name must not start or end with a blank."); +- } +- +- void test_validateConstructorName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateConstructorName("na-me"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Constructor name must not contain '-'."); +- } +- +- void test_validateConstructorName_notIdentifierStart() { +- assertRefactoringStatus( +- validateConstructorName("2name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Constructor name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateConstructorName_null() { +- assertRefactoringStatus( +- validateConstructorName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Constructor name must not be null."); +- } +- +- void test_validateConstructorName_OK() { +- assertRefactoringStatusOK(validateConstructorName("newName")); +- } +- +- void test_validateConstructorName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateConstructorName("_newName")); +- } +- +- void test_validateConstructorName_trailingBlanks() { +- assertRefactoringStatus( +- validateConstructorName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Constructor name must not start or end with a blank."); +- } +- +- void test_validateFieldName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateFieldName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: "Field name should start with a lowercase letter."); +- } +- +- void test_validateFieldName_empty() { +- assertRefactoringStatus( +- validateFieldName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not be empty."); +- } +- +- void test_validateFieldName_leadingBlanks() { +- assertRefactoringStatus( +- validateFieldName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not start or end with a blank."); +- } +- +- void test_validateFieldName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateFieldName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not contain '-'."); +- } +- +- void test_validateFieldName_notIdentifierStart() { +- assertRefactoringStatus( +- validateFieldName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Field name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateFieldName_notKeyword() { +- assertRefactoringStatus( +- validateFieldName("for"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not be a keyword."); +- } +- +- void test_validateFieldName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateFieldName("await"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not be a keyword."); +- } +- +- void test_validateFieldName_null() { +- assertRefactoringStatus( +- validateFieldName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not be null."); +- } +- +- void test_validateFieldName_OK() { +- assertRefactoringStatusOK(validateFieldName("newName")); +- } +- +- void test_validateFieldName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateFieldName("_newName")); +- } +- +- void test_validateFieldName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateFieldName("new_name")); +- } +- +- void test_validateFieldName_trailingBlanks() { +- assertRefactoringStatus( +- validateFieldName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not start or end with a blank."); +- } +- +- void test_validateFunctionName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateFunctionName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: "Function name should start with a lowercase letter."); +- } +- +- void test_validateFunctionName_empty() { +- assertRefactoringStatus( +- validateFunctionName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be empty."); +- } +- +- void test_validateFunctionName_leadingBlanks() { +- assertRefactoringStatus( +- validateFunctionName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not start or end with a blank."); +- } +- +- void test_validateFunctionName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateFunctionName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not contain '-'."); +- } +- +- void test_validateFunctionName_notIdentifierStart() { +- assertRefactoringStatus( +- validateFunctionName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Function name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateFunctionName_notKeyword() { +- assertRefactoringStatus( +- validateFunctionName("new"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be a keyword."); +- } +- +- void test_validateFunctionName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateFunctionName("yield"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be a keyword."); +- } +- +- void test_validateFunctionName_null() { +- assertRefactoringStatus( +- validateFunctionName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be null."); +- } +- +- void test_validateFunctionName_OK() { +- assertRefactoringStatusOK(validateFunctionName("newName")); +- } +- +- void test_validateFunctionName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateFunctionName("_newName")); +- } +- +- void test_validateFunctionName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateFunctionName("new_name")); +- } +- +- void test_validateFunctionName_trailingBlanks() { +- assertRefactoringStatus( +- validateFunctionName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not start or end with a blank."); +- } +- +- void test_validateFunctionTypeAliasName_doesNotStartWithLowerCase() { +- assertRefactoringStatus(validateFunctionTypeAliasName("newName"), +- RefactoringProblemSeverity.WARNING, +- expectedMessage: +- "Function type alias name should start with an uppercase letter."); +- } +- +- void test_validateFunctionTypeAliasName_empty() { +- assertRefactoringStatus( +- validateFunctionTypeAliasName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function type alias name must not be empty."); +- } +- +- void test_validateFunctionTypeAliasName_leadingBlanks() { +- assertRefactoringStatus(validateFunctionTypeAliasName(" NewName"), +- RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Function type alias name must not start or end with a blank."); +- } +- +- void test_validateFunctionTypeAliasName_notIdentifierMiddle() { +- assertRefactoringStatus(validateFunctionTypeAliasName("New-Name"), +- RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function type alias name must not contain '-'."); +- } +- +- void test_validateFunctionTypeAliasName_notIdentifierStart() { +- assertRefactoringStatus(validateFunctionTypeAliasName("-NewName"), +- RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Function type alias name must begin with an uppercase letter or underscore."); +- } +- +- void test_validateFunctionTypeAliasName_null() { +- assertRefactoringStatus( +- validateFunctionTypeAliasName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function type alias name must not be null."); +- } +- +- void test_validateFunctionTypeAliasName_OK() { +- assertRefactoringStatusOK(validateFunctionTypeAliasName("NewName")); +- } +- +- void test_validateFunctionTypeAliasName_OK_leadingDollar() { +- assertRefactoringStatusOK(validateFunctionTypeAliasName("\$NewName")); +- } +- +- void test_validateFunctionTypeAliasName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateFunctionTypeAliasName("_NewName")); +- } +- +- void test_validateFunctionTypeAliasName_OK_middleDollar() { +- assertRefactoringStatusOK(validateFunctionTypeAliasName("New\$Name")); +- } +- +- void test_validateFunctionTypeAliasName_trailingBlanks() { +- assertRefactoringStatus(validateFunctionTypeAliasName("NewName "), +- RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Function type alias name must not start or end with a blank."); +- } +- +- void test_validateImportPrefixName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateImportPrefixName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: +- "Import prefix name should start with a lowercase letter."); +- } +- +- void test_validateImportPrefixName_empty() { +- assertRefactoringStatusOK(validateImportPrefixName("")); +- } +- +- void test_validateImportPrefixName_leadingBlanks() { +- assertRefactoringStatus( +- validateImportPrefixName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Import prefix name must not start or end with a blank."); +- } +- +- void test_validateImportPrefixName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateImportPrefixName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Import prefix name must not contain '-'."); +- } +- +- void test_validateImportPrefixName_notIdentifierStart() { +- assertRefactoringStatus( +- validateImportPrefixName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Import prefix name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateImportPrefixName_notKeyword() { +- assertRefactoringStatus( +- validateImportPrefixName("while"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Import prefix name must not be a keyword."); +- } +- +- void test_validateImportPrefixName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateImportPrefixName("await"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Import prefix name must not be a keyword."); +- } +- +- void test_validateImportPrefixName_null() { +- assertRefactoringStatus( +- validateImportPrefixName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Import prefix name must not be null."); +- } +- +- void test_validateImportPrefixName_OK() { +- assertRefactoringStatusOK(validateImportPrefixName("newName")); +- } +- +- void test_validateImportPrefixName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateImportPrefixName("_newName")); +- } +- +- void test_validateImportPrefixName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateImportPrefixName("new_name")); +- } +- +- void test_validateImportPrefixName_trailingBlanks() { +- assertRefactoringStatus( +- validateImportPrefixName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Import prefix name must not start or end with a blank."); +- } +- +- void test_validateLabelName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateLabelName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: "Label name should start with a lowercase letter."); +- } +- +- void test_validateLabelName_empty() { +- assertRefactoringStatus( +- validateLabelName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not be empty."); +- } +- +- void test_validateLabelName_leadingBlanks() { +- assertRefactoringStatus( +- validateLabelName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not start or end with a blank."); +- } +- +- void test_validateLabelName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateLabelName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not contain '-'."); +- } +- +- void test_validateLabelName_notIdentifierStart() { +- assertRefactoringStatus( +- validateLabelName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Label name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateLabelName_notKeyword() { +- assertRefactoringStatus( +- validateLabelName("for"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not be a keyword."); +- } +- +- void test_validateLabelName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateLabelName("await"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not be a keyword."); +- } +- +- void test_validateLabelName_null() { +- assertRefactoringStatus( +- validateLabelName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not be null."); +- } +- +- void test_validateLabelName_OK() { +- assertRefactoringStatusOK(validateLabelName("newName")); +- } +- +- void test_validateLabelName_OK_leadingDollar() { +- assertRefactoringStatusOK(validateLabelName("\$newName")); +- } +- +- void test_validateLabelName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateLabelName("_newName")); +- } +- +- void test_validateLabelName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateLabelName("new_name")); +- } +- +- void test_validateLabelName_trailingBlanks() { +- assertRefactoringStatus( +- validateLabelName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not start or end with a blank."); +- } +- +- void test_validateLibraryName_blank() { +- assertRefactoringStatus( +- validateLibraryName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name must not be blank."); +- assertRefactoringStatus( +- validateLibraryName(" "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name must not be blank."); +- } +- +- void test_validateLibraryName_blank_identifier() { +- assertRefactoringStatus( +- validateLibraryName("my..name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name identifier must not be empty."); +- assertRefactoringStatus( +- validateLibraryName("my. .name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Library name identifier must not start or end with a blank."); +- } +- +- void test_validateLibraryName_hasUpperCase() { +- assertRefactoringStatus( +- validateLibraryName("my.newName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: +- "Library name should consist of lowercase identifier separated by dots."); +- } +- +- void test_validateLibraryName_leadingBlanks() { +- assertRefactoringStatus( +- validateLibraryName("my. name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Library name identifier must not start or end with a blank."); +- } +- +- void test_validateLibraryName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateLibraryName("my.ba-d.name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name identifier must not contain '-'."); +- } +- +- void test_validateLibraryName_notIdentifierStart() { +- assertRefactoringStatus( +- validateLibraryName("my.2bad.name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Library name identifier must begin with a lowercase letter or underscore."); +- } +- +- void test_validateLibraryName_notKeyword() { +- assertRefactoringStatus( +- validateLibraryName("my.yield.name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name identifier must not be a keyword."); +- } +- +- void test_validateLibraryName_null() { +- assertRefactoringStatus( +- validateLibraryName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name must not be null."); +- } +- +- void test_validateLibraryName_OK_oneIdentifier() { +- assertRefactoringStatusOK(validateLibraryName("name")); +- } +- +- void test_validateLibraryName_OK_severalIdentifiers() { +- assertRefactoringStatusOK(validateLibraryName("my.lib.name")); +- } +- +- void test_validateLibraryName_trailingBlanks() { +- assertRefactoringStatus( +- validateLibraryName("my.bad .name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Library name identifier must not start or end with a blank."); +- } +- +- void test_validateMethodName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateMethodName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: "Method name should start with a lowercase letter."); +- } +- +- void test_validateMethodName_empty() { +- assertRefactoringStatus( +- validateMethodName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be empty."); +- } +- +- void test_validateMethodName_keyword() { +- assertRefactoringStatus( +- validateMethodName("for"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be a keyword."); +- } +- +- void test_validateMethodName_leadingBlanks() { +- assertRefactoringStatus( +- validateMethodName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not start or end with a blank."); +- } +- +- void test_validateMethodName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateMethodName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not contain '-'."); +- } +- +- void test_validateMethodName_notIdentifierStart() { +- assertRefactoringStatus( +- validateMethodName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Method name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateMethodName_notKeyword() { +- assertRefactoringStatus( +- validateMethodName("do"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be a keyword."); +- } +- +- void test_validateMethodName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateMethodName("yield"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be a keyword."); +- } +- +- void test_validateMethodName_null() { +- assertRefactoringStatus( +- validateMethodName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be null."); +- } +- +- void test_validateMethodName_OK() { +- assertRefactoringStatusOK(validateMethodName("newName")); +- } +- +- void test_validateMethodName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateMethodName("_newName")); +- } +- +- void test_validateMethodName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateMethodName("new_name")); +- } +- +- void test_validateMethodName_trailingBlanks() { +- assertRefactoringStatus( +- validateMethodName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not start or end with a blank."); +- } +- +- void test_validateParameterName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateParameterName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: +- "Parameter name should start with a lowercase letter."); +- } +- +- void test_validateParameterName_empty() { +- assertRefactoringStatus( +- validateParameterName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not be empty."); +- } +- +- void test_validateParameterName_leadingBlanks() { +- assertRefactoringStatus( +- validateParameterName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not start or end with a blank."); +- } +- +- void test_validateParameterName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateParameterName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not contain '-'."); +- } +- +- void test_validateParameterName_notIdentifierStart() { +- assertRefactoringStatus( +- validateParameterName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Parameter name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateParameterName_notKeyword() { +- assertRefactoringStatus( +- validateParameterName("while"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not be a keyword."); +- } +- +- void test_validateParameterName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateParameterName("await"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not be a keyword."); +- } +- +- void test_validateParameterName_null() { +- assertRefactoringStatus( +- validateParameterName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not be null."); +- } +- +- void test_validateParameterName_OK() { +- assertRefactoringStatusOK(validateParameterName("newName")); +- } +- +- void test_validateParameterName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateParameterName("_newName")); +- } +- +- void test_validateParameterName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateParameterName("new_name")); +- } +- +- void test_validateParameterName_trailingBlanks() { +- assertRefactoringStatus( +- validateParameterName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not start or end with a blank."); +- } +- +- void test_validateVariableName_doesNotStartWithLowerCase() { +- assertRefactoringStatus( +- validateVariableName("NewName"), RefactoringProblemSeverity.WARNING, +- expectedMessage: "Variable name should start with a lowercase letter."); +- } +- +- void test_validateVariableName_empty() { +- assertRefactoringStatus( +- validateVariableName(""), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be empty."); +- } +- +- void test_validateVariableName_leadingBlanks() { +- assertRefactoringStatus( +- validateVariableName(" newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not start or end with a blank."); +- } +- +- void test_validateVariableName_notIdentifierMiddle() { +- assertRefactoringStatus( +- validateVariableName("new-Name"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not contain '-'."); +- } +- +- void test_validateVariableName_notIdentifierStart() { +- assertRefactoringStatus( +- validateVariableName("2newName"), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "Variable name must begin with a lowercase letter or underscore."); +- } +- +- void test_validateVariableName_notKeyword() { +- assertRefactoringStatus( +- validateVariableName("for"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be a keyword."); +- } +- +- void test_validateVariableName_notPseudoKeyword() { +- assertRefactoringStatus( +- validateVariableName("await"), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be a keyword."); +- } +- +- void test_validateVariableName_null() { +- assertRefactoringStatus( +- validateVariableName(null), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be null."); +- } +- +- void test_validateVariableName_OK() { +- assertRefactoringStatusOK(validateVariableName("newName")); +- } +- +- void test_validateVariableName_OK_leadingDollar() { +- assertRefactoringStatusOK(validateVariableName("\$newName")); +- } +- +- void test_validateVariableName_OK_leadingUnderscore() { +- assertRefactoringStatusOK(validateVariableName("_newName")); +- } +- +- void test_validateVariableName_OK_middleUnderscore() { +- assertRefactoringStatusOK(validateVariableName("new_name")); +- } +- +- void test_validateVariableName_trailingBlanks() { +- assertRefactoringStatus( +- validateVariableName("newName "), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not start or end with a blank."); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart +deleted file mode 100644 +index 18eb7d2e909..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart ++++ /dev/null +@@ -1,894 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameClassMemberTest); +- }); +-} +- +-@reflectiveTest +-class RenameClassMemberTest extends RenameRefactoringTest { +- test_checkFinalConditions_classNameConflict_sameClass() async { +- await indexTestUnit(''' +-class NewName { +- void test() {} +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Renamed method has the same name as the declaring class 'NewName'.", +- expectedContextSearch: 'test() {}'); +- } +- +- test_checkFinalConditions_classNameConflict_subClass() async { +- await indexTestUnit(''' +-class A { +- void test() {} // 1 +-} +-class NewName extends A { +- void test() {} // 2 +-} +-'''); +- createRenameRefactoringAtString('test() {} // 1'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Renamed method has the same name as the declaring class 'NewName'.", +- expectedContextSearch: 'test() {} // 2'); +- } +- +- test_checkFinalConditions_classNameConflict_superClass() async { +- await indexTestUnit(''' +-class NewName { +- void test() {} // 1 +-} +-class B extends NewName { +- void test() {} // 2 +-} +-'''); +- createRenameRefactoringAtString('test() {} // 2'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Renamed method has the same name as the declaring class 'NewName'.", +- expectedContextSearch: 'test() {} // 1'); +- } +- +- test_checkFinalConditions_hasMember_MethodElement() async { +- await indexTestUnit(''' +-class A { +- test() {} +- newName() {} // existing +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Class 'A' already declares method with name 'newName'.", +- expectedContextSearch: 'newName() {} // existing'); +- } +- +- test_checkFinalConditions_OK_dropSuffix() async { +- await indexTestUnit(r''' +-abstract class A { +- void testOld(); +-} +-class B implements A { +- void testOld() {} +-} +-'''); +- createRenameRefactoringAtString('testOld() {}'); +- // check status +- refactoring.newName = 'test'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_OK_noShadow() async { +- await indexTestUnit(''' +-class A { +- int newName; +-} +-class B { +- test() {} +-} +-class C extends A { +- main() { +- print(newName); +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_publicToPrivate_usedInOtherLibrary() async { +- await indexTestUnit(''' +-class A { +- test() {} +-} +-'''); +- await indexUnit('/lib.dart', ''' +-library my.lib; +-import 'test.dart'; +- +-main(A a) { +- a.test(); +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = '_newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed method will be invisible in 'my.lib'."); +- } +- +- test_checkFinalConditions_shadowed_byLocalFunction_inSameClass() async { +- await indexTestUnit(''' +-class A { +- test() {} +- main() { +- newName() {} +- test(); // marker +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Usage of renamed method will be shadowed by function 'newName'.", +- expectedContextSearch: 'test(); // marker'); +- } +- +- test_checkFinalConditions_shadowed_byLocalVariable_inSameClass() async { +- await indexTestUnit(''' +-class A { +- test() {} +- main() { +- var newName; +- test(); // marker +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Usage of renamed method will be shadowed by local variable 'newName'.", +- expectedContextSearch: 'test(); // marker'); +- } +- +- test_checkFinalConditions_shadowed_byLocalVariable_inSubClass() async { +- await indexTestUnit(''' +-class A { +- test() {} +-} +-class B extends A { +- main() { +- var newName; +- test(); // marker +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Usage of renamed method will be shadowed by local variable 'newName'.", +- expectedContextSearch: 'test(); // marker'); +- } +- +- test_checkFinalConditions_shadowed_byLocalVariable_OK_qualifiedReference() async { +- await indexTestUnit(''' +-class A { +- test() {} +- main() { +- var newName; +- this.test(); // marker +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_shadowed_byLocalVariable_OK_renamedNotUsed() async { +- await indexTestUnit(''' +-class A { +- test() {} +- main() { +- var newName; +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_shadowed_byParameter_inSameClass() async { +- await indexTestUnit(''' +-class A { +- test() {} +- main(newName) { +- test(); // marker +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Usage of renamed method will be shadowed by parameter 'newName'.", +- expectedContextSearch: 'test(); // marker'); +- } +- +- test_checkFinalConditions_shadowedBySub_MethodElement() async { +- await indexTestUnit(''' +-class A { +- test() {} +-} +-class B extends A { +- newName() {} // marker +- main() { +- test(); +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Renamed method will be shadowed by method 'B.newName'.", +- expectedContextSearch: 'newName() {} // marker'); +- } +- +- test_checkFinalConditions_shadowsSuper_FieldElement() async { +- await indexTestUnit(''' +-class A { +- int newName; // marker +-} +-class B extends A { +- test() {} +-} +-class C extends B { +- main() { +- print(newName); +- } +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed method will shadow field 'A.newName'.", +- expectedContextSearch: 'newName; // marker'); +- } +- +- test_checkFinalConditions_shadowsSuper_MethodElement() async { +- await indexTestUnit(''' +-class A { +- newName() {} // marker +-} +-class B extends A { +- test() {} +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed method will shadow method 'A.newName'.", +- expectedContextSearch: 'newName() {} // marker'); +- } +- +- test_checkFinalConditions_shadowsSuper_MethodElement_otherLib() async { +- var libCode = r''' +-class A { +- newName() {} // marker +-} +-'''; +- await indexUnit('/lib.dart', libCode); +- await indexTestUnit(''' +-import 'lib.dart'; +-class B extends A { +- test() {} +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed method will shadow method 'A.newName'.", +- expectedContextRange: new SourceRange( +- libCode.indexOf('newName() {} // marker'), 'newName'.length)); +- } +- +- test_checkInitialConditions_inSDK() async { +- await indexTestUnit(''' +-main() { +- 'abc'.toUpperCase(); +-} +-'''); +- createRenameRefactoringAtString('toUpperCase()'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The method 'String.toUpperCase' is defined in the SDK, so cannot be renamed."); +- } +- +- test_checkInitialConditions_operator() async { +- await indexTestUnit(''' +-class A { +- operator -(other) => this; +-} +-'''); +- createRenameRefactoringAtString('-(other)'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL); +- } +- +- test_checkNewName_FieldElement() async { +- await indexTestUnit(''' +-class A { +- int test; +-} +-'''); +- createRenameRefactoringAtString('test;'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Field name must not be null."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_MethodElement() async { +- await indexTestUnit(''' +-class A { +- test() {} +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Method name must not be empty."); +- // same +- refactoring.newName = 'test'; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The new name must be different than the current name."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_createChange_FieldElement() async { +- await indexTestUnit(''' +-class A { +- int test; // marker +- main() { +- print(test); +- test = 1; +- test += 2; +- } +-} +-class B extends A { +-} +-class C extends B { +- get test => 1; +- set test(x) {} +-} +-main() { +- A a = new A(); +- B b = new B(); +- C c = new C(); +- print(a.test); +- a.test = 1; +- a.test += 2; +- print(b.test); +- b.test = 1; +- print(c.test); +- c.test = 1; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test; // marker'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.elementKindName, 'field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- int newName; // marker +- main() { +- print(newName); +- newName = 1; +- newName += 2; +- } +-} +-class B extends A { +-} +-class C extends B { +- get newName => 1; +- set newName(x) {} +-} +-main() { +- A a = new A(); +- B b = new B(); +- C c = new C(); +- print(a.newName); +- a.newName = 1; +- a.newName += 2; +- print(b.newName); +- b.newName = 1; +- print(c.newName); +- c.newName = 1; +-} +-'''); +- } +- +- test_createChange_FieldElement_constructorFieldInitializer() async { +- await indexTestUnit(''' +-class A { +- final test; +- A() : test = 5; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test;'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- final newName; +- A() : newName = 5; +-} +-'''); +- } +- +- test_createChange_FieldElement_fieldFormalParameter() async { +- await indexTestUnit(''' +-class A { +- final test; +- A(this.test); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test;'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- final newName; +- A(this.newName); +-} +-'''); +- } +- +- test_createChange_FieldElement_fieldFormalParameter_named() async { +- await indexTestUnit(''' +-class A { +- final test; +- A({this.test}); +-} +-main() { +- new A(test: 42); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test;'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- final newName; +- A({this.newName}); +-} +-main() { +- new A(newName: 42); +-} +-'''); +- } +- +- test_createChange_FieldElement_invocation() async { +- await indexTestUnit(''' +-typedef F(a); +-class A { +- F test; +- main() { +- test(1); +- } +-} +-main() { +- A a = new A(); +- a.test(2); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test(2);'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-typedef F(a); +-class A { +- F newName; +- main() { +- newName(1); +- } +-} +-main() { +- A a = new A(); +- a.newName(2); +-} +-'''); +- } +- +- test_createChange_MethodElement() async { +- await indexTestUnit(''' +-class A { +- test() {} +-} +-class B extends A { +- test() {} // marker +-} +-class C extends B { +- test() {} +-} +-class D implements A { +- test() {} +-} +-class E { +- test() {} +-} +-main() { +- A a = new A(); +- B b = new B(); +- C c = new C(); +- D d = new D(); +- E e = new E(); +- a.test(); +- b.test(); +- c.test(); +- d.test(); +- e.test(); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test() {} // marker'); +- expect(refactoring.refactoringName, 'Rename Method'); +- expect(refactoring.elementKindName, 'method'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- newName() {} +-} +-class B extends A { +- newName() {} // marker +-} +-class C extends B { +- newName() {} +-} +-class D implements A { +- newName() {} +-} +-class E { +- test() {} +-} +-main() { +- A a = new A(); +- B b = new B(); +- C c = new C(); +- D d = new D(); +- E e = new E(); +- a.newName(); +- b.newName(); +- c.newName(); +- d.newName(); +- e.test(); +-} +-'''); +- } +- +- test_createChange_MethodElement_potential() async { +- await indexTestUnit(''' +-class A { +- test() {} +-} +-main(var a) { +- a.test(); // 1 +- new A().test(); +- a.test(); // 2 +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test() {}'); +- expect(refactoring.refactoringName, 'Rename Method'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- await assertSuccessfulRefactoring(''' +-class A { +- newName() {} +-} +-main(var a) { +- a.newName(); // 1 +- new A().newName(); +- a.newName(); // 2 +-} +-'''); +- assertPotentialEdits(['test(); // 1', 'test(); // 2']); +- } +- +- test_createChange_MethodElement_potential_inPubCache() async { +- String pkgLib = '/.pub-cache/lib.dart'; +- await indexUnit(pkgLib, r''' +-processObj(p) { +- p.test(); +-} +-'''); +- await indexTestUnit(''' +-import '$pkgLib'; +-class A { +- test() {} +-} +-main(var a) { +- a.test(); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test() {}'); +- expect(refactoring.refactoringName, 'Rename Method'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- await assertSuccessfulRefactoring(''' +-import '/.pub-cache/lib.dart'; +-class A { +- newName() {} +-} +-main(var a) { +- a.newName(); +-} +-'''); +- SourceFileEdit fileEdit = refactoringChange.getFileEdit(pkgLib); +- expect(fileEdit, isNull); +- } +- +- test_createChange_MethodElement_potential_private_otherLibrary() async { +- await indexUnit('/lib.dart', ''' +-library lib; +-main(p) { +- p._test(); +-} +-'''); +- await indexTestUnit(''' +-class A { +- _test() {} +-} +-main(var a) { +- a._test(); +- new A()._test(); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('_test() {}'); +- expect(refactoring.refactoringName, 'Rename Method'); +- expect(refactoring.oldName, '_test'); +- refactoring.newName = 'newName'; +- // validate change +- await assertSuccessfulRefactoring(''' +-class A { +- newName() {} +-} +-main(var a) { +- a.newName(); +- new A().newName(); +-} +-'''); +- assertNoFileChange('/lib.dart'); +- } +- +- test_createChange_PropertyAccessorElement_getter() async { +- await indexTestUnit(''' +-class A { +- get test {} // marker +- set test(x) {} +- main() { +- print(test); +- test = 1; +- } +-} +-class B extends A { +- get test {} +- set test(x) {} +-} +-main() { +- A a = new A(); +- print(a.test); +- a.test = 2; +- +- B b = new B(); +- print(b.test); +- b.test = 2; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test {} // marker'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- get newName {} // marker +- set newName(x) {} +- main() { +- print(newName); +- newName = 1; +- } +-} +-class B extends A { +- get newName {} +- set newName(x) {} +-} +-main() { +- A a = new A(); +- print(a.newName); +- a.newName = 2; +- +- B b = new B(); +- print(b.newName); +- b.newName = 2; +-} +-'''); +- } +- +- test_createChange_PropertyAccessorElement_setter() async { +- await indexTestUnit(''' +-class A { +- get test {} +- set test(x) {} // marker +- main() { +- print(test); +- test = 1; +- } +-} +-class B extends A { +- get test {} +- set test(x) {} +-} +-main() { +- A a = new A(); +- print(a.test); +- a.test = 2; +- +- B b = new B(); +- print(b.test); +- b.test = 2; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test(x) {} // marker'); +- expect(refactoring.refactoringName, 'Rename Field'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- get newName {} +- set newName(x) {} // marker +- main() { +- print(newName); +- newName = 1; +- } +-} +-class B extends A { +- get newName {} +- set newName(x) {} +-} +-main() { +- A a = new A(); +- print(a.newName); +- a.newName = 2; +- +- B b = new B(); +- print(b.newName); +- b.newName = 2; +-} +-'''); +- } +- +- test_createChange_TypeParameterElement() async { +- await indexTestUnit(''' +-class A { +- Test field; +- List items; +- Test method(Test p) => null; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('Test> {'); +- expect(refactoring.refactoringName, 'Rename Type Parameter'); +- expect(refactoring.elementKindName, 'type parameter'); +- expect(refactoring.oldName, 'Test'); +- refactoring.newName = 'NewName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A { +- NewName field; +- List items; +- NewName method(NewName p) => null; +-} +-'''); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart +deleted file mode 100644 +index 1434a051cd0..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart ++++ /dev/null +@@ -1,249 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analysis_server/src/services/refactoring/refactoring.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameConstructorTest); +- }); +-} +- +-@reflectiveTest +-class RenameConstructorTest extends RenameRefactoringTest { +- test_checkInitialConditions_inSDK() async { +- await indexTestUnit(''' +-main() { +- new String.fromCharCodes([]); +-} +-'''); +- createRenameRefactoringAtString('fromCharCodes('); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The constructor 'String.fromCharCodes' is defined in the SDK, so cannot be renamed."); +- } +- +- test_checkNewName() async { +- await indexTestUnit(''' +-class A { +- A.test() {} +-} +-'''); +- createRenameRefactoringAtString('test() {}'); +- expect(refactoring.oldName, 'test'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Constructor name must not be null."); +- // same +- refactoring.newName = 'test'; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The new name must be different than the current name."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_hasMember_constructor() async { +- await indexTestUnit(''' +-class A { +- A.test() {} +- A.newName() {} // existing +-} +-'''); +- _createConstructorDeclarationRefactoring('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = refactoring.checkNewName(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Class 'A' already declares constructor with name 'newName'.", +- expectedContextSearch: 'newName() {} // existing'); +- } +- +- test_checkNewName_hasMember_method() async { +- await indexTestUnit(''' +-class A { +- A.test() {} +- newName() {} // existing +-} +-'''); +- _createConstructorDeclarationRefactoring('test() {}'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = refactoring.checkNewName(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Class 'A' already declares method with name 'newName'.", +- expectedContextSearch: 'newName() {} // existing'); +- } +- +- test_createChange_add() async { +- await indexTestUnit(''' +-class A { +- A() {} // marker +- factory A._() = A; +-} +-class B extends A { +- B() : super() {} +-} +-main() { +- new A(); +-} +-'''); +- // configure refactoring +- _createConstructorDeclarationRefactoring('() {} // marker'); +- expect(refactoring.refactoringName, 'Rename Constructor'); +- expect(refactoring.elementKindName, 'constructor'); +- expect(refactoring.oldName, ''); +- // validate change +- refactoring.newName = 'newName'; +- return assertSuccessfulRefactoring(''' +-class A { +- A.newName() {} // marker +- factory A._() = A.newName; +-} +-class B extends A { +- B() : super.newName() {} +-} +-main() { +- new A.newName(); +-} +-'''); +- } +- +- test_createChange_add_toSynthetic() async { +- await indexTestUnit(''' +-class A { +-} +-class B extends A { +- B() : super() {} +-} +-main() { +- new A(); +-} +-'''); +- // configure refactoring +- _createConstructorInvocationRefactoring('new A();'); +- expect(refactoring.refactoringName, 'Rename Constructor'); +- expect(refactoring.elementKindName, 'constructor'); +- expect(refactoring.oldName, ''); +- // validate change +- refactoring.newName = 'newName'; +- return assertSuccessfulRefactoring(''' +-class A { +- A.newName(); +-} +-class B extends A { +- B() : super.newName() {} +-} +-main() { +- new A.newName(); +-} +-'''); +- } +- +- test_createChange_change() async { +- await indexTestUnit(''' +-class A { +- A.test() {} // marker +- factory A._() = A.test; +-} +-class B extends A { +- B() : super.test() {} +-} +-main() { +- new A.test(); +-} +-'''); +- // configure refactoring +- _createConstructorDeclarationRefactoring('test() {} // marker'); +- expect(refactoring.refactoringName, 'Rename Constructor'); +- expect(refactoring.elementKindName, 'constructor'); +- expect(refactoring.oldName, 'test'); +- // validate change +- refactoring.newName = 'newName'; +- return assertSuccessfulRefactoring(''' +-class A { +- A.newName() {} // marker +- factory A._() = A.newName; +-} +-class B extends A { +- B() : super.newName() {} +-} +-main() { +- new A.newName(); +-} +-'''); +- } +- +- test_createChange_remove() async { +- await indexTestUnit(''' +-class A { +- A.test() {} // marker +- factory A._() = A.test; +-} +-class B extends A { +- B() : super.test() {} +-} +-main() { +- new A.test(); +-} +-'''); +- // configure refactoring +- _createConstructorDeclarationRefactoring('test() {} // marker'); +- expect(refactoring.refactoringName, 'Rename Constructor'); +- expect(refactoring.elementKindName, 'constructor'); +- expect(refactoring.oldName, 'test'); +- // validate change +- refactoring.newName = ''; +- return assertSuccessfulRefactoring(''' +-class A { +- A() {} // marker +- factory A._() = A; +-} +-class B extends A { +- B() : super() {} +-} +-main() { +- new A(); +-} +-'''); +- } +- +- test_newInstance_nullElement() async { +- RenameRefactoring refactoring = +- new RenameRefactoring(searchEngine, null, null); +- expect(refactoring, isNull); +- } +- +- void _createConstructorDeclarationRefactoring(String search) { +- ConstructorElement element = findNodeElementAtString( +- search, (node) => node is ConstructorDeclaration); +- createRenameRefactoringForElement(element); +- } +- +- void _createConstructorInvocationRefactoring(String search) { +- ConstructorElement element = findNodeElementAtString( +- search, (node) => node is InstanceCreationExpression); +- createRenameRefactoringForElement(element); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart +deleted file mode 100644 +index ed29086e76b..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart ++++ /dev/null +@@ -1,230 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameImportTest); +- }); +-} +- +-@reflectiveTest +-class RenameImportTest extends RenameRefactoringTest { +- test_checkNewName() async { +- await indexTestUnit("import 'dart:async' as test;"); +- _createRefactoring("import 'dart:"); +- expect(refactoring.oldName, 'test'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Import prefix name must not be null."); +- // same +- refactoring.newName = 'test'; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The new name must be different than the current name."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_createChange_add() async { +- await indexTestUnit(''' +-import 'dart:async'; +-import 'dart:math' show Random, min hide max; +-main() { +- Future f; +- Random r; +- min(1, 2); +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:math"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-import 'dart:async'; +-import 'dart:math' as newName show Random, min hide max; +-main() { +- Future f; +- newName.Random r; +- newName.min(1, 2); +-} +-'''); +- } +- +- test_createChange_add_interpolationExpression_hasCurlyBrackets() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-main() { +- Future f; +- print('Future type: ${Future}'); +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:async"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(r''' +-import 'dart:async' as newName; +-main() { +- newName.Future f; +- print('Future type: ${newName.Future}'); +-} +-'''); +- } +- +- test_createChange_add_interpolationExpression_noCurlyBrackets() async { +- await indexTestUnit(r''' +-import 'dart:async'; +-main() { +- Future f; +- print('Future type: $Future'); +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:async"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(r''' +-import 'dart:async' as newName; +-main() { +- newName.Future f; +- print('Future type: ${newName.Future}'); +-} +-'''); +- } +- +- test_createChange_change_className() async { +- await indexTestUnit(''' +-import 'dart:math' as test; +-import 'dart:async' as test; +-main() { +- test.Future f; +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:async"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-import 'dart:math' as test; +-import 'dart:async' as newName; +-main() { +- newName.Future f; +-} +-'''); +- } +- +- test_createChange_change_function() async { +- await indexTestUnit(''' +-import 'dart:math' as test; +-import 'dart:async' as test; +-main() { +- test.max(1, 2); +- test.Future f; +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:math"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-import 'dart:math' as newName; +-import 'dart:async' as test; +-main() { +- newName.max(1, 2); +- test.Future f; +-} +-'''); +- } +- +- test_createChange_change_onPrefixElement() async { +- await indexTestUnit(''' +-import 'dart:async' as test; +-import 'dart:math' as test; +-main() { +- test.Future f; +- test.PI; +- test.E; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test.PI'); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-import 'dart:async' as test; +-import 'dart:math' as newName; +-main() { +- test.Future f; +- newName.PI; +- newName.E; +-} +-'''); +- } +- +- test_createChange_remove() async { +- await indexTestUnit(''' +-import 'dart:math' as test; +-import 'dart:async' as test; +-main() { +- test.Future f; +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:async"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = ''; +- // validate change +- return assertSuccessfulRefactoring(''' +-import 'dart:math' as test; +-import 'dart:async'; +-main() { +- Future f; +-} +-'''); +- } +- +- test_oldName_empty() async { +- await indexTestUnit(''' +-import 'dart:math'; +-import 'dart:async'; +-main() { +- Future f; +-} +-'''); +- // configure refactoring +- _createRefactoring("import 'dart:async"); +- expect(refactoring.refactoringName, 'Rename Import Prefix'); +- expect(refactoring.oldName, ''); +- } +- +- void _createRefactoring(String search) { +- ImportDirective directive = +- findNodeAtString(search, (node) => node is ImportDirective); +- createRenameRefactoringForElement(directive.element); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart b/pkg/analysis_server/test/services/refactoring/rename_label_test.dart +deleted file mode 100644 +index 076ec774931..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart ++++ /dev/null +@@ -1,83 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameLabelTest); +- }); +-} +- +-@reflectiveTest +-class RenameLabelTest extends RenameRefactoringTest { +- test_checkNewName_LocalVariableElement() async { +- await indexTestUnit(''' +-main() { +-test: +- while (true) { +- break test; +- } +-} +-'''); +- createRenameRefactoringAtString('test:'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Label name must not be empty."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_createChange() async { +- await indexTestUnit(''' +-main() { +-test: +- while (true) { +- break test; +- } +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test:'); +- expect(refactoring.refactoringName, 'Rename Label'); +- expect(refactoring.elementKindName, 'label'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +-newName: +- while (true) { +- break newName; +- } +-} +-'''); +- } +- +- test_oldName() async { +- await indexTestUnit(''' +-main() { +-test: +- while (true) { +- break test; +- } +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test:'); +- // old name +- expect(refactoring.oldName, 'test'); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart +deleted file mode 100644 +index 1acca7dc124..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart ++++ /dev/null +@@ -1,91 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameLibraryTest); +- }); +-} +- +-@reflectiveTest +-class RenameLibraryTest extends RenameRefactoringTest { +- test_checkNewName() async { +- await indexTestUnit(''' +-library my.app; +-'''); +- _createRenameRefactoring(); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Library name must not be blank."); +- // same name +- refactoring.newName = 'my.app'; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The new name must be different than the current name."); +- } +- +- test_createChange() async { +- addSource('/part.dart', ''' +-part of my.app; +-'''); +- await indexTestUnit(''' +-library my.app; +-part 'part.dart'; +-'''); +- // configure refactoring +- _createRenameRefactoring(); +- expect(refactoring.refactoringName, 'Rename Library'); +- expect(refactoring.elementKindName, 'library'); +- refactoring.newName = 'the.new.name'; +- // validate change +- await assertSuccessfulRefactoring(''' +-library the.new.name; +-part 'part.dart'; +-'''); +- assertFileChangeResult('/part.dart', ''' +-part of the.new.name; +-'''); +- } +- +- test_createChange_hasWhitespaces() async { +- addSource('/part.dart', ''' +-part of my . app; +-'''); +- await indexTestUnit(''' +-library my . app; +-part 'part.dart'; +-'''); +- // configure refactoring +- _createRenameRefactoring(); +- expect(refactoring.refactoringName, 'Rename Library'); +- expect(refactoring.elementKindName, 'library'); +- refactoring.newName = 'the.new.name'; +- // validate change +- await assertSuccessfulRefactoring(''' +-library the.new.name; +-part 'part.dart'; +-'''); +- assertFileChangeResult('/part.dart', ''' +-part of the.new.name; +-'''); +- } +- +- void _createRenameRefactoring() { +- createRenameRefactoringForElement(testUnitElement.library); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart +deleted file mode 100644 +index 8533be07c98..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart ++++ /dev/null +@@ -1,545 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameLocalTest); +- }); +-} +- +-@reflectiveTest +-class RenameLocalTest extends RenameRefactoringTest { +- test_checkFinalConditions_hasLocalFunction_after() async { +- await indexTestUnit(''' +-main() { +- int test = 0; +- newName() => 1; +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Duplicate function 'newName'.", +- expectedContextSearch: 'newName() => 1'); +- } +- +- test_checkFinalConditions_hasLocalFunction_before() async { +- await indexTestUnit(''' +-main() { +- newName() => 1; +- int test = 0; +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Duplicate function 'newName'."); +- } +- +- test_checkFinalConditions_hasLocalVariable_after() async { +- await indexTestUnit(''' +-main() { +- int test = 0; +- var newName = 1; +- print(newName); +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- expect(status.problems, hasLength(1)); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Duplicate local variable 'newName'.", +- expectedContextSearch: 'newName = 1;'); +- } +- +- test_checkFinalConditions_hasLocalVariable_before() async { +- await indexTestUnit(''' +-main() { +- var newName = 1; +- int test = 0; +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Duplicate local variable 'newName'.", +- expectedContextSearch: 'newName = 1;'); +- } +- +- test_checkFinalConditions_hasLocalVariable_otherBlock() async { +- await indexTestUnit(''' +-main() { +- { +- var newName = 1; +- } +- { +- int test = 0; +- } +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- return assertRefactoringConditionsOK(); +- } +- +- test_checkFinalConditions_hasLocalVariable_otherForEachLoop() async { +- await indexTestUnit(''' +-main() { +- for (int newName in []) {} +- for (int test in []) {} +-} +-'''); +- createRenameRefactoringAtString('test in'); +- // check status +- refactoring.newName = 'newName'; +- return assertRefactoringConditionsOK(); +- } +- +- test_checkFinalConditions_hasLocalVariable_otherForLoop() async { +- await indexTestUnit(''' +-main() { +- for (int newName = 0; newName < 10; newName++) {} +- for (int test = 0; test < 10; test++) {} +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- return assertRefactoringConditionsOK(); +- } +- +- test_checkFinalConditions_hasLocalVariable_otherFunction() async { +- await indexTestUnit(''' +-main() { +- int test = 0; +-} +-main2() { +- var newName = 1; +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- return assertRefactoringConditionsOK(); +- } +- +- test_checkFinalConditions_shadows_classMember() async { +- await indexTestUnit(''' +-class A { +- var newName = 1; +- main() { +- var test = 0; +- print(newName); +- } +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: 'Usage of field "A.newName" declared in "test.dart" ' +- 'will be shadowed by renamed local variable.', +- expectedContextSearch: 'newName);'); +- } +- +- test_checkFinalConditions_shadows_classMember_namedParameter() async { +- await indexTestUnit(''' +-class A { +- foo({test: 1}) { // in A +- } +-} +-class B extends A { +- var newName = 1; +- foo({test: 1}) { +- print(newName); +- } +-} +-'''); +- createRenameRefactoringAtString('test: 1}) { // in A'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: 'Usage of field "B.newName" declared in "test.dart" ' +- 'will be shadowed by renamed parameter.', +- expectedContextSearch: 'newName);'); +- } +- +- test_checkFinalConditions_shadows_classMemberOK_qualifiedReference() async { +- await indexTestUnit(''' +-class A { +- var newName = 1; +- main() { +- var test = 0; +- print(this.newName); +- } +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- return assertRefactoringConditionsOK(); +- } +- +- test_checkFinalConditions_shadows_OK_namedParameterReference() async { +- await indexTestUnit(''' +-void f({newName}) {} +-main() { +- var test = 0; +- f(newName: test); +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- return assertRefactoringFinalConditionsOK(); +- } +- +- test_checkFinalConditions_shadows_topLevelFunction() async { +- await indexTestUnit(''' +-newName() {} +-main() { +- var test = 0; +- newName(); // ref +-} +-'''); +- createRenameRefactoringAtString('test = 0'); +- // check status +- refactoring.newName = 'newName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedContextSearch: 'newName(); // ref'); +- } +- +- test_checkNewName_FunctionElement() async { +- await indexTestUnit(''' +-main() { +- int test() => 0; +-} +-'''); +- createRenameRefactoringAtString('test() => 0;'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be null."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_LocalVariableElement() async { +- await indexTestUnit(''' +-main() { +- int test = 0; +-} +-'''); +- createRenameRefactoringAtString('test = 0;'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be empty."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_ParameterElement() async { +- await indexTestUnit(''' +-main(test) { +-} +-'''); +- createRenameRefactoringAtString('test) {'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Parameter name must not be null."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_createChange_localFunction() async { +- await indexTestUnit(''' +-main() { +- int test() => 0; +- print(test); +- print(test()); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test() => 0'); +- expect(refactoring.refactoringName, 'Rename Local Function'); +- expect(refactoring.elementKindName, 'function'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- int newName() => 0; +- print(newName); +- print(newName()); +-} +-'''); +- } +- +- test_createChange_localFunction_sameNameDifferenceScopes() async { +- await indexTestUnit(''' +-main() { +- { +- int test() => 0; +- print(test); +- } +- { +- int test() => 1; +- print(test); +- } +- { +- int test() => 2; +- print(test); +- } +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test() => 1'); +- expect(refactoring.refactoringName, 'Rename Local Function'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- { +- int test() => 0; +- print(test); +- } +- { +- int newName() => 1; +- print(newName); +- } +- { +- int test() => 2; +- print(test); +- } +-} +-'''); +- } +- +- test_createChange_localVariable() async { +- await indexTestUnit(''' +-main() { +- int test = 0; +- test = 1; +- test += 2; +- print(test); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test = 0'); +- expect(refactoring.refactoringName, 'Rename Local Variable'); +- expect(refactoring.elementKindName, 'local variable'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- int newName = 0; +- newName = 1; +- newName += 2; +- print(newName); +-} +-'''); +- } +- +- test_createChange_localVariable_sameNameDifferenceScopes() async { +- await indexTestUnit(''' +-main() { +- { +- int test = 0; +- print(test); +- } +- { +- int test = 1; +- print(test); +- } +- { +- int test = 2; +- print(test); +- } +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test = 1'); +- expect(refactoring.refactoringName, 'Rename Local Variable'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-main() { +- { +- int test = 0; +- print(test); +- } +- { +- int newName = 1; +- print(newName); +- } +- { +- int test = 2; +- print(test); +- } +-} +-'''); +- } +- +- test_createChange_parameter() async { +- await indexTestUnit(''' +-myFunction({int test}) { +- test = 1; +- test += 2; +- print(test); +-} +-main() { +- myFunction(test: 2); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test}) {'); +- expect(refactoring.refactoringName, 'Rename Parameter'); +- expect(refactoring.elementKindName, 'parameter'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-myFunction({int newName}) { +- newName = 1; +- newName += 2; +- print(newName); +-} +-main() { +- myFunction(newName: 2); +-} +-'''); +- } +- +- test_createChange_parameter_named_inOtherFile() async { +- await indexTestUnit(''' +-class A { +- A({test}); +-} +-'''); +- await indexUnit('/test2.dart', ''' +-import 'test.dart'; +-main() { +- new A(test: 2); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test});'); +- expect(refactoring.refactoringName, 'Rename Parameter'); +- refactoring.newName = 'newName'; +- // validate change +- await assertSuccessfulRefactoring(''' +-class A { +- A({newName}); +-} +-'''); +- assertFileChangeResult('/test2.dart', ''' +-import 'test.dart'; +-main() { +- new A(newName: 2); +-} +-'''); +- } +- +- test_createChange_parameter_named_updateHierarchy() async { +- await indexUnit('/test2.dart', ''' +-library test2; +-class A { +- void foo({int test: 1}) { +- print(test); +- } +-} +-class B extends A { +- void foo({int test: 2}) { +- print(test); +- } +-} +-'''); +- await indexTestUnit(''' +-import 'test2.dart'; +-main() { +- new A().foo(test: 10); +- new B().foo(test: 20); +- new C().foo(test: 30); +-} +-class C extends A { +- void foo({int test: 3}) { +- print(test); +- } +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test: 20'); +- expect(refactoring.refactoringName, 'Rename Parameter'); +- refactoring.newName = 'newName'; +- // validate change +- await assertSuccessfulRefactoring(''' +-import 'test2.dart'; +-main() { +- new A().foo(newName: 10); +- new B().foo(newName: 20); +- new C().foo(newName: 30); +-} +-class C extends A { +- void foo({int newName: 3}) { +- print(newName); +- } +-} +-'''); +- assertFileChangeResult('/test2.dart', ''' +-library test2; +-class A { +- void foo({int newName: 1}) { +- print(newName); +- } +-} +-class B extends A { +- void foo({int newName: 2}) { +- print(newName); +- } +-} +-'''); +- } +- +- test_oldName() async { +- await indexTestUnit(''' +-main() { +- int test = 0; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test = 0'); +- // old name +- expect(refactoring.oldName, 'test'); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart +deleted file mode 100644 +index 80085b4ced9..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart ++++ /dev/null +@@ -1,607 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:analysis_server/src/services/correction/status.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'abstract_rename.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RenameUnitMemberTest); +- }); +-} +- +-@reflectiveTest +-class RenameUnitMemberTest extends RenameRefactoringTest { +- test_checkFinalConditions_hasTopLevel_ClassElement() async { +- await indexTestUnit(''' +-class Test {} +-class NewName {} // existing +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Library already declares class with name 'NewName'.", +- expectedContextSearch: 'NewName {} // existing'); +- } +- +- test_checkFinalConditions_hasTopLevel_FunctionTypeAliasElement() async { +- await indexTestUnit(''' +-class Test {} +-typedef NewName(); // existing +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Library already declares function type alias with name 'NewName'.", +- expectedContextSearch: 'NewName(); // existing'); +- } +- +- test_checkFinalConditions_OK_qualifiedSuper_MethodElement() async { +- await indexTestUnit(''' +-class Test {} +-class A { +- NewName() {} +-} +-class B extends A { +- main() { +- super.NewName(); // super-ref +- } +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_publicToPrivate_usedInOtherLibrary() async { +- await indexTestUnit(''' +-class Test {} +-'''); +- await indexUnit('/lib.dart', ''' +-library my.lib; +-import 'test.dart'; +- +-main() { +- new Test(); +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = '_NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed class will be invisible in 'my.lib'."); +- } +- +- test_checkFinalConditions_shadowedBy_MethodElement() async { +- await indexTestUnit(''' +-class Test {} +-class A { +- void NewName() {} +- main() { +- new Test(); +- } +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: +- "Reference to renamed class will be shadowed by method 'A.NewName'.", +- expectedContextSearch: 'NewName() {}'); +- } +- +- test_checkFinalConditions_shadowsInSubClass_importedLib() async { +- await indexTestUnit(''' +-class Test {} +-'''); +- await indexUnit('/lib.dart', ''' +-library my.lib; +-import 'test.dart'; +-class A { +- NewName() {} +-} +-class B extends A { +- main() { +- NewName(); // super-ref +- }", +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed class will shadow method 'A.NewName'."); +- } +- +- test_checkFinalConditions_shadowsInSubClass_importedLib_hideCombinator() async { +- await indexTestUnit(''' +-class Test {} +-'''); +- await indexUnit('/lib.dart', ''' +-library my.lib; +-import 'test.dart' hide Test; +-class A { +- NewName() {} +-} +-class B extends A { +- main() { +- NewName(); // super-ref +- }", +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_shadowsInSubClass_MethodElement() async { +- await indexTestUnit(''' +-class Test {} +-class A { +- NewName() {} +-} +-class B extends A { +- main() { +- NewName(); // super-ref +- } +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR, +- expectedMessage: "Renamed class will shadow method 'A.NewName'.", +- expectedContextSearch: 'NewName(); // super-ref'); +- } +- +- test_checkFinalConditions_shadowsInSubClass_notImportedLib() async { +- await indexUnit('/lib.dart', ''' +-library my.lib; +-class A { +- NewName() {} +-} +-class B extends A { +- main() { +- NewName(); // super-ref +- }", +-} +-'''); +- await indexTestUnit(''' +-class Test {} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkFinalConditions_shadowsInSubClass_notSubClass() async { +- await indexTestUnit(''' +-class Test {} +-class A { +- NewName() {} +-} +-class B { +- main(A a) { +- a.NewName(); +- } +-} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkFinalConditions(); +- assertRefactoringStatusOK(status); +- } +- +- test_checkInitialConditions_inPubCache_posix() async { +- addSource('/.pub-cache/lib.dart', r''' +-class A {} +-'''); +- await indexTestUnit(''' +-import '/.pub-cache/lib.dart'; +-main() { +- A a; +-} +-'''); +- createRenameRefactoringAtString('A a'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The class 'A' is defined in a pub package, so cannot be renamed."); +- } +- +- test_checkInitialConditions_inPubCache_windows() async { +- addSource('/Pub/Cache/lib.dart', r''' +-class A {} +-'''); +- await indexTestUnit(''' +-import '/Pub/Cache/lib.dart'; +-main() { +- A a; +-} +-'''); +- createRenameRefactoringAtString('A a'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The class 'A' is defined in a pub package, so cannot be renamed."); +- } +- +- test_checkInitialConditions_inSDK() async { +- await indexTestUnit(''' +-main() { +- String s; +-} +-'''); +- createRenameRefactoringAtString('String s'); +- // check status +- refactoring.newName = 'NewName'; +- RefactoringStatus status = await refactoring.checkInitialConditions(); +- assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The class 'String' is defined in the SDK, so cannot be renamed."); +- } +- +- test_checkNewName_ClassElement() async { +- await indexTestUnit(''' +-class Test {} +-'''); +- createRenameRefactoringAtString('Test {}'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Class name must not be empty."); +- // same +- refactoring.newName = 'Test'; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: +- "The new name must be different than the current name."); +- // OK +- refactoring.newName = 'NewName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_FunctionElement() async { +- await indexTestUnit(''' +-test() {} +-'''); +- createRenameRefactoringAtString('test() {}'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function name must not be empty."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_FunctionTypeAliasElement() async { +- await indexTestUnit(''' +-typedef Test(); +-'''); +- createRenameRefactoringAtString('Test();'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Function type alias name must not be null."); +- // OK +- refactoring.newName = 'NewName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_checkNewName_TopLevelVariableElement() async { +- await indexTestUnit(''' +-var test; +-'''); +- createRenameRefactoringAtString('test;'); +- // null +- refactoring.newName = null; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be null."); +- // empty +- refactoring.newName = ''; +- assertRefactoringStatus( +- refactoring.checkNewName(), RefactoringProblemSeverity.FATAL, +- expectedMessage: "Variable name must not be empty."); +- // OK +- refactoring.newName = 'newName'; +- assertRefactoringStatusOK(refactoring.checkNewName()); +- } +- +- test_createChange_ClassElement() async { +- await indexTestUnit(''' +-class Test implements Other { +- Test() {} +- Test.named() {} +-} +-class Other { +- factory Other.a() = Test; +- factory Other.b() = Test.named; +-} +-main() { +- Test t1 = new Test(); +- Test t2 = new Test.named(); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('Test implements'); +- expect(refactoring.refactoringName, 'Rename Class'); +- expect(refactoring.elementKindName, 'class'); +- expect(refactoring.oldName, 'Test'); +- refactoring.newName = 'NewName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class NewName implements Other { +- NewName() {} +- NewName.named() {} +-} +-class Other { +- factory Other.a() = NewName; +- factory Other.b() = NewName.named; +-} +-main() { +- NewName t1 = new NewName(); +- NewName t2 = new NewName.named(); +-} +-'''); +- } +- +- test_createChange_ClassElement_invocation() async { +- verifyNoTestUnitErrors = false; +- await indexTestUnit(''' +-class Test { +-} +-main() { +- Test(); // invalid code, but still a reference +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('Test();'); +- expect(refactoring.refactoringName, 'Rename Class'); +- expect(refactoring.elementKindName, 'class'); +- expect(refactoring.oldName, 'Test'); +- refactoring.newName = 'NewName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class NewName { +-} +-main() { +- NewName(); // invalid code, but still a reference +-} +-'''); +- } +- +- test_createChange_ClassElement_parameterTypeNested() async { +- await indexTestUnit(''' +-class Test { +-} +-main(f(Test p)) { +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('Test {'); +- expect(refactoring.refactoringName, 'Rename Class'); +- expect(refactoring.oldName, 'Test'); +- refactoring.newName = 'NewName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class NewName { +-} +-main(f(NewName p)) { +-} +-'''); +- } +- +- test_createChange_ClassElement_typeAlias() async { +- await indexTestUnit(''' +-class A {} +-class Test = Object with A; +-main(Test t) { +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('Test ='); +- expect(refactoring.refactoringName, 'Rename Class'); +- expect(refactoring.elementKindName, 'class'); +- expect(refactoring.oldName, 'Test'); +- refactoring.newName = 'NewName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-class A {} +-class NewName = Object with A; +-main(NewName t) { +-} +-'''); +- } +- +- test_createChange_FunctionElement() async { +- await indexTestUnit(''' +-test() {} +-foo() {} +-main() { +- print(test); +- print(test()); +- foo(); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test() {}'); +- expect(refactoring.refactoringName, 'Rename Top-Level Function'); +- expect(refactoring.elementKindName, 'function'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-newName() {} +-foo() {} +-main() { +- print(newName); +- print(newName()); +- foo(); +-} +-'''); +- } +- +- test_createChange_FunctionElement_imported() async { +- await indexUnit('/foo.dart', r''' +-test() {} +-foo() {} +-'''); +- await indexTestUnit(''' +-import 'foo.dart'; +-main() { +- print(test); +- print(test()); +- foo(); +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString('test);'); +- expect(refactoring.refactoringName, 'Rename Top-Level Function'); +- expect(refactoring.elementKindName, 'function'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- await assertSuccessfulRefactoring(''' +-import 'foo.dart'; +-main() { +- print(newName); +- print(newName()); +- foo(); +-} +-'''); +- assertFileChangeResult('/foo.dart', ''' +-newName() {} +-foo() {} +-'''); +- } +- +- test_createChange_PropertyAccessorElement_getter_declaration() async { +- await _test_createChange_PropertyAccessorElement("test {}"); +- } +- +- test_createChange_PropertyAccessorElement_getter_usage() async { +- await _test_createChange_PropertyAccessorElement("test);"); +- } +- +- test_createChange_PropertyAccessorElement_mix() async { +- await _test_createChange_PropertyAccessorElement("test += 2"); +- } +- +- test_createChange_PropertyAccessorElement_setter_declaration() async { +- await _test_createChange_PropertyAccessorElement("test(x) {}"); +- } +- +- test_createChange_PropertyAccessorElement_setter_usage() async { +- await _test_createChange_PropertyAccessorElement("test = 1"); +- } +- +- test_createChange_TopLevelVariableElement_field() async { +- await _test_createChange_TopLevelVariableElement("test = 0"); +- } +- +- test_createChange_TopLevelVariableElement_getter() async { +- await _test_createChange_TopLevelVariableElement("test);"); +- } +- +- test_createChange_TopLevelVariableElement_mix() async { +- await _test_createChange_TopLevelVariableElement("test += 2"); +- } +- +- test_createChange_TopLevelVariableElement_setter() async { +- await _test_createChange_TopLevelVariableElement("test = 1"); +- } +- +- _test_createChange_PropertyAccessorElement(String search) async { +- await indexTestUnit(''' +-get test {} +-set test(x) {} +-main() { +- print(test); +- test = 1; +- test += 2; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString(search); +- expect(refactoring.refactoringName, 'Rename Top-Level Variable'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-get newName {} +-set newName(x) {} +-main() { +- print(newName); +- newName = 1; +- newName += 2; +-} +-'''); +- } +- +- _test_createChange_TopLevelVariableElement(String search) async { +- await indexTestUnit(''' +-int test = 0; +-main() { +- print(test); +- test = 1; +- test += 2; +-} +-'''); +- // configure refactoring +- createRenameRefactoringAtString(search); +- expect(refactoring.refactoringName, 'Rename Top-Level Variable'); +- expect(refactoring.elementKindName, 'top level variable'); +- expect(refactoring.oldName, 'test'); +- refactoring.newName = 'newName'; +- // validate change +- return assertSuccessfulRefactoring(''' +-int newName = 0; +-main() { +- print(newName); +- newName = 1; +- newName += 2; +-} +-'''); +- } +-} +diff --git a/pkg/analysis_server/test/services/refactoring/test_all.dart b/pkg/analysis_server/test/services/refactoring/test_all.dart +deleted file mode 100644 +index b845a983e45..00000000000 +--- a/pkg/analysis_server/test/services/refactoring/test_all.dart ++++ /dev/null +@@ -1,40 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'convert_getter_to_method_test.dart' as convert_getter_to_method_test; +-import 'convert_method_to_getter_test.dart' as convert_method_to_getter_test; +-import 'extract_local_test.dart' as extract_local_test; +-import 'extract_method_test.dart' as extract_method_test; +-import 'inline_local_test.dart' as inline_local_test; +-import 'inline_method_test.dart' as inline_method_test; +-import 'naming_conventions_test.dart' as naming_conventions_test; +-import 'rename_class_member_test.dart' as rename_class_member_test; +-import 'rename_constructor_test.dart' as rename_constructor_test; +-import 'rename_import_test.dart' as rename_import_test; +-import 'rename_label_test.dart' as rename_label_test; +-import 'rename_library_test.dart' as rename_library_test; +-import 'rename_local_test.dart' as rename_local_test; +-import 'rename_unit_member_test.dart' as rename_unit_member_test; +- +-/// Utility for manually running all tests. +-main() { +- defineReflectiveSuite(() { +- convert_getter_to_method_test.main(); +- convert_method_to_getter_test.main(); +- extract_local_test.main(); +- extract_method_test.main(); +- inline_local_test.main(); +- inline_method_test.main(); +- naming_conventions_test.main(); +- rename_class_member_test.main(); +- rename_constructor_test.main(); +- rename_import_test.main(); +- rename_label_test.main(); +- rename_library_test.main(); +- rename_local_test.main(); +- rename_unit_member_test.main(); +- }, name: 'refactoring'); +-} +diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart +deleted file mode 100644 +index d81893de9d0..00000000000 +--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart ++++ /dev/null +@@ -1,362 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/src/services/search/hierarchy.dart'; +-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(HierarchyTest); +- }); +-} +- +-@reflectiveTest +-class HierarchyTest extends AbstractSingleUnitTest { +- SearchEngineImpl searchEngine; +- +- void setUp() { +- super.setUp(); +- searchEngine = new SearchEngineImpl([driver]); +- } +- +- test_getClassMembers() async { +- await _indexTestUnit(''' +-class A { +- A() {} +- var ma1; +- ma2() {} +-} +-class B extends A { +- B() {} +- B.named() {} +- var mb1; +- mb2() {} +-} +-'''); +- { +- ClassElement classA = findElement('A'); +- List members = getClassMembers(classA); +- expect(members.map((e) => e.name), unorderedEquals(['ma1', 'ma2'])); +- } +- { +- ClassElement classB = findElement('B'); +- List members = getClassMembers(classB); +- expect(members.map((e) => e.name), unorderedEquals(['mb1', 'mb2'])); +- } +- } +- +- test_getHierarchyMembers_constructors() async { +- await _indexTestUnit(''' +-class A { +- A() {} +-} +-class B extends A { +- B() {} +-} +-'''); +- ClassElement classA = findElement("A"); +- ClassElement classB = findElement("B"); +- ClassMemberElement memberA = classA.constructors[0]; +- ClassMemberElement memberB = classB.constructors[0]; +- var futureA = getHierarchyMembers(searchEngine, memberA).then((members) { +- expect(members, unorderedEquals([memberA])); +- }); +- var futureB = getHierarchyMembers(searchEngine, memberB).then((members) { +- expect(members, unorderedEquals([memberB])); +- }); +- return Future.wait([futureA, futureB]); +- } +- +- test_getHierarchyMembers_fields() async { +- await _indexTestUnit(''' +-class A { +- int foo; +-} +-class B extends A { +- get foo => null; +-} +-class C extends B { +- set foo(x) {} +-} +-class D { +- int foo; +-} +-'''); +- ClassElement classA = findElement("A"); +- ClassElement classB = findElement("B"); +- ClassElement classC = findElement("C"); +- ClassElement classD = findElement("D"); +- ClassMemberElement memberA = classA.fields[0]; +- ClassMemberElement memberB = classB.fields[0]; +- ClassMemberElement memberC = classC.fields[0]; +- ClassMemberElement memberD = classD.fields[0]; +- var futureA = getHierarchyMembers(searchEngine, memberA).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberC])); +- }); +- var futureB = getHierarchyMembers(searchEngine, memberB).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberC])); +- }); +- var futureC = getHierarchyMembers(searchEngine, memberC).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberC])); +- }); +- var futureD = getHierarchyMembers(searchEngine, memberD).then((members) { +- expect(members, unorderedEquals([memberD])); +- }); +- return Future.wait([futureA, futureB, futureC, futureD]); +- } +- +- test_getHierarchyMembers_fields_static() async { +- await _indexTestUnit(''' +-class A { +- static int foo; +-} +-class B extends A { +- static get foo => null; +-} +-class C extends B { +- static set foo(x) {} +-} +-'''); +- ClassElement classA = findElement('A'); +- ClassElement classB = findElement('B'); +- ClassElement classC = findElement('C'); +- ClassMemberElement memberA = classA.fields[0]; +- ClassMemberElement memberB = classB.fields[0]; +- ClassMemberElement memberC = classC.fields[0]; +- { +- Set members = +- await getHierarchyMembers(searchEngine, memberA); +- expect(members, unorderedEquals([memberA])); +- } +- { +- Set members = +- await getHierarchyMembers(searchEngine, memberB); +- expect(members, unorderedEquals([memberB])); +- } +- { +- Set members = +- await getHierarchyMembers(searchEngine, memberC); +- expect(members, unorderedEquals([memberC])); +- } +- } +- +- test_getHierarchyMembers_methods() async { +- await _indexTestUnit(''' +-class A { +- foo() {} +-} +-class B extends A { +- foo() {} +-} +-class C extends B { +- foo() {} +-} +-class D { +- foo() {} +-} +-class E extends D { +- foo() {} +-} +-'''); +- ClassElement classA = findElement("A"); +- ClassElement classB = findElement("B"); +- ClassElement classC = findElement("C"); +- ClassElement classD = findElement("D"); +- ClassElement classE = findElement("E"); +- ClassMemberElement memberA = classA.methods[0]; +- ClassMemberElement memberB = classB.methods[0]; +- ClassMemberElement memberC = classC.methods[0]; +- ClassMemberElement memberD = classD.methods[0]; +- ClassMemberElement memberE = classE.methods[0]; +- var futureA = getHierarchyMembers(searchEngine, memberA).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberC])); +- }); +- var futureB = getHierarchyMembers(searchEngine, memberB).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberC])); +- }); +- var futureC = getHierarchyMembers(searchEngine, memberC).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberC])); +- }); +- var futureD = getHierarchyMembers(searchEngine, memberD).then((members) { +- expect(members, unorderedEquals([memberD, memberE])); +- }); +- var futureE = getHierarchyMembers(searchEngine, memberE).then((members) { +- expect(members, unorderedEquals([memberD, memberE])); +- }); +- return Future.wait([futureA, futureB, futureC, futureD, futureE]); +- } +- +- test_getHierarchyMembers_methods_static() async { +- await _indexTestUnit(''' +-class A { +- static foo() {} +-} +-class B extends A { +- static foo() {} +-} +-'''); +- ClassElement classA = findElement('A'); +- ClassElement classB = findElement('B'); +- ClassMemberElement memberA = classA.methods[0]; +- ClassMemberElement memberB = classB.methods[0]; +- { +- Set members = +- await getHierarchyMembers(searchEngine, memberA); +- expect(members, unorderedEquals([memberA])); +- } +- { +- Set members = +- await getHierarchyMembers(searchEngine, memberB); +- expect(members, unorderedEquals([memberB])); +- } +- } +- +- test_getHierarchyMembers_withInterfaces() async { +- await _indexTestUnit(''' +-class A { +- foo() {} +-} +-class B implements A { +- foo() {} +-} +-abstract class C implements A { +-} +-class D extends C { +- foo() {} +-} +-class E { +- foo() {} +-} +-'''); +- ClassElement classA = findElement("A"); +- ClassElement classB = findElement("B"); +- ClassElement classD = findElement("D"); +- ClassMemberElement memberA = classA.methods[0]; +- ClassMemberElement memberB = classB.methods[0]; +- ClassMemberElement memberD = classD.methods[0]; +- var futureA = getHierarchyMembers(searchEngine, memberA).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberD])); +- }); +- var futureB = getHierarchyMembers(searchEngine, memberB).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberD])); +- }); +- var futureD = getHierarchyMembers(searchEngine, memberD).then((members) { +- expect(members, unorderedEquals([memberA, memberB, memberD])); +- }); +- return Future.wait([futureA, futureB, futureD]); +- } +- +- test_getMembers() async { +- await _indexTestUnit(''' +-class A { +- A() {} +- var ma1; +- ma2() {} +-} +-class B extends A { +- B() {} +- B.named() {} +- var mb1; +- mb2() {} +-} +-'''); +- { +- ClassElement classA = findElement('A'); +- List members = getMembers(classA); +- expect( +- members.map((e) => e.name), +- unorderedEquals([ +- 'ma1', +- 'ma2', +- '==', +- 'toString', +- 'hashCode', +- 'noSuchMethod', +- 'runtimeType' +- ])); +- } +- { +- ClassElement classB = findElement('B'); +- List members = getMembers(classB); +- expect( +- members.map((e) => e.name), +- unorderedEquals([ +- 'mb1', +- 'mb2', +- 'ma1', +- 'ma2', +- '==', +- 'toString', +- 'hashCode', +- 'noSuchMethod', +- 'runtimeType' +- ])); +- } +- } +- +- test_getSuperClasses() async { +- await _indexTestUnit(''' +-class A {} +-class B extends A {} +-class C extends B {} +-class D extends B implements A {} +-class M {} +-class E extends A with M {} +-class F implements A {} +-'''); +- ClassElement classA = findElement("A"); +- ClassElement classB = findElement("B"); +- ClassElement classC = findElement("C"); +- ClassElement classD = findElement("D"); +- ClassElement classE = findElement("E"); +- ClassElement classF = findElement("F"); +- ClassElement objectElement = classA.supertype.element; +- // Object +- { +- Set supers = getSuperClasses(objectElement); +- expect(supers, isEmpty); +- } +- // A +- { +- Set supers = getSuperClasses(classA); +- expect(supers, unorderedEquals([objectElement])); +- } +- // B +- { +- Set supers = getSuperClasses(classB); +- expect(supers, unorderedEquals([objectElement, classA])); +- } +- // C +- { +- Set supers = getSuperClasses(classC); +- expect(supers, unorderedEquals([objectElement, classA, classB])); +- } +- // D +- { +- Set supers = getSuperClasses(classD); +- expect(supers, unorderedEquals([objectElement, classA, classB])); +- } +- // E +- { +- Set supers = getSuperClasses(classE); +- expect(supers, unorderedEquals([objectElement, classA])); +- } +- // F +- { +- Set supers = getSuperClasses(classF); +- expect(supers, unorderedEquals([objectElement, classA])); +- } +- } +- +- Future _indexTestUnit(String code) async { +- await resolveTestUnit(code); +- } +-} +diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart +deleted file mode 100644 +index 7f65d45ce60..00000000000 +--- a/pkg/analysis_server/test/services/search/search_engine_test.dart ++++ /dev/null +@@ -1,422 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +- +-import 'package:analysis_server/src/services/search/search_engine.dart'; +-import 'package:analysis_server/src/services/search/search_engine_internal.dart'; +-import 'package:analyzer/dart/element/element.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/file_state.dart'; +-import 'package:analyzer/src/generated/engine.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:front_end/byte_store.dart'; +-import 'package:front_end/src/base/performance_logger.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../mock_sdk.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(SearchEngineImpl2Test); +- }); +-} +- +-@reflectiveTest +-class SearchEngineImpl2Test { +- final MemoryResourceProvider provider = new MemoryResourceProvider(); +- DartSdk sdk; +- final ByteStore byteStore = new MemoryByteStore(); +- final FileContentOverlay contentOverlay = new FileContentOverlay(); +- +- final StringBuffer logBuffer = new StringBuffer(); +- PerformanceLog logger; +- +- AnalysisDriverScheduler scheduler; +- +- void setUp() { +- sdk = new MockSdk(resourceProvider: provider); +- logger = new PerformanceLog(logBuffer); +- scheduler = new AnalysisDriverScheduler(logger); +- scheduler.start(); +- } +- +- test_membersOfSubtypes_hasMembers() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- var c = _p('/test/c.dart'); +- +- provider.newFile(a, ''' +-class A { +- void a() {} +- void b() {} +- void c() {} +-} +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-class B extends A { +- void a() {} +-} +-'''); +- provider.newFile(c, ''' +-import 'a.dart'; +-class C extends A { +- void b() {} +-} +-'''); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- driver2.addFile(c); +- await scheduler.waitForIdle(); +- +- var resultA = await driver1.getResult(a); +- ClassElement elementA = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- Set members = await searchEngine.membersOfSubtypes(elementA); +- expect(members, unorderedEquals(['a', 'b'])); +- } +- +- test_membersOfSubtypes_noMembers() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class A { +- void a() {} +- void b() {} +- void c() {} +-} +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-class B extends A {} +-'''); +- +- var driver = _newDriver(); +- +- driver.addFile(a); +- driver.addFile(b); +- await scheduler.waitForIdle(); +- +- var resultA = await driver.getResult(a); +- ClassElement elementA = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver]); +- Set members = await searchEngine.membersOfSubtypes(elementA); +- expect(members, isEmpty); +- } +- +- test_membersOfSubtypes_noSubtypes() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class A { +- void a() {} +- void b() {} +- void c() {} +-} +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-class B { +- void a() {} +-} +-'''); +- +- var driver = _newDriver(); +- +- driver.addFile(a); +- driver.addFile(b); +- await scheduler.waitForIdle(); +- +- var resultA = await driver.getResult(a); +- ClassElement elementA = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver]); +- Set members = await searchEngine.membersOfSubtypes(elementA); +- expect(members, isNull); +- } +- +- test_membersOfSubtypes_private() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class A { +- void a() {} +- void _b() {} +- void _c() {} +-} +-class B extends A { +- void _b() {} +-} +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-class C extends A { +- void a() {} +- void _c() {} +-} +-class D extends B { +- void _c() {} +-} +-'''); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- await scheduler.waitForIdle(); +- +- var resultA = await driver1.getResult(a); +- ClassElement elementA = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- Set members = await searchEngine.membersOfSubtypes(elementA); +- expect(members, unorderedEquals(['a', '_b'])); +- } +- +- test_searchAllSubtypes() async { +- var p = _p('/test.dart'); +- +- provider.newFile(p, ''' +-class T {} +-class A extends T {} +-class B extends A {} +-class C implements B {} +-'''); +- +- var driver = _newDriver(); +- driver.addFile(p); +- +- var resultA = await driver.getResult(p); +- ClassElement element = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver]); +- Set subtypes = await searchEngine.searchAllSubtypes(element); +- expect(subtypes, hasLength(3)); +- expect(subtypes, contains(predicate((ClassElement e) => e.name == 'A'))); +- expect(subtypes, contains(predicate((ClassElement e) => e.name == 'B'))); +- expect(subtypes, contains(predicate((ClassElement e) => e.name == 'C'))); +- } +- +- test_searchAllSubtypes_acrossDrivers() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class T {} +-class A extends T {} +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-class B extends A {} +-class C extends B {} +-'''); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- +- var resultA = await driver1.getResult(a); +- ClassElement element = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- Set subtypes = await searchEngine.searchAllSubtypes(element); +- expect(subtypes, hasLength(3)); +- expect(subtypes, contains(predicate((ClassElement e) => e.name == 'A'))); +- expect(subtypes, contains(predicate((ClassElement e) => e.name == 'B'))); +- expect(subtypes, contains(predicate((ClassElement e) => e.name == 'C'))); +- } +- +- test_searchMemberDeclarations() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- var codeA = ''' +-class A { +- int test; // 1 +- int testTwo; +-} +-'''; +- var codeB = ''' +-class B { +- void test() {} // 2 +- void testTwo() {} +-} +-int test; +-'''; +- +- provider.newFile(a, codeA); +- provider.newFile(b, codeB); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- +- while (scheduler.isAnalyzing) { +- await new Future.delayed(new Duration(milliseconds: 1)); +- } +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- List matches = +- await searchEngine.searchMemberDeclarations('test'); +- expect(matches, hasLength(2)); +- +- void assertHasElement(String name, int nameOffset) { +- expect( +- matches, +- contains(predicate((SearchMatch m) => +- m.kind == MatchKind.DECLARATION && +- m.element.name == name && +- m.element.nameOffset == nameOffset))); +- } +- +- assertHasElement('test', codeA.indexOf('test; // 1')); +- assertHasElement('test', codeB.indexOf('test() {} // 2')); +- } +- +- test_searchMemberReferences() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class A { +- int test; +-} +-foo(p) { +- p.test; +-} +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-bar(p) { +- p.test = 1; +-} +-'''); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- List matches = +- await searchEngine.searchMemberReferences('test'); +- expect(matches, hasLength(2)); +- expect( +- matches, +- contains(predicate((SearchMatch m) => +- m.element.name == 'foo' || m.kind == MatchKind.READ))); +- expect( +- matches, +- contains(predicate((SearchMatch m) => +- m.element.name == 'bar' || m.kind == MatchKind.WRITE))); +- } +- +- test_searchReferences() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class T {} +-T a; +-'''); +- provider.newFile(b, ''' +-import 'a.dart'; +-T b; +-'''); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- +- var resultA = await driver1.getResult(a); +- ClassElement element = resultA.unit.element.types[0]; +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- List matches = await searchEngine.searchReferences(element); +- expect(matches, hasLength(2)); +- expect( +- matches, contains(predicate((SearchMatch m) => m.element.name == 'a'))); +- expect( +- matches, contains(predicate((SearchMatch m) => m.element.name == 'b'))); +- } +- +- test_searchTopLevelDeclarations() async { +- var a = _p('/test/a.dart'); +- var b = _p('/test/b.dart'); +- +- provider.newFile(a, ''' +-class A {} +-int a; +-'''); +- provider.newFile(b, ''' +-class B {} +-get b => 42; +-'''); +- +- var driver1 = _newDriver(); +- var driver2 = _newDriver(); +- +- driver1.addFile(a); +- driver2.addFile(b); +- +- while (scheduler.isAnalyzing) { +- await new Future.delayed(new Duration(milliseconds: 1)); +- } +- +- var searchEngine = new SearchEngineImpl([driver1, driver2]); +- List matches = +- await searchEngine.searchTopLevelDeclarations('.*'); +- expect( +- matches.where((match) => !match.libraryElement.isInSdk), hasLength(4)); +- +- void assertHasElement(String name) { +- expect( +- matches, +- contains(predicate((SearchMatch m) => +- m.kind == MatchKind.DECLARATION && m.element.name == name))); +- } +- +- assertHasElement('A'); +- assertHasElement('a'); +- assertHasElement('B'); +- assertHasElement('b'); +- } +- +- AnalysisDriver _newDriver() => new AnalysisDriver( +- scheduler, +- logger, +- provider, +- byteStore, +- contentOverlay, +- null, +- new SourceFactory( +- [new DartUriResolver(sdk), new ResourceUriResolver(provider)], +- null, +- provider), +- new AnalysisOptionsImpl()..strongMode = true); +- +- String _p(String path) => provider.convertPath(path); +-} +diff --git a/pkg/analysis_server/test/services/search/test_all.dart b/pkg/analysis_server/test/services/search/test_all.dart +deleted file mode 100644 +index 0bc46de88e2..00000000000 +--- a/pkg/analysis_server/test/services/search/test_all.dart ++++ /dev/null +@@ -1,18 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'hierarchy_test.dart' as hierarchy_test; +-import 'search_engine_test.dart' as search_engine_test; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- defineReflectiveSuite(() { +- hierarchy_test.main(); +- search_engine_test.main(); +- }, name: 'search'); +-} +diff --git a/pkg/analysis_server/test/services/test_all.dart b/pkg/analysis_server/test/services/test_all.dart +deleted file mode 100644 +index 2d77c254c4a..00000000000 +--- a/pkg/analysis_server/test/services/test_all.dart ++++ /dev/null +@@ -1,21 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'completion/test_all.dart' as completion_all; +-import 'correction/test_all.dart' as correction_all; +-import 'linter/test_all.dart' as linter_all; +-import 'refactoring/test_all.dart' as refactoring_all; +-import 'search/test_all.dart' as search_all; +- +-main() { +- defineReflectiveSuite(() { +- completion_all.main(); +- correction_all.main(); +- linter_all.main(); +- refactoring_all.main(); +- search_all.main(); +- }); +-} +diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart +deleted file mode 100644 +index 244e7c86f08..00000000000 +--- a/pkg/analysis_server/test/socket_server_test.dart ++++ /dev/null +@@ -1,142 +0,0 @@ +-// Copyright (c) 2014, 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 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_constants.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/analysis_server.dart'; +-import 'package:analysis_server/src/socket_server.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer/src/dart/sdk/sdk.dart'; +-import 'package:analyzer/src/generated/sdk.dart'; +-import 'package:test/test.dart'; +- +-import 'mocks.dart'; +- +-main() { +- group('SocketServer', () { +- test('createAnalysisServer_successful', +- SocketServerTest.createAnalysisServer_successful); +- test('createAnalysisServer_alreadyStarted', +- SocketServerTest.createAnalysisServer_alreadyStarted); +- test('requestHandler_exception', SocketServerTest.requestHandler_exception); +- test('requestHandler_futureException', +- SocketServerTest.requestHandler_futureException); +- }); +-} +- +-class SocketServerTest { +- static void createAnalysisServer_alreadyStarted() { +- SocketServer server = _createSocketServer(); +- MockServerChannel channel1 = new MockServerChannel(); +- MockServerChannel channel2 = new MockServerChannel(); +- server.createAnalysisServer(channel1); +- expect( +- channel1.notificationsReceived[0].event, SERVER_NOTIFICATION_CONNECTED); +- server.createAnalysisServer(channel2); +- channel1.expectMsgCount(notificationCount: 1); +- channel2.expectMsgCount(responseCount: 1); +- expect(channel2.responsesReceived[0].id, equals('')); +- expect(channel2.responsesReceived[0].error, isNotNull); +- expect(channel2.responsesReceived[0].error.code, +- equals(RequestErrorCode.SERVER_ALREADY_STARTED)); +- channel2 +- .sendRequest(new ServerShutdownParams().toRequest('0')) +- .then((Response response) { +- expect(response.id, equals('0')); +- expect(response.error, isNotNull); +- expect( +- response.error.code, equals(RequestErrorCode.SERVER_ALREADY_STARTED)); +- channel2.expectMsgCount(responseCount: 2); +- }); +- } +- +- static Future createAnalysisServer_successful() { +- SocketServer server = _createSocketServer(); +- MockServerChannel channel = new MockServerChannel(); +- server.createAnalysisServer(channel); +- channel.expectMsgCount(notificationCount: 1); +- expect( +- channel.notificationsReceived[0].event, SERVER_NOTIFICATION_CONNECTED); +- return channel +- .sendRequest(new ServerShutdownParams().toRequest('0')) +- .then((Response response) { +- expect(response.id, equals('0')); +- expect(response.error, isNull); +- channel.expectMsgCount(responseCount: 1, notificationCount: 1); +- }); +- } +- +- static Future requestHandler_exception() { +- SocketServer server = _createSocketServer(); +- MockServerChannel channel = new MockServerChannel(); +- server.createAnalysisServer(channel); +- channel.expectMsgCount(notificationCount: 1); +- expect( +- channel.notificationsReceived[0].event, SERVER_NOTIFICATION_CONNECTED); +- _MockRequestHandler handler = new _MockRequestHandler(false); +- server.analysisServer.handlers = [handler]; +- var request = new ServerGetVersionParams().toRequest('0'); +- return channel.sendRequest(request).then((Response response) { +- expect(response.id, equals('0')); +- expect(response.error, isNotNull); +- expect(response.error.code, equals(RequestErrorCode.SERVER_ERROR)); +- expect(response.error.message, equals('mock request exception')); +- expect(response.error.stackTrace, isNotNull); +- expect(response.error.stackTrace, isNotEmpty); +- channel.expectMsgCount(responseCount: 1, notificationCount: 1); +- }); +- } +- +- static Future requestHandler_futureException() { +- SocketServer server = _createSocketServer(); +- MockServerChannel channel = new MockServerChannel(); +- server.createAnalysisServer(channel); +- _MockRequestHandler handler = new _MockRequestHandler(true); +- server.analysisServer.handlers = [handler]; +- var request = new ServerGetVersionParams().toRequest('0'); +- return channel.sendRequest(request).then((Response response) { +- expect(response.id, equals('0')); +- expect(response.error, isNull); +- channel.expectMsgCount(responseCount: 1, notificationCount: 2); +- expect(channel.notificationsReceived[1].event, SERVER_NOTIFICATION_ERROR); +- }); +- } +- +- static SocketServer _createSocketServer() { +- PhysicalResourceProvider resourceProvider = +- PhysicalResourceProvider.INSTANCE; +- return new SocketServer( +- new AnalysisServerOptions(), +- new DartSdkManager('', false), +- new FolderBasedDartSdk(resourceProvider, +- FolderBasedDartSdk.defaultSdkDirectory(resourceProvider)), +- InstrumentationService.NULL_SERVICE, +- null, +- null, +- null); +- } +-} +- +-class _MockRequestHandler implements RequestHandler { +- final bool futureException; +- +- _MockRequestHandler(this.futureException); +- +- @override +- Response handleRequest(Request request) { +- if (futureException) { +- new Future(throwException); +- return new Response(request.id); +- } +- throw 'mock request exception'; +- } +- +- void throwException() { +- throw 'mock future exception'; +- } +-} +diff --git a/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart b/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart +deleted file mode 100644 +index 533d072a61c..00000000000 +--- a/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart ++++ /dev/null +@@ -1,346 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/computer/computer_closingLabels.dart'; +-import 'package:analyzer/dart/analysis/results.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_context.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ClosingLabelsComputerTest); +- }); +-} +- +-@reflectiveTest +-class ClosingLabelsComputerTest extends AbstractContextTest { +- String sourcePath; +- +- setUp() { +- super.setUp(); +- sourcePath = provider.convertPath('/p/lib/source.dart'); +- } +- +- test_adjacentLinesExcluded() async { +- String content = """ +-void myMethod() { +- return /*1*/new Thing(1, +- 2)/*1:Thing*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- /// When constructors span many like this, the node's start position is on the first line +- /// of the expression and not where the opening paren is, so this test ensures we +- /// don't end up with lots of unwanted labels on each line here. +- test_chainedConstructorOverManyLines() async { +- String content = """ +-main() { +- return new thing +- .whatIsSplit +- .acrossManyLines(1, 2); +-} +- """; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 0); +- } +- +- /// When chaining methods like this, the node's start position is on the first line +- /// of the expression and not where the opening paren is, so this test ensures we +- /// don't end up with lots of unwanted labels on each line here. +- test_chainedMethodsOverManyLines() async { +- String content = """ +-List compute() { +- _unit.accept(new _DartUnitClosingLabelsComputerVisitor(this)); +- return _closingLabelsByEndLine.values +- .where((l) => l.any((cl) => cl.spannedLines >= 2)) +- .expand((cls) => cls) +- .map((clwlc) => clwlc.label) +- .toList(); +-} +- """; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 0); +- } +- +- test_constConstructor() async { +- String content = """ +-void myMethod() { +- return /*1*/const Class( +- 1, +- 2 +- )/*1:Class*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_constNamedConstructor() async { +- String content = """ +-void myMethod() { +- return /*1*/const Class.fromThing( +- 1, +- 2 +- )/*1:Class.fromThing*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_knownBadCode1() async { +- // This code crashed during testing when I accidentally inserted a test snippet. +- String content = """ +-@override +-Widget build(BuildContext context) { +- new SliverGrid( +- gridDelegate: gridDelegate, +- delegate: myMethod([ +- "a", +- 'b', +- "c", +- ]), +- ), +- ), +- ], +- ), +- ); +-} +-"""; +- +- // TODO(dantup) Results here are currently bad so this test is just checking +- // that we don't crash. Need to confirm what to do here; the bad labels +- // might not be fixed until the code is using the new shared parser. +- // https://github.com/dart-lang/sdk/issues/30370 +- await _computeElements(content); +- } +- +- test_listLiterals() async { +- String content = """ +-void myMethod() { +- return Widget.createWidget(/*1*/[ +- 1, +- 2 +- ]/*1:[]*/); +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- /// When a line contains the end of a label, we need to ensure we also include any +- /// other labels that end on the same line, even if they are 1-2 lines, otherwise +- /// it isn't obvious which closing bracket goes with the label. +- test_mixedLineSpanning() async { +- String content = """ +-main() { +- /*1*/new Foo((m) { +- /*2*/new Bar( +- labels, +- /*3*/new Padding( +- new ClosingLabel(expectedStart, expectedLength, expectedLabel))/*3:Padding*/)/*2:Bar*/; +- })/*1:Foo*/; +- } +-} +- """; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 3); +- } +- +- test_multipleNested() async { +- String content = """ +-Widget build(BuildContext context) { +- return /*1*/new Row( +- children: /*2*/[ +- /*3*/new RaisedButton( +- onPressed: increment, +- child: /*4*/new Text( +- 'Increment' +- )/*4:Text*/, +- )/*3:RaisedButton*/, +- _makeWidget( +- 'a', +- 'b' +- ), +- new Text('Count: \$counter'), +- ]/*2:[]*/, +- )/*1:Row*/; +-} +-"""; +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 4); +- } +- +- test_newConstructor() async { +- String content = """ +-void myMethod() { +- return /*1*/new Class( +- 1, +- 2 +- )/*1:Class*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_newNamedConstructor() async { +- String content = """ +-void myMethod() { +- return /*1*/new Class.fromThing( +- 1, +- 2 +- )/*1:Class.fromThing*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_NoLabelsFromInterpolatedStrings() async { +- String content = """ +-void main(HighlightRegionType type, int offset, int length) { +- /*1*/new Fail( +- 'Not expected to find (offset=\$offset; length=\$length; type=\$type) in\\n' +- '\${regions.join('\\n')}')/*1:Fail*/; +-} +- """; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_prefixedConstConstructor() async { +- String content = """ +-import 'dart:async' as a; +-void myMethod() { +- return /*1*/const a.Future( +- 1, +- 2 +- )/*1:a.Future*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_prefixedConstNamedConstructor() async { +- String content = """ +-import 'dart:async' as a; +-void myMethod() { +- return /*1*/const a.Future.delayed( +- 1, +- 2 +- )/*1:a.Future.delayed*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_prefixedNewConstructor() async { +- String content = """ +-import 'dart:async' as a; +-void myMethod() { +- return /*1*/new a.Future( +- 1, +- 2 +- )/*1:a.Future*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_prefixedNewNamedConstructor() async { +- String content = """ +-import 'dart:async' as a; +-void myMethod() { +- return /*1*/new a.Future.delayed( +- 1, +- 2 +- )/*1:a.Future.delayed*/; +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 1); +- } +- +- test_sameLineExcluded() async { +- String content = """ +-void myMethod() { +- return new Thing(); +-} +-"""; +- +- var labels = await _computeElements(content); +- _compareLabels(labels, content, expectedLabelCount: 0); +- } +- +- /// Compares provided closing labels with expected +- /// labels extracted from the comments in the provided content. +- _compareLabels(List labels, String content, +- {int expectedLabelCount}) { +- // Require the test pass us the expected count to guard +- // against expected annotations being mistyped and not +- // extracted by the regex. +- expect(labels, hasLength(expectedLabelCount)); +- +- // Find all numeric markers for label starts. +- var regex = new RegExp("/\\*(\\d+)\\*/"); +- var expectedLabels = regex.allMatches(content); +- +- // Check we didn't get more than expected, since the loop below only +- // checks for the presence of matches, not absence. +- expect(labels, hasLength(expectedLabels.length)); +- +- // Go through each marker, find the expected label/end and +- // ensure it's in the results. +- expectedLabels.forEach((m) { +- var i = m.group(1); +- // Find the end marker. +- var endMatch = new RegExp("/\\*$i:(.+?)\\*/").firstMatch(content); +- +- var expectedStart = m.end; +- var expectedLength = endMatch.start - expectedStart; +- var expectedLabel = endMatch.group(1); +- +- expect( +- labels, +- contains( +- new ClosingLabel(expectedStart, expectedLength, expectedLabel))); +- }); +- } +- +- Future> _computeElements(String sourceContent) async { +- provider.newFile(sourcePath, sourceContent); +- ResolveResult result = await driver.getResult(sourcePath); +- DartUnitClosingLabelsComputer computer = +- new DartUnitClosingLabelsComputer(result.lineInfo, result.unit); +- return computer.compute(); +- } +-} +diff --git a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart +deleted file mode 100644 +index 63d54320ca9..00000000000 +--- a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart ++++ /dev/null +@@ -1,343 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/computer/import_elements_computer.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:front_end/src/base/source.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_context.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ImportElementsComputerTest); +- }); +-} +- +-@reflectiveTest +-class ImportElementsComputerTest extends AbstractContextTest { +- String path; +- String originalContent; +- ImportElementsComputer computer; +- SourceFileEdit sourceFileEdit; +- +- void assertChanges(String expectedContent) { +- String resultCode = +- SourceEdit.applySequence(originalContent, sourceFileEdit.edits); +- expect(resultCode, expectedContent); +- } +- +- void assertNoChanges() { +- expect(sourceFileEdit.edits, isEmpty); +- } +- +- Future computeChanges(List importedElements) async { +- SourceChange change = await computer.createEdits(importedElements); +- expect(change, isNotNull); +- List edits = change.edits; +- expect(edits, hasLength(1)); +- sourceFileEdit = edits[0]; +- expect(sourceFileEdit, isNotNull); +- } +- +- Future createBuilder(String content) async { +- originalContent = content; +- provider.newFile(path, content); +- AnalysisResult result = await driver.getResult(path); +- computer = new ImportElementsComputer(provider, result); +- } +- +- void setUp() { +- super.setUp(); +- path = provider.convertPath('/test.dart'); +- } +- +- test_createEdits_addImport_noDirectives() async { +- await createBuilder(''' +-main() { +- // paste here +-} +-'''); +- await computeChanges([ +- new ImportedElements('/lib/math/math.dart', '', ['Random']) +- ]); +- assertChanges(''' +-import 'dart:math'; +- +-main() { +- // paste here +-} +-'''); +- } +- +- test_createEdits_addImport_noPrefix() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' as foo; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' as foo; +-import 'package:pkg/foo.dart'; +-'''); +- } +- +- test_createEdits_addImport_prefix() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart'; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, 'foo', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart'; +-import 'package:pkg/foo.dart' as foo; +-'''); +- } +- +- test_createEdits_addShow_multipleNames() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' show B; +-import 'package:pkg/foo.dart' as foo; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A', 'C']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' show B, A, C; +-import 'package:pkg/foo.dart' as foo; +-'''); +- } +- +- test_createEdits_addShow_removeHide() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' show A, B hide C, D; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['C']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' show A, B, C hide D; +-'''); +- } +- +- test_createEdits_addShow_singleName_noPrefix() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' show B; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' show B, A; +-'''); +- } +- +- test_createEdits_addShow_singleName_prefix() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' show C; +-import 'package:pkg/foo.dart' as foo show B; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, 'foo', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' show C; +-import 'package:pkg/foo.dart' as foo show B, A; +-'''); +- } +- +- test_createEdits_alreadyImported_noCombinators() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart'; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A', 'B']) +- ]); +- assertNoChanges(); +- } +- +- test_createEdits_alreadyImported_withPrefix() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' as foo; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, 'foo', ['A', 'B']) +- ]); +- assertNoChanges(); +- } +- +- test_createEdits_alreadyImported_withShow() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' show A; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A']) +- ]); +- assertNoChanges(); +- } +- +- test_createEdits_importSelf() async { +- await createBuilder(''' +-class A { +- A parent; +-} +-'''); +- await computeChanges([ +- new ImportedElements(path, '', ['A']) +- ]); +- assertNoChanges(); +- } +- +- test_createEdits_noElements() async { +- await createBuilder(''); +- await computeChanges([]); +- assertNoChanges(); +- } +- +- test_createEdits_removeHide_firstInCombinator() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A, B, C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide B, C; +-'''); +- } +- +- test_createEdits_removeHide_lastInCombinator() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A, B, C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['C']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide A, B; +-'''); +- } +- +- test_createEdits_removeHide_middleInCombinator() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A, B, C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['B']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide A, C; +-'''); +- } +- +- test_createEdits_removeHide_multipleCombinators() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A, B, C hide A, B, C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['B']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide A, C hide A, C; +-'''); +- } +- +- test_createEdits_removeHide_multipleNames() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A, B, C hide D, E, F hide G, H, I; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A', 'E', 'I']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide B, C hide D, F hide G, H; +-'''); +- } +- +- test_createEdits_removeHideCombinator_first() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A hide B hide C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide B hide C; +-'''); +- } +- +- test_createEdits_removeHideCombinator_last() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A hide B hide C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['C']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide A hide B; +-'''); +- } +- +- test_createEdits_removeHideCombinator_middle() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A hide B hide C; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['B']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart' hide A hide C; +-'''); +- } +- +- test_createEdits_removeHideCombinator_only() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart'; +-'''); +- } +- +- test_createEdits_removeHideCombinator_only_multiple() async { +- Source fooSource = addPackageSource('pkg', 'foo.dart', ''); +- await createBuilder(''' +-import 'package:pkg/foo.dart' hide A, B; +-'''); +- await computeChanges([ +- new ImportedElements(fooSource.fullName, '', ['A', 'B']) +- ]); +- assertChanges(''' +-import 'package:pkg/foo.dart'; +-'''); +- } +-} +diff --git a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart +deleted file mode 100644 +index adcf5f1c35f..00000000000 +--- a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart ++++ /dev/null +@@ -1,400 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/computer/imported_elements_computer.dart'; +-import 'package:analyzer/dart/analysis/results.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_context.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ImportElementsComputerTest); +- }); +-} +- +-@reflectiveTest +-class ImportElementsComputerTest extends AbstractContextTest { +- String sourcePath; +- +- setUp() { +- super.setUp(); +- sourcePath = provider.convertPath('/p/lib/source.dart'); +- } +- +- test_dartAsync_noPrefix() async { +- String selection = "Future f = null;"; +- String content = """ +-import 'dart:async'; +-printer() { +- $selection +- print(await f); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(2)); +- ImportedElements elements1 = elementsList[0]; +- ImportedElements elements2 = elementsList[1]; +- ImportedElements asyncElements; +- ImportedElements coreElements; +- if (elements1.path == '/lib/core/core.dart') { +- coreElements = elements1; +- asyncElements = elements2; +- } else { +- coreElements = elements2; +- asyncElements = elements1; +- } +- expect(coreElements, isNotNull); +- expect(coreElements.path, '/lib/core/core.dart'); +- expect(coreElements.prefix, ''); +- expect(coreElements.elements, unorderedEquals(['String'])); +- +- expect(asyncElements, isNotNull); +- expect(asyncElements.path, '/lib/async/async.dart'); +- expect(asyncElements.prefix, ''); +- expect(asyncElements.elements, unorderedEquals(['Future'])); +- } +- +- test_dartAsync_prefix() async { +- String selection = "a.Future f = null;"; +- String content = """ +-import 'dart:async' as a; +-printer() { +- $selection +- print(await f); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(2)); +- ImportedElements elements1 = elementsList[0]; +- ImportedElements elements2 = elementsList[1]; +- ImportedElements asyncElements; +- ImportedElements coreElements; +- if (elements1.path == '/lib/core/core.dart') { +- coreElements = elements1; +- asyncElements = elements2; +- } else { +- coreElements = elements2; +- asyncElements = elements1; +- } +- expect(coreElements, isNotNull); +- expect(coreElements.path, '/lib/core/core.dart'); +- expect(coreElements.prefix, ''); +- expect(coreElements.elements, unorderedEquals(['String'])); +- +- expect(asyncElements, isNotNull); +- expect(asyncElements.path, '/lib/async/async.dart'); +- expect(asyncElements.prefix, 'a'); +- expect(asyncElements.elements, unorderedEquals(['Future'])); +- } +- +- test_dartCore_noPrefix() async { +- String selection = "String s = '';"; +- String content = """ +-blankLine() { +- $selection +- print(s); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/lib/core/core.dart'); +- expect(elements.prefix, ''); +- expect(elements.elements, unorderedEquals(['String'])); +- } +- +- test_dartCore_prefix() async { +- String selection = "core.String s = '';"; +- String content = """ +-import 'dart:core' as core; +-blankLine() { +- $selection +- print(s); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/lib/core/core.dart'); +- expect(elements.prefix, 'core'); +- expect(elements.elements, unorderedEquals(['String'])); +- } +- +- test_dartMath_noPrefix() async { +- String selection = "new Random();"; +- String content = """ +-import 'dart:math'; +-bool randomBool() { +- Random r = $selection +- return r.nextBool(); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/lib/math/math.dart'); +- expect(elements.prefix, ''); +- expect(elements.elements, unorderedEquals(['Random'])); +- } +- +- test_multiple() async { +- String selection = r''' +-main() { +- Random r = new Random(); +- String s = r.nextBool().toString(); +- print(s); +-} +-'''; +- String content = ''' +-import 'dart:math'; +- +-$selection +-'''; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(2)); +- +- ImportedElements mathElements = elementsList[0]; +- expect(mathElements, isNotNull); +- expect(mathElements.path, '/lib/math/math.dart'); +- expect(mathElements.prefix, ''); +- expect(mathElements.elements, unorderedEquals(['Random'])); +- +- ImportedElements coreElements = elementsList[1]; +- expect(coreElements, isNotNull); +- expect(coreElements.path, '/lib/core/core.dart'); +- expect(coreElements.prefix, ''); +- expect(coreElements.elements, unorderedEquals(['String', 'print'])); +- } +- +- test_none_comment() async { +- String selection = 'comment'; +- String content = """ +-// Method $selection. +-blankLine() { +- print(''); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(0)); +- } +- +- test_none_constructorDeclarationReturnType() async { +- String selection = r''' +-class A { +- A(); +- A.named(); +-} +-'''; +- String content = """ +-$selection +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(0)); +- } +- +- test_none_partialNames() async { +- String selection = 'x + y'; +- String content = """ +-plusThree(int xx) { +- int yy = 2; +- print(x${selection}y); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(0)); +- } +- +- test_none_wholeNames() async { +- String selection = 'x + y + 1'; +- String content = """ +-plusThree(int x) { +- int y = 2; +- print($selection); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(0)); +- } +- +- test_package_multipleInSame() async { +- addPackageSource('foo', 'foo.dart', ''' +-class A { +- static String a = ''; +-} +-class B { +- static String b = ''; +-} +-'''); +- String selection = "A.a + B.b"; +- String content = """ +-import 'package:foo/foo.dart'; +-blankLine() { +- print($selection); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/pubcache/foo/lib/foo.dart'); +- expect(elements.prefix, ''); +- expect(elements.elements, unorderedEquals(['A', 'B'])); +- } +- +- test_package_noPrefix() async { +- addPackageSource('foo', 'foo.dart', ''' +-class Foo { +- static String first = ''; +-} +-'''); +- String selection = "Foo.first"; +- String content = """ +-import 'package:foo/foo.dart'; +-blankLine() { +- print($selection); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/pubcache/foo/lib/foo.dart'); +- expect(elements.prefix, ''); +- expect(elements.elements, unorderedEquals(['Foo'])); +- } +- +- test_package_prefix_selected() async { +- addPackageSource('foo', 'foo.dart', ''' +-class Foo { +- static String first = ''; +-} +-'''); +- String selection = "f.Foo.first"; +- String content = """ +-import 'package:foo/foo.dart' as f; +-blankLine() { +- print($selection); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/pubcache/foo/lib/foo.dart'); +- expect(elements.prefix, 'f'); +- expect(elements.elements, unorderedEquals(['Foo'])); +- } +- +- test_package_prefix_unselected() async { +- addPackageSource('foo', 'foo.dart', ''' +-class Foo { +- static String first = ''; +-} +-'''); +- String selection = "Foo.first"; +- String content = """ +-import 'package:foo/foo.dart' as f; +-blankLine() { +- print(f.$selection); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, '/pubcache/foo/lib/foo.dart'); +- expect(elements.prefix, ''); +- expect(elements.elements, unorderedEquals(['Foo'])); +- } +- +- test_package_prefixedAndNot() async { +- addPackageSource('foo', 'foo.dart', ''' +-class Foo { +- static String first = ''; +- static String second = ''; +-} +-'''); +- String selection = "f.Foo.first + Foo.second"; +- String content = """ +-import 'package:foo/foo.dart'; +-import 'package:foo/foo.dart' as f; +-blankLine() { +- print($selection); +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- +- expect(elementsList, hasLength(2)); +- ImportedElements elements1 = elementsList[0]; +- ImportedElements elements2 = elementsList[1]; +- ImportedElements notPrefixedElements; +- ImportedElements prefixedElements; +- if (elements1.prefix == '') { +- prefixedElements = elements2; +- notPrefixedElements = elements1; +- } else { +- prefixedElements = elements1; +- notPrefixedElements = elements2; +- } +- +- expect(notPrefixedElements, isNotNull); +- expect(notPrefixedElements.path, '/pubcache/foo/lib/foo.dart'); +- expect(notPrefixedElements.prefix, ''); +- expect(notPrefixedElements.elements, unorderedEquals(['Foo'])); +- +- expect(prefixedElements, isNotNull); +- expect(prefixedElements.path, '/pubcache/foo/lib/foo.dart'); +- expect(prefixedElements.prefix, 'f'); +- expect(prefixedElements.elements, unorderedEquals(['Foo'])); +- } +- +- test_self() async { +- String selection = 'A parent;'; +- String content = """ +-class A { +- $selection +-} +-"""; +- List elementsList = await _computeElements( +- content, content.indexOf(selection), selection.length); +- expect(elementsList, hasLength(1)); +- ImportedElements elements = elementsList[0]; +- expect(elements, isNotNull); +- expect(elements.path, sourcePath); +- expect(elements.prefix, ''); +- expect(elements.elements, unorderedEquals(['A'])); +- } +- +- Future> _computeElements( +- String sourceContent, int offset, int length) async { +- provider.newFile(sourcePath, sourceContent); +- ResolveResult result = await driver.getResult(sourcePath); +- ImportedElementsComputer computer = +- new ImportedElementsComputer(result.unit, offset, length); +- return computer.compute(); +- } +-} +diff --git a/pkg/analysis_server/test/src/computer/outline_computer_test.dart b/pkg/analysis_server/test/src/computer/outline_computer_test.dart +deleted file mode 100644 +index 2b887045275..00000000000 +--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart ++++ /dev/null +@@ -1,1022 +0,0 @@ +-// 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 'package:analysis_server/src/computer/computer_outline.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:meta/meta.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_context.dart'; +-import '../utilities/flutter_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FlutterOutlineComputerTest); +- defineReflectiveTests(OutlineComputerTest); +- }); +-} +- +-class AbstractOutlineComputerTest extends AbstractContextTest { +- String testPath; +- String testCode; +- +- @override +- void setUp() { +- super.setUp(); +- testPath = provider.convertPath('/test.dart'); +- } +- +- Future _computeOutline(String code) async { +- testCode = code; +- provider.newFile(testPath, code); +- AnalysisResult analysisResult = await driver.getResult(testPath); +- return new DartUnitOutlineComputer( +- testPath, analysisResult.lineInfo, analysisResult.unit) +- .compute(); +- } +-} +- +-@reflectiveTest +-class FlutterOutlineComputerTest extends AbstractOutlineComputerTest { +- @override +- void setUp() { +- super.setUp(); +- Folder libFolder = configureFlutterPackage(provider); +- packageMap['flutter'] = [libFolder]; +- } +- +- test_columnWithChildren() async { +- Outline unitOutline = await _computeOutline(''' +-import 'package:flutter/widgets.dart'; +- +-class MyWidget extends StatelessWidget { +- @override +- Widget build(BuildContext context) { +- return new Column(children: [ +- const Text('aaa'), +- const Text('bbb'), +- ]); // Column +- } +-} +-'''); +- expect(_toText(unitOutline), r''' +-MyWidget +- build +- Column +- Text('aaa') +- Text('bbb') +-'''); +- var myWidget = unitOutline.children[0]; +- var build = myWidget.children[0]; +- +- var columnOutline = build.children[0]; +- { +- int offset = testCode.indexOf('new Column'); +- int length = testCode.indexOf('; // Column') - offset; +- _expect(columnOutline, +- name: 'Column', +- elementOffset: offset, +- offset: offset, +- length: length); +- } +- +- { +- var textOutline = columnOutline.children[0]; +- String text = "const Text('aaa')"; +- int offset = testCode.indexOf(text); +- _expect(textOutline, +- name: "Text('aaa')", +- elementOffset: offset, +- offset: offset, +- length: text.length); +- } +- +- { +- var textOutline = columnOutline.children[1]; +- String text = "const Text('bbb')"; +- int offset = testCode.indexOf(text); +- _expect(textOutline, +- name: "Text('bbb')", +- elementOffset: offset, +- offset: offset, +- length: text.length); +- } +- } +- +- void _expect(Outline outline, +- {@required String name, +- @required int elementOffset, +- @required int offset, +- @required int length}) { +- Element element = outline.element; +- expect(element.name, name); +- expect(element.location.offset, elementOffset); +- expect(outline.offset, offset); +- expect(outline.length, length); +- } +- +- static String _toText(Outline outline) { +- var buffer = new StringBuffer(); +- +- void writeOutline(Outline outline, String indent) { +- buffer.write(indent); +- buffer.writeln(outline.element.name); +- for (var child in outline.children ?? const []) { +- writeOutline(child, '$indent '); +- } +- } +- +- for (var child in outline.children) { +- writeOutline(child, ''); +- } +- return buffer.toString(); +- } +-} +- +-@reflectiveTest +-class OutlineComputerTest extends AbstractOutlineComputerTest { +- test_class() async { +- Outline unitOutline = await _computeOutline(''' +-class A { +- int fa, fb; +- String fc; +- A(int i, String s); +- A.name(num p); +- A._privateName(num p); +- static String ma(int pa) => null; +- _mb(int pb); +- String get propA => null; +- set propB(int v) {} +-} +-class B { +- B(int p); +-}"); +-'''); +- List topOutlines = unitOutline.children; +- expect(topOutlines, hasLength(2)); +- // A +- { +- Outline outline_A = topOutlines[0]; +- Element element_A = outline_A.element; +- expect(element_A.kind, ElementKind.CLASS); +- expect(element_A.name, "A"); +- expect(element_A.typeParameters, ""); +- { +- Location location = element_A.location; +- expect(location.offset, testCode.indexOf("A {")); +- expect(location.length, 1); +- } +- expect(element_A.parameters, null); +- expect(element_A.returnType, null); +- // A children +- List outlines_A = outline_A.children; +- expect(outlines_A, hasLength(10)); +- { +- Outline outline = outlines_A[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fa"); +- expect(element.parameters, isNull); +- expect(element.returnType, "int"); +- } +- { +- Outline outline = outlines_A[1]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fb"); +- expect(element.parameters, isNull); +- expect(element.returnType, "int"); +- } +- { +- Outline outline = outlines_A[2]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fc"); +- expect(element.parameters, isNull); +- expect(element.returnType, "String"); +- } +- { +- Outline outline = outlines_A[3]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CONSTRUCTOR); +- expect(element.name, "A"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("A(int i, String s);")); +- expect(location.length, "A".length); +- } +- expect(element.parameters, "(int i, String s)"); +- expect(element.returnType, isNull); +- expect(element.isAbstract, isFalse); +- expect(element.isStatic, isFalse); +- } +- { +- Outline outline = outlines_A[4]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CONSTRUCTOR); +- expect(element.name, "A.name"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("name(num p);")); +- expect(location.length, "name".length); +- } +- expect(element.parameters, "(num p)"); +- expect(element.returnType, isNull); +- expect(element.isAbstract, isFalse); +- expect(element.isStatic, isFalse); +- } +- { +- Outline outline = outlines_A[5]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CONSTRUCTOR); +- expect(element.name, "A._privateName"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("_privateName(num p);")); +- expect(location.length, "_privateName".length); +- } +- expect(element.parameters, "(num p)"); +- expect(element.returnType, isNull); +- expect(element.isAbstract, isFalse); +- expect(element.isStatic, isFalse); +- } +- { +- Outline outline = outlines_A[6]; +- Element element = outline.element; +- expect(element.kind, ElementKind.METHOD); +- expect(element.name, "ma"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("ma(int pa) => null;")); +- expect(location.length, "ma".length); +- } +- expect(element.parameters, "(int pa)"); +- expect(element.returnType, "String"); +- expect(element.isAbstract, isFalse); +- expect(element.isStatic, isTrue); +- } +- { +- Outline outline = outlines_A[7]; +- Element element = outline.element; +- expect(element.kind, ElementKind.METHOD); +- expect(element.name, "_mb"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("_mb(int pb);")); +- expect(location.length, "_mb".length); +- } +- expect(element.parameters, "(int pb)"); +- expect(element.returnType, ""); +- expect(element.isAbstract, isTrue); +- expect(element.isStatic, isFalse); +- } +- { +- Outline outline = outlines_A[8]; +- Element element = outline.element; +- expect(element.kind, ElementKind.GETTER); +- expect(element.name, "propA"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("propA => null;")); +- expect(location.length, "propA".length); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, "String"); +- } +- { +- Outline outline = outlines_A[9]; +- Element element = outline.element; +- expect(element.kind, ElementKind.SETTER); +- expect(element.name, "propB"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("propB(int v) {}")); +- expect(location.length, "propB".length); +- } +- expect(element.parameters, "(int v)"); +- expect(element.returnType, ""); +- } +- } +- // B +- { +- Outline outline_B = topOutlines[1]; +- Element element_B = outline_B.element; +- expect(element_B.kind, ElementKind.CLASS); +- expect(element_B.name, "B"); +- expect(element_B.typeParameters, isNull); +- { +- Location location = element_B.location; +- expect(location.offset, testCode.indexOf("B {")); +- expect(location.length, 1); +- } +- expect(element_B.parameters, null); +- expect(element_B.returnType, null); +- // B children +- List outlines_B = outline_B.children; +- expect(outlines_B, hasLength(1)); +- { +- Outline outline = outlines_B[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CONSTRUCTOR); +- expect(element.name, "B"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("B(int p);")); +- expect(location.length, "B".length); +- } +- expect(element.parameters, "(int p)"); +- expect(element.returnType, isNull); +- } +- } +- } +- +- test_enum() async { +- Outline unitOutline = await _computeOutline(''' +-enum MyEnum { +- A, B, C +-} +-'''); +- List topOutlines = unitOutline.children; +- expect(topOutlines, hasLength(1)); +- // MyEnum +- { +- Outline outline_MyEnum = topOutlines[0]; +- Element element_MyEnum = outline_MyEnum.element; +- expect(element_MyEnum.kind, ElementKind.ENUM); +- expect(element_MyEnum.name, "MyEnum"); +- { +- Location location = element_MyEnum.location; +- expect(location.offset, testCode.indexOf("MyEnum {")); +- expect(location.length, 'MyEnum'.length); +- } +- expect(element_MyEnum.parameters, null); +- expect(element_MyEnum.returnType, null); +- // MyEnum children +- List outlines_MyEnum = outline_MyEnum.children; +- expect(outlines_MyEnum, hasLength(3)); +- _isEnumConstant(outlines_MyEnum[0], 'A'); +- _isEnumConstant(outlines_MyEnum[1], 'B'); +- _isEnumConstant(outlines_MyEnum[2], 'C'); +- } +- } +- +- test_groupAndTest() async { +- Outline outline = await _computeOutline(''' +-void group(name, closure) {} +-void test(name) {} +-void main() { +- group('group1', () { +- group('group1_1', () { +- test('test1_1_1'); +- test('test1_1_2'); +- }); +- group('group1_2', () { +- test('test1_2_1'); +- }); +- }); +- group('group2', () { +- test('test2_1'); +- test('test2_2'); +- }); +-} +-'''); +- // unit +- List unit_children = outline.children; +- expect(unit_children, hasLength(3)); +- // main +- Outline main_outline = unit_children[2]; +- _expect(main_outline, +- kind: ElementKind.FUNCTION, +- name: 'main', +- offset: testCode.indexOf("main() {"), +- parameters: '()', +- returnType: 'void'); +- List main_children = main_outline.children; +- expect(main_children, hasLength(2)); +- // group1 +- Outline group1_outline = main_children[0]; +- _expect(group1_outline, +- kind: ElementKind.UNIT_TEST_GROUP, +- length: 5, +- name: 'group("group1")', +- offset: testCode.indexOf("group('group1'")); +- List group1_children = group1_outline.children; +- expect(group1_children, hasLength(2)); +- // group1_1 +- Outline group1_1_outline = group1_children[0]; +- _expect(group1_1_outline, +- kind: ElementKind.UNIT_TEST_GROUP, +- length: 5, +- name: 'group("group1_1")', +- offset: testCode.indexOf("group('group1_1'")); +- List group1_1_children = group1_1_outline.children; +- expect(group1_1_children, hasLength(2)); +- // test1_1_1 +- Outline test1_1_1_outline = group1_1_children[0]; +- _expect(test1_1_1_outline, +- kind: ElementKind.UNIT_TEST_TEST, +- leaf: true, +- length: 4, +- name: 'test("test1_1_1")', +- offset: testCode.indexOf("test('test1_1_1'")); +- // test1_1_1 +- Outline test1_1_2_outline = group1_1_children[1]; +- _expect(test1_1_2_outline, +- kind: ElementKind.UNIT_TEST_TEST, +- leaf: true, +- length: 4, +- name: 'test("test1_1_2")', +- offset: testCode.indexOf("test('test1_1_2'")); +- // group1_2 +- Outline group1_2_outline = group1_children[1]; +- _expect(group1_2_outline, +- kind: ElementKind.UNIT_TEST_GROUP, +- length: 5, +- name: 'group("group1_2")', +- offset: testCode.indexOf("group('group1_2'")); +- List group1_2_children = group1_2_outline.children; +- expect(group1_2_children, hasLength(1)); +- // test2_1 +- Outline test1_2_1_outline = group1_2_children[0]; +- _expect(test1_2_1_outline, +- kind: ElementKind.UNIT_TEST_TEST, +- leaf: true, +- length: 4, +- name: 'test("test1_2_1")', +- offset: testCode.indexOf("test('test1_2_1'")); +- // group2 +- Outline group2_outline = main_children[1]; +- _expect(group2_outline, +- kind: ElementKind.UNIT_TEST_GROUP, +- length: 5, +- name: 'group("group2")', +- offset: testCode.indexOf("group('group2'")); +- List group2_children = group2_outline.children; +- expect(group2_children, hasLength(2)); +- // test2_1 +- Outline test2_1_outline = group2_children[0]; +- _expect(test2_1_outline, +- kind: ElementKind.UNIT_TEST_TEST, +- leaf: true, +- length: 4, +- name: 'test("test2_1")', +- offset: testCode.indexOf("test('test2_1'")); +- // test2_2 +- Outline test2_2_outline = group2_children[1]; +- _expect(test2_2_outline, +- kind: ElementKind.UNIT_TEST_TEST, +- leaf: true, +- length: 4, +- name: 'test("test2_2")', +- offset: testCode.indexOf("test('test2_2'")); +- } +- +- /** +- * Code like this caused NPE in the past. +- * +- * https://code.google.com/p/dart/issues/detail?id=21373 +- */ +- test_invalidGetterInConstructor() async { +- Outline outline = await _computeOutline(''' +-class A { +- A() { +- get badGetter { +- const int CONST = 0; +- } +- } +-} +-'''); +- expect(outline, isNotNull); +- } +- +- test_localFunctions() async { +- Outline unitOutline = await _computeOutline(''' +-class A { +- A() { +- int local_A() {} +- } +- m() { +- local_m() {} +- } +-} +-f() { +- local_f1(int i) {} +- local_f2(String s) { +- local_f21(int p) {} +- } +-} +-'''); +- List topOutlines = unitOutline.children; +- expect(topOutlines, hasLength(2)); +- // A +- { +- Outline outline_A = topOutlines[0]; +- Element element_A = outline_A.element; +- expect(element_A.kind, ElementKind.CLASS); +- expect(element_A.name, "A"); +- { +- Location location = element_A.location; +- expect(location.offset, testCode.indexOf("A {")); +- expect(location.length, "A".length); +- } +- expect(element_A.parameters, null); +- expect(element_A.returnType, null); +- // A children +- List outlines_A = outline_A.children; +- expect(outlines_A, hasLength(2)); +- { +- Outline constructorOutline = outlines_A[0]; +- Element constructorElement = constructorOutline.element; +- expect(constructorElement.kind, ElementKind.CONSTRUCTOR); +- expect(constructorElement.name, "A"); +- { +- Location location = constructorElement.location; +- expect(location.offset, testCode.indexOf("A() {")); +- expect(location.length, "A".length); +- } +- expect(constructorElement.parameters, "()"); +- expect(constructorElement.returnType, isNull); +- // local function +- List outlines_constructor = constructorOutline.children; +- expect(outlines_constructor, hasLength(1)); +- { +- Outline outline = outlines_constructor[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FUNCTION); +- expect(element.name, "local_A"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("local_A() {}")); +- expect(location.length, "local_A".length); +- } +- expect(element.parameters, "()"); +- expect(element.returnType, "int"); +- } +- } +- { +- Outline outline_m = outlines_A[1]; +- Element element_m = outline_m.element; +- expect(element_m.kind, ElementKind.METHOD); +- expect(element_m.name, "m"); +- { +- Location location = element_m.location; +- expect(location.offset, testCode.indexOf("m() {")); +- expect(location.length, "m".length); +- } +- expect(element_m.parameters, "()"); +- expect(element_m.returnType, ""); +- // local function +- List methodChildren = outline_m.children; +- expect(methodChildren, hasLength(1)); +- { +- Outline outline = methodChildren[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FUNCTION); +- expect(element.name, "local_m"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("local_m() {}")); +- expect(location.length, "local_m".length); +- } +- expect(element.parameters, "()"); +- expect(element.returnType, ""); +- } +- } +- } +- // f() +- { +- Outline outline_f = topOutlines[1]; +- Element element_f = outline_f.element; +- expect(element_f.kind, ElementKind.FUNCTION); +- expect(element_f.name, "f"); +- { +- Location location = element_f.location; +- expect(location.offset, testCode.indexOf("f() {")); +- expect(location.length, "f".length); +- } +- expect(element_f.parameters, "()"); +- expect(element_f.returnType, ""); +- // f() children +- List outlines_f = outline_f.children; +- expect(outlines_f, hasLength(2)); +- { +- Outline outline_f1 = outlines_f[0]; +- Element element_f1 = outline_f1.element; +- expect(element_f1.kind, ElementKind.FUNCTION); +- expect(element_f1.name, "local_f1"); +- { +- Location location = element_f1.location; +- expect(location.offset, testCode.indexOf("local_f1(int i) {}")); +- expect(location.length, "local_f1".length); +- } +- expect(element_f1.parameters, "(int i)"); +- expect(element_f1.returnType, ""); +- } +- { +- Outline outline_f2 = outlines_f[1]; +- Element element_f2 = outline_f2.element; +- expect(element_f2.kind, ElementKind.FUNCTION); +- expect(element_f2.name, "local_f2"); +- { +- Location location = element_f2.location; +- expect(location.offset, testCode.indexOf("local_f2(String s) {")); +- expect(location.length, "local_f2".length); +- } +- expect(element_f2.parameters, "(String s)"); +- expect(element_f2.returnType, ""); +- // local_f2() local function +- List outlines_f2 = outline_f2.children; +- expect(outlines_f2, hasLength(1)); +- { +- Outline outline_f21 = outlines_f2[0]; +- Element element_f21 = outline_f21.element; +- expect(element_f21.kind, ElementKind.FUNCTION); +- expect(element_f21.name, "local_f21"); +- { +- Location location = element_f21.location; +- expect(location.offset, testCode.indexOf("local_f21(int p) {")); +- expect(location.length, "local_f21".length); +- } +- expect(element_f21.parameters, "(int p)"); +- expect(element_f21.returnType, ""); +- } +- } +- } +- } +- +- test_sourceRange_inClass() async { +- Outline unitOutline = await _computeOutline(''' +-class A { // leftA +- int methodA() {} // endA +- int methodB() {} // endB +-} +-'''); +- List outlines = unitOutline.children[0].children; +- expect(outlines, hasLength(2)); +- // methodA +- { +- Outline outline = outlines[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.METHOD); +- expect(element.name, "methodA"); +- { +- int offset = testCode.indexOf(" // leftA"); +- int end = testCode.indexOf(" // endA"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // methodB +- { +- Outline outline = outlines[1]; +- Element element = outline.element; +- expect(element.kind, ElementKind.METHOD); +- expect(element.name, "methodB"); +- { +- int offset = testCode.indexOf(" // endA"); +- int end = testCode.indexOf(" // endB"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- } +- +- test_sourceRange_inClass_inVariableList() async { +- Outline unitOutline = await _computeOutline(''' +-class A { // leftA +- int fieldA, fieldB, fieldC; // marker +- int fieldD; // marker2 +-} +-'''); +- List outlines = unitOutline.children[0].children; +- expect(outlines, hasLength(4)); +- // fieldA +- { +- Outline outline = outlines[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fieldA"); +- { +- int offset = testCode.indexOf(" // leftA"); +- int end = testCode.indexOf(", fieldB"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // fieldB +- { +- Outline outline = outlines[1]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fieldB"); +- { +- int offset = testCode.indexOf(", fieldB"); +- int end = testCode.indexOf(", fieldC"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // fieldC +- { +- Outline outline = outlines[2]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fieldC"); +- { +- int offset = testCode.indexOf(", fieldC"); +- int end = testCode.indexOf(" // marker"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // fieldD +- { +- Outline outline = outlines[3]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FIELD); +- expect(element.name, "fieldD"); +- { +- int offset = testCode.indexOf(" // marker"); +- int end = testCode.indexOf(" // marker2"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- } +- +- test_sourceRange_inUnit() async { +- Outline unitOutline = await _computeOutline(''' +-library lib; +-/// My first class. +-class A { +-} // endA +-class B { +-} // endB +-'''); +- List topOutlines = unitOutline.children; +- expect(topOutlines, hasLength(2)); +- // A +- { +- Outline outline = topOutlines[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CLASS); +- expect(element.name, "A"); +- { +- int offset = testCode.indexOf("/// My first class."); +- int end = testCode.indexOf(" // endA"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // B +- { +- Outline outline = topOutlines[1]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CLASS); +- expect(element.name, "B"); +- { +- int offset = testCode.indexOf(" // endA"); +- int end = testCode.indexOf(" // endB"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- } +- +- test_sourceRange_inUnit_inVariableList() async { +- Outline unitOutline = await _computeOutline(''' +-int fieldA, fieldB, fieldC; // marker +-int fieldD; // marker2 +-'''); +- List outlines = unitOutline.children; +- expect(outlines, hasLength(4)); +- // fieldA +- { +- Outline outline = outlines[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE); +- expect(element.name, "fieldA"); +- { +- int offset = 0; +- int end = testCode.indexOf(", fieldB"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // fieldB +- { +- Outline outline = outlines[1]; +- Element element = outline.element; +- expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE); +- expect(element.name, "fieldB"); +- { +- int offset = testCode.indexOf(", fieldB"); +- int end = testCode.indexOf(", fieldC"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // fieldC +- { +- Outline outline = outlines[2]; +- Element element = outline.element; +- expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE); +- expect(element.name, "fieldC"); +- { +- int offset = testCode.indexOf(", fieldC"); +- int end = testCode.indexOf(" // marker"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- // fieldD +- { +- Outline outline = outlines[3]; +- Element element = outline.element; +- expect(element.kind, ElementKind.TOP_LEVEL_VARIABLE); +- expect(element.name, "fieldD"); +- { +- int offset = testCode.indexOf(" // marker"); +- int end = testCode.indexOf(" // marker2"); +- expect(outline.offset, offset); +- expect(outline.length, end - offset); +- } +- } +- } +- +- test_topLevel() async { +- Outline unitOutline = await _computeOutline(''' +-typedef String FTA(int i, String s); +-typedef FTB(int p); +-class A {} +-class B {} +-class CTA = A with B; +-class CTB = A with B; +-String fA(int i, String s) => null; +-fB(int p) => null; +-String get propA => null; +-set propB(int v) {} +-'''); +- List topOutlines = unitOutline.children; +- expect(topOutlines, hasLength(10)); +- // FTA +- { +- Outline outline = topOutlines[0]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS); +- expect(element.name, "FTA"); +- expect(element.typeParameters, ""); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("FTA(")); +- expect(location.length, "FTA".length); +- } +- expect(element.parameters, "(int i, String s)"); +- expect(element.returnType, "String"); +- } +- // FTB +- { +- Outline outline = topOutlines[1]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS); +- expect(element.name, "FTB"); +- expect(element.typeParameters, isNull); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("FTB(")); +- expect(location.length, "FTB".length); +- } +- expect(element.parameters, "(int p)"); +- expect(element.returnType, ""); +- } +- // CTA +- { +- Outline outline = topOutlines[4]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CLASS_TYPE_ALIAS); +- expect(element.name, "CTA"); +- expect(element.typeParameters, ''); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("CTA =")); +- expect(location.length, "CTA".length); +- } +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- } +- // CTB +- { +- Outline outline = topOutlines[5]; +- Element element = outline.element; +- expect(element.kind, ElementKind.CLASS_TYPE_ALIAS); +- expect(element.name, 'CTB'); +- expect(element.typeParameters, isNull); +- expect(element.returnType, isNull); +- } +- // fA +- { +- Outline outline = topOutlines[6]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FUNCTION); +- expect(element.name, "fA"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("fA(")); +- expect(location.length, "fA".length); +- } +- expect(element.parameters, "(int i, String s)"); +- expect(element.returnType, "String"); +- } +- // fB +- { +- Outline outline = topOutlines[7]; +- Element element = outline.element; +- expect(element.kind, ElementKind.FUNCTION); +- expect(element.name, "fB"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("fB(")); +- expect(location.length, "fB".length); +- } +- expect(element.parameters, "(int p)"); +- expect(element.returnType, ""); +- } +- // propA +- { +- Outline outline = topOutlines[8]; +- Element element = outline.element; +- expect(element.kind, ElementKind.GETTER); +- expect(element.name, "propA"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("propA => null;")); +- expect(location.length, "propA".length); +- } +- expect(element.parameters, ""); +- expect(element.returnType, "String"); +- } +- // propB +- { +- Outline outline = topOutlines[9]; +- Element element = outline.element; +- expect(element.kind, ElementKind.SETTER); +- expect(element.name, "propB"); +- { +- Location location = element.location; +- expect(location.offset, testCode.indexOf("propB(int v) {}")); +- expect(location.length, "propB".length); +- } +- expect(element.parameters, "(int v)"); +- expect(element.returnType, ""); +- } +- } +- +- void _expect(Outline outline, +- {ElementKind kind, +- bool leaf: false, +- int length, +- String name, +- int offset, +- String parameters, +- String returnType}) { +- Element element = outline.element; +- Location location = element.location; +- +- if (kind != null) { +- expect(element.kind, kind); +- } +- if (leaf) { +- expect(outline.children, isNull); +- } +- length ??= name?.length; +- if (length != null) { +- expect(location.length, length); +- } +- if (name != null) { +- expect(element.name, name); +- } +- if (offset != null) { +- expect(location.offset, offset); +- } +- if (parameters != null) { +- expect(element.parameters, parameters); +- } +- if (returnType != null) { +- expect(element.returnType, returnType); +- } +- } +- +- void _isEnumConstant(Outline outline, String name) { +- Element element = outline.element; +- expect(element.kind, ElementKind.ENUM_CONSTANT); +- expect(element.name, name); +- expect(element.parameters, isNull); +- expect(element.returnType, isNull); +- } +-} +diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart +deleted file mode 100644 +index 4bf0a762dab..00000000000 +--- a/pkg/analysis_server/test/src/computer/test_all.dart ++++ /dev/null +@@ -1,20 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'closingLabels_computer_test.dart' as closingLabels_computer_test; +-import 'import_elements_computer_test.dart' as import_elements_computer_test; +-import 'imported_elements_computer_test.dart' +- as imported_elements_computer_test; +-import 'outline_computer_test.dart' as outline_computer_test; +- +-main() { +- defineReflectiveSuite(() { +- closingLabels_computer_test.main(); +- import_elements_computer_test.main(); +- imported_elements_computer_test.main(); +- outline_computer_test.main(); +- }); +-} +diff --git a/pkg/analysis_server/test/src/domain_abstract_test.dart b/pkg/analysis_server/test/src/domain_abstract_test.dart +deleted file mode 100644 +index 6585efb1bb9..00000000000 +--- a/pkg/analysis_server/test/src/domain_abstract_test.dart ++++ /dev/null +@@ -1,105 +0,0 @@ +-// 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 'package:analysis_server/src/domain_abstract.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/protocol_server.dart' hide Element; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../analysis_abstract.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(AbstractRequestHandlerTest); +- }); +-} +- +-@reflectiveTest +-class AbstractRequestHandlerTest extends AbstractAnalysisTest { +- test_waitForResponses_empty_noTimeout() async { +- AbstractRequestHandler handler = new TestAbstractRequestHandler(server); +- Map> futures = +- >{}; +- List responses = await handler.waitForResponses(futures); +- expect(responses, isEmpty); +- } +- +- test_waitForResponses_empty_timeout() async { +- AbstractRequestHandler handler = new TestAbstractRequestHandler(server); +- Map> futures = +- >{}; +- List responses = +- await handler.waitForResponses(futures, timeout: 250); +- expect(responses, isEmpty); +- } +- +- test_waitForResponses_nonEmpty_noTimeout_immediate() async { +- AbstractRequestHandler handler = new TestAbstractRequestHandler(server); +- PluginInfo plugin1 = new DiscoveredPluginInfo('p1', '', '', null, null); +- PluginInfo plugin2 = new DiscoveredPluginInfo('p2', '', '', null, null); +- plugin.Response response1 = new plugin.Response('1', 1); +- plugin.Response response2 = new plugin.Response('2', 2); +- Map> futures = +- >{ +- plugin1: new Future.value(response1), +- plugin2: new Future.value(response2), +- }; +- List responses = await handler.waitForResponses(futures); +- expect(responses, unorderedEquals([response1, response2])); +- } +- +- test_waitForResponses_nonEmpty_noTimeout_withError() async { +- AbstractRequestHandler handler = new TestAbstractRequestHandler(server); +- PluginInfo plugin1 = new DiscoveredPluginInfo('p1', '', '', null, null); +- PluginInfo plugin2 = new DiscoveredPluginInfo('p2', '', '', null, null); +- plugin.Response response1 = new plugin.Response('1', 1); +- plugin.Response response2 = new plugin.Response('2', 2, +- error: new plugin.RequestError( +- plugin.RequestErrorCode.PLUGIN_ERROR, 'message')); +- Map> futures = +- >{ +- plugin1: new Future.value(response1), +- plugin2: new Future.value(response2), +- }; +- List responses = await handler.waitForResponses(futures); +- expect(responses, unorderedEquals([response1])); +- } +- +- test_waitForResponses_nonEmpty_timeout_someDelayed() async { +- AbstractRequestHandler handler = new TestAbstractRequestHandler(server); +- PluginInfo plugin1 = new DiscoveredPluginInfo('p1', '', '', null, null); +- PluginInfo plugin2 = new DiscoveredPluginInfo('p2', '', '', null, null); +- PluginInfo plugin3 = new DiscoveredPluginInfo('p3', '', '', null, null); +- plugin.Response response1 = new plugin.Response('1', 1); +- plugin.Response response2 = new plugin.Response('2', 2); +- plugin.Response response3 = new plugin.Response('3', 3); +- Map> futures = +- >{ +- plugin1: +- new Future.delayed(new Duration(milliseconds: 500), () => response1), +- plugin2: new Future.value(response2), +- plugin3: +- new Future.delayed(new Duration(milliseconds: 500), () => response3) +- }; +- List responses = +- await handler.waitForResponses(futures, timeout: 50); +- expect(responses, unorderedEquals([response2])); +- } +-} +- +-class TestAbstractRequestHandler extends AbstractRequestHandler { +- TestAbstractRequestHandler(server) : super(server); +- +- @override +- Response handleRequest(Request request) { +- fail('Unexpected invocation of handleRequest'); +- return null; +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart b/pkg/analysis_server/test/src/plugin/notification_manager_test.dart +deleted file mode 100644 +index 1b5dd99031c..00000000000 +--- a/pkg/analysis_server/test/src/plugin/notification_manager_test.dart ++++ /dev/null +@@ -1,511 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol.dart' as server; +-import 'package:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analysis_server/src/channel/channel.dart'; +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'protocol_test_utilities.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(NotificationManagerTest); +- }); +-} +- +-@reflectiveTest +-class NotificationManagerTest extends ProtocolTestUtilities { +- String testDir; +- String fileA; +- String fileB; +- +- TestChannel channel; +- +- NotificationManager manager; +- +- void setUp() { +- MemoryResourceProvider provider = new MemoryResourceProvider(); +- testDir = provider.convertPath('/test'); +- fileA = provider.convertPath('/test/a.dart'); +- fileB = provider.convertPath('/test/b.dart'); +- channel = new TestChannel(); +- manager = new NotificationManager(channel, provider); +- } +- +- void test_handlePluginNotification_errors() { +- manager.setAnalysisRoots([testDir], []); +- AnalysisError error1 = analysisError(0, 0, file: fileA); +- AnalysisError error2 = analysisError(3, 4, file: fileA); +- plugin.AnalysisErrorsParams params = +- new plugin.AnalysisErrorsParams(fileA, [error1, error2]); +- manager.handlePluginNotification('a', params.toNotification()); +- _verifyErrors(fileA, [error1, error2]); +- } +- +- void test_handlePluginNotification_folding() { +- manager.setSubscriptions({ +- server.AnalysisService.FOLDING: new Set.from([fileA, fileB]) +- }); +- FoldingRegion region1 = foldingRegion(10, 3); +- FoldingRegion region2 = foldingRegion(20, 6); +- plugin.AnalysisFoldingParams params = +- new plugin.AnalysisFoldingParams(fileA, [region1, region2]); +- manager.handlePluginNotification('a', params.toNotification()); +- _verifyFoldingRegions(fileA, [region1, region2]); +- } +- +- void test_handlePluginNotification_highlights() { +- manager.setSubscriptions({ +- server.AnalysisService.HIGHLIGHTS: new Set.from([fileA, fileB]) +- }); +- HighlightRegion region1 = highlightRegion(10, 3); +- HighlightRegion region2 = highlightRegion(20, 6); +- plugin.AnalysisHighlightsParams params = +- new plugin.AnalysisHighlightsParams(fileA, [region1, region2]); +- manager.handlePluginNotification('a', params.toNotification()); +- _verifyHighlightRegions(fileA, [region1, region2]); +- } +- +- void test_handlePluginNotification_naviation() { +- manager.setSubscriptions({ +- server.AnalysisService.NAVIGATION: new Set.from([fileA, fileB]) +- }); +- plugin.AnalysisNavigationParams pluginParams = +- pluginNavigationParams(0, 0, file: fileA); +- manager.handlePluginNotification('a', pluginParams.toNotification()); +- +- server.AnalysisNavigationParams serverParams = +- serverNavigationParams(0, 0, file: fileA); +- _verifyNavigationParams(serverParams); +- } +- +- void test_handlePluginNotification_occurences() { +- manager.setSubscriptions({ +- server.AnalysisService.OCCURRENCES: new Set.from([fileA, fileB]) +- }); +- Occurrences occurrences1 = occurrences(0, 0); +- Occurrences occurrences2 = occurrences(5, 7); +- plugin.AnalysisOccurrencesParams params = +- new plugin.AnalysisOccurrencesParams( +- fileA, [occurrences1, occurrences2]); +- +- manager.handlePluginNotification('a', params.toNotification()); +- _verifyOccurrences(fileA, [occurrences1, occurrences2]); +- } +- +- void test_handlePluginNotification_outline() { +- manager.setSubscriptions({ +- server.AnalysisService.OUTLINE: new Set.from([fileA, fileB]) +- }); +- Outline outline1 = outline(0, 0); +- plugin.AnalysisOutlineParams params = +- new plugin.AnalysisOutlineParams(fileA, [outline1]); +- manager.handlePluginNotification('a', params.toNotification()); +- +- _verifyOutlines(fileA, outline1); +- } +- +- void test_handlePluginNotification_pluginError() { +- bool isFatal = false; +- String message = 'message'; +- String stackTrace = 'stackTrace'; +- plugin.PluginErrorParams params = +- new plugin.PluginErrorParams(isFatal, message, stackTrace); +- manager.handlePluginNotification('a', params.toNotification()); +- _verifyPluginError(isFatal, message, stackTrace); +- } +- +- void test_recordAnalysisErrors_noSubscription() { +- AnalysisError error = analysisError(0, 0, file: fileA); +- manager.recordAnalysisErrors('a', fileA, [error]); +- expect(channel.sentNotification, isNull); +- } +- +- void test_recordAnalysisErrors_withSubscription() { +- manager.setAnalysisRoots([testDir], []); +- // +- // Errors should be reported when they are recorded. +- // +- AnalysisError error1 = analysisError(0, 0, file: fileA); +- AnalysisError error2 = analysisError(3, 4, file: fileA); +- manager.recordAnalysisErrors('a', fileA, [error1, error2]); +- _verifyErrors(fileA, [error1, error2]); +- // +- // Errors from different plugins should be cumulative. +- // +- AnalysisError error3 = analysisError(6, 8, file: fileA); +- manager.recordAnalysisErrors('b', fileA, [error3]); +- _verifyErrors(fileA, [error1, error2, error3]); +- // +- // Overwriting errors from one plugin should not affect errors from other +- // plugins. +- // +- AnalysisError error4 = analysisError(9, 12, file: fileA); +- manager.recordAnalysisErrors('a', fileA, [error4]); +- _verifyErrors(fileA, [error4, error3]); +- // +- // Recording errors against a file should not affect the errors for other +- // files. +- // +- AnalysisError error5 = analysisError(12, 16, file: fileB); +- manager.recordAnalysisErrors('a', fileB, [error5]); +- _verifyErrors(fileB, [error5]); +- } +- +- void test_recordFoldingRegions_noSubscription() { +- FoldingRegion region = foldingRegion(10, 5); +- manager.recordFoldingRegions('a', fileA, [region]); +- expect(channel.sentNotification, isNull); +- } +- +- void test_recordFoldingRegions_withSubscription() { +- manager.setSubscriptions({ +- server.AnalysisService.FOLDING: new Set.from([fileA, fileB]) +- }); +- // +- // Regions should be reported when they are recorded. +- // +- FoldingRegion region1 = foldingRegion(10, 3); +- FoldingRegion region2 = foldingRegion(20, 6); +- manager.recordFoldingRegions('a', fileA, [region1, region2]); +- _verifyFoldingRegions(fileA, [region1, region2]); +- // +- // Regions from different plugins should be cumulative. +- // +- FoldingRegion region3 = foldingRegion(30, 5); +- manager.recordFoldingRegions('b', fileA, [region3]); +- _verifyFoldingRegions(fileA, [region1, region2, region3]); +- // +- // Overwriting regions from one plugin should not affect regions from other +- // plugins. +- // +- FoldingRegion region4 = foldingRegion(40, 2); +- manager.recordFoldingRegions('a', fileA, [region4]); +- _verifyFoldingRegions(fileA, [region4, region3]); +- // +- // Recording regions against a file should not affect the regions for other +- // files. +- // +- FoldingRegion region5 = foldingRegion(50, 7); +- manager.recordFoldingRegions('a', fileB, [region5]); +- _verifyFoldingRegions(fileB, [region5]); +- } +- +- void test_recordHighlightRegions_noSubscription() { +- HighlightRegion region = highlightRegion(10, 5); +- manager.recordHighlightRegions('a', fileA, [region]); +- expect(channel.sentNotification, isNull); +- } +- +- void test_recordHighlightRegions_withSubscription() { +- manager.setSubscriptions({ +- server.AnalysisService.HIGHLIGHTS: new Set.from([fileA, fileB]) +- }); +- // +- // Regions should be reported when they are recorded. +- // +- HighlightRegion region1 = highlightRegion(10, 3); +- HighlightRegion region2 = highlightRegion(20, 6); +- manager.recordHighlightRegions('a', fileA, [region1, region2]); +- _verifyHighlightRegions(fileA, [region1, region2]); +- // +- // Regions from different plugins should be cumulative. +- // +- HighlightRegion region3 = highlightRegion(30, 5); +- manager.recordHighlightRegions('b', fileA, [region3]); +- _verifyHighlightRegions(fileA, [region1, region2, region3]); +- // +- // Overwriting regions from one plugin should not affect regions from other +- // plugins. +- // +- HighlightRegion region4 = highlightRegion(40, 2); +- manager.recordHighlightRegions('a', fileA, [region4]); +- _verifyHighlightRegions(fileA, [region4, region3]); +- // +- // Recording regions against a file should not affect the regions for other +- // files. +- // +- HighlightRegion region5 = highlightRegion(50, 7); +- manager.recordHighlightRegions('a', fileB, [region5]); +- _verifyHighlightRegions(fileB, [region5]); +- } +- +- void test_recordNavigationParams_noSubscription() { +- server.AnalysisNavigationParams params = +- serverNavigationParams(0, 0, file: fileA); +- manager.recordNavigationParams('a', fileA, params); +- expect(channel.sentNotification, isNull); +- } +- +- void test_recordNavigationParams_withSubscription() { +- manager.setSubscriptions({ +- server.AnalysisService.NAVIGATION: new Set.from([fileA, fileB]) +- }); +- // +- // Parameters should be reported when they are recorded. +- // +- server.AnalysisNavigationParams params1 = +- serverNavigationParams(0, 0, file: fileA); +- manager.recordNavigationParams('a', fileA, params1); +- _verifyNavigationParams(params1); +- // +- // Parameters from different plugins should be cumulative. +- // +- server.AnalysisNavigationParams params2 = +- serverNavigationParams(2, 4, file: fileA); +- manager.recordNavigationParams('b', fileA, params2); +- server.AnalysisNavigationParams params1and2 = +- new server.AnalysisNavigationParams(fileA, [ +- new NavigationRegion(0, 2, [0]), +- new NavigationRegion(4, 2, [1]) +- ], [ +- new NavigationTarget(ElementKind.FIELD, 0, 1, 2, 2, 3), +- new NavigationTarget(ElementKind.FIELD, 2, 5, 2, 6, 7) +- ], [ +- 'aa', +- 'ab', +- 'ac', +- 'ad' +- ]); +- _verifyNavigationParams(params1and2); +- // +- // Overwriting parameters from one plugin should not affect parameters from +- // other plugins. +- // +- server.AnalysisNavigationParams params3 = +- serverNavigationParams(4, 8, file: fileA); +- manager.recordNavigationParams('a', fileA, params3); +- server.AnalysisNavigationParams params3and2 = +- new server.AnalysisNavigationParams(fileA, [ +- new NavigationRegion(8, 2, [0]), +- new NavigationRegion(4, 2, [1]) +- ], [ +- new NavigationTarget(ElementKind.FIELD, 0, 9, 2, 10, 11), +- new NavigationTarget(ElementKind.FIELD, 2, 5, 2, 6, 7) +- ], [ +- 'ae', +- 'af', +- 'ac', +- 'ad' +- ]); +- _verifyNavigationParams(params3and2); +- // +- // Recording parameters against a file should not affect the parameters for +- // other files. +- // +- server.AnalysisNavigationParams params4 = +- serverNavigationParams(6, 12, file: fileB); +- manager.recordNavigationParams('a', fileB, params4); +- _verifyNavigationParams(params4); +- } +- +- void test_recordOccurrences_noSubscription() { +- Occurrences occurrences1 = occurrences(0, 0); +- manager.recordOccurrences('a', fileA, [occurrences1]); +- expect(channel.sentNotification, isNull); +- } +- +- void test_recordOccurrences_withSubscription() { +- manager.setSubscriptions({ +- server.AnalysisService.OCCURRENCES: new Set.from([fileA, fileB]) +- }); +- // +- // Occurrences should be reported when they are recorded. +- // +- Occurrences occurrences1 = occurrences(0, 0); +- Occurrences occurrences2 = occurrences(5, 7); +- manager.recordOccurrences('a', fileA, [occurrences1, occurrences2]); +- _verifyOccurrences(fileA, [occurrences1, occurrences2]); +- // +- // Occurrences from different plugins should be cumulative. +- // +- Occurrences occurrences3 = occurrences(10, 14); +- manager.recordOccurrences('b', fileA, [occurrences3]); +- _verifyOccurrences(fileA, [occurrences1, occurrences2, occurrences3]); +- // +- // Overwriting occurrences from one plugin should not affect occurrences +- // from other plugins. +- // +- Occurrences occurrences4 = occurrences(15, 21); +- manager.recordOccurrences('a', fileA, [occurrences4]); +- _verifyOccurrences(fileA, [occurrences4, occurrences3]); +- // +- // Recording occurrences against a file should not affect the occurrences +- // for other files. +- // +- Occurrences occurrences5 = occurrences(20, 28); +- manager.recordOccurrences('a', fileB, [occurrences5]); +- _verifyOccurrences(fileB, [occurrences5]); +- } +- +- void test_recordOutlines_noSubscription() { +- Outline outline1 = outline(0, 0); +- manager.recordOutlines('a', fileA, [outline1]); +- expect(channel.sentNotification, isNull); +- } +- +- @failingTest +- void test_recordOutlines_withSubscription() { +- fail('The outline handling needs to be re-worked slightly'); +- // TODO(brianwilkerson) Figure out outlines. What should we do when merge +- // cannot produce a single outline? +- manager.setSubscriptions({ +- server.AnalysisService.OUTLINE: new Set.from([fileA, fileB]) +- }); +- // +- // Outlines should be reported when they are recorded. +- // +- Outline outline1 = outline(0, 0); +- Outline outline2 = outline(5, 7); +- manager.recordOutlines('a', fileA, [outline1, outline2]); +- // TODO(brianwilkerson) Figure out how to test this. +-// _verifyOutlines(fileA, [outline1, outline2]); +- // +- // Outlines from different plugins should be cumulative. +- // +- Outline outline3 = outline(10, 14); +- manager.recordOutlines('b', fileA, [outline3]); +- // TODO(brianwilkerson) Figure out how to test this. +-// _verifyOutlines(fileA, [outline1, outline2, outline3]); +- // +- // Overwriting outlines from one plugin should not affect outlines from +- // other plugins. +- // +- Outline outline4 = outline(15, 21); +- manager.recordOutlines('a', fileA, [outline4]); +- // TODO(brianwilkerson) Figure out how to test this. +-// _verifyOutlines(fileA, [outline4, outline3]); +- // +- // Recording outlines against a file should not affect the outlines for +- // other files. +- // +- Outline outline5 = outline(20, 28); +- manager.recordOutlines('a', fileB, [outline5]); +- // TODO(brianwilkerson) Figure out how to test this. +-// _verifyOutlines(fileB, [outline5]); +- } +- +- void _verifyErrors(String fileName, List expectedErrors) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'analysis.errors'); +- server.AnalysisErrorsParams params = +- new server.AnalysisErrorsParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.file, fileName); +- expect(params.errors, equals(expectedErrors)); +- channel.sentNotification = null; +- } +- +- void _verifyFoldingRegions( +- String fileName, List expectedRegions) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'analysis.folding'); +- server.AnalysisFoldingParams params = +- new server.AnalysisFoldingParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.file, fileName); +- expect(params.regions, equals(expectedRegions)); +- channel.sentNotification = null; +- } +- +- void _verifyHighlightRegions( +- String fileName, List expectedRegions) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'analysis.highlights'); +- server.AnalysisHighlightsParams params = +- new server.AnalysisHighlightsParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.file, fileName); +- expect(params.regions, equals(expectedRegions)); +- channel.sentNotification = null; +- } +- +- void _verifyNavigationParams(server.AnalysisNavigationParams expectedParams) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'analysis.navigation'); +- server.AnalysisNavigationParams params = +- new server.AnalysisNavigationParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.file, expectedParams.file); +- expect(params.files, equals(expectedParams.files)); +- expect(params.regions, equals(expectedParams.regions)); +- expect(params.targets, equals(expectedParams.targets)); +- channel.sentNotification = null; +- } +- +- void _verifyOccurrences( +- String fileName, List expectedOccurrences) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'analysis.occurrences'); +- server.AnalysisOccurrencesParams params = +- new server.AnalysisOccurrencesParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.file, fileName); +- expect(params.occurrences, equals(expectedOccurrences)); +- channel.sentNotification = null; +- } +- +- void _verifyOutlines(String fileName, Outline expectedOutline) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'analysis.outline'); +- server.AnalysisOutlineParams params = +- new server.AnalysisOutlineParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.file, fileName); +- expect(params.outline, equals(expectedOutline)); +- channel.sentNotification = null; +- } +- +- void _verifyPluginError(bool isFatal, String message, String stackTrace) { +- server.Notification notification = channel.sentNotification; +- expect(notification, isNotNull); +- expect(notification.event, 'server.error'); +- server.ServerErrorParams params = +- new server.ServerErrorParams.fromNotification(notification); +- expect(params, isNotNull); +- expect(params.isFatal, isFatal); +- expect(params.message, message); +- expect(params.stackTrace, stackTrace); +- channel.sentNotification = null; +- } +-} +- +-class TestChannel implements ServerCommunicationChannel { +- server.Notification sentNotification; +- +- @override +- void close() { +- fail('Unexpected invocation of close'); +- } +- +- @override +- void listen(void onRequest(server.Request request), +- {Function onError, void onDone()}) { +- fail('Unexpected invocation of listen'); +- } +- +- @override +- void sendNotification(server.Notification notification) { +- sentNotification = notification; +- } +- +- @override +- void sendResponse(server.Response response) { +- fail('Unexpected invocation of sendResponse'); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart +deleted file mode 100644 +index 38e71a9e0a0..00000000000 +--- a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart ++++ /dev/null +@@ -1,96 +0,0 @@ +-// 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 'package:analysis_server/src/plugin/plugin_locator.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(PluginLocatorTest); +- }); +-} +- +-@reflectiveTest +-class PluginLocatorTest { +- MemoryResourceProvider resourceProvider; +- String packageRoot; +- String pubspecPath; +- String defaultDirPath; +- PluginLocator locator; +- +- void setUp() { +- resourceProvider = new MemoryResourceProvider(); +- packageRoot = resourceProvider.convertPath('/package'); +- resourceProvider.newFolder(packageRoot); +- locator = new PluginLocator(resourceProvider); +- } +- +- @failingTest +- void test_findPlugin_inPubspec_defaultDir() { +- // Support for specifying plugin locations in the pubspec is temporarily +- // disabled. +- String dirPath = _createPubspecWithKey(); +- _createDefaultDir(); +- expect(locator.findPlugin(packageRoot), dirPath); +- } +- +- @failingTest +- void test_findPlugin_inPubspec_noDefaultDir() { +- // Support for specifying plugin locations in the pubspec is temporarily +- // disabled. +- String dirPath = _createPubspecWithKey(); +- expect(locator.findPlugin(packageRoot), dirPath); +- } +- +- void test_findPlugin_noPubspec_defaultDir() { +- _createDefaultDir(); +- expect(locator.findPlugin(packageRoot), defaultDirPath); +- } +- +- void test_findPlugin_noPubspec_noDefaultDir() { +- expect(locator.findPlugin(packageRoot), isNull); +- } +- +- void test_findPlugin_notInPubspec_defaultDir() { +- _createPubspecWithoutKey(); +- _createDefaultDir(); +- expect(locator.findPlugin(packageRoot), defaultDirPath); +- } +- +- void test_findPlugin_notInPubspec_noDefaultDir() { +- _createPubspecWithoutKey(); +- expect(locator.findPlugin(packageRoot), isNull); +- } +- +- void _createDefaultDir() { +- defaultDirPath = resourceProvider.pathContext.join(packageRoot, +- PluginLocator.toolsFolderName, PluginLocator.defaultPluginFolderName); +- resourceProvider.newFolder(defaultDirPath); +- } +- +- void _createPubspec(String content) { +- pubspecPath = resourceProvider.pathContext +- .join(packageRoot, PluginLocator.pubspecFileName); +- resourceProvider.newFile(pubspecPath, content); +- } +- +- String _createPubspecWithKey() { +- String nonDefaultPath = +- resourceProvider.pathContext.join(packageRoot, 'pluginDir'); +- _createPubspec(''' +-name: test_project +-${PluginLocator.analyzerPluginKey}: $nonDefaultPath +-'''); +- resourceProvider.newFolder(nonDefaultPath); +- return nonDefaultPath; +- } +- +- void _createPubspecWithoutKey() { +- _createPubspec(''' +-name: test_project +-'''); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart +deleted file mode 100644 +index c9665cd4423..00000000000 +--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart ++++ /dev/null +@@ -1,918 +0,0 @@ +-// 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:io' as io; +- +-import 'package:analysis_server/src/plugin/notification_manager.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:analyzer_plugin/channel/channel.dart'; +-import 'package:analyzer_plugin/protocol/protocol.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' +- hide ContextRoot; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +-import 'package:watcher/watcher.dart' as watcher; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(BuiltInPluginInfoTest); +- defineReflectiveTests(DiscoveredPluginInfoTest); +- defineReflectiveTests(PluginManagerTest); +- defineReflectiveTests(PluginManagerFromDiskTest); +- defineReflectiveTests(PluginSessionTest); +- defineReflectiveTests(PluginSessionFromDiskTest); +- }); +-} +- +-@reflectiveTest +-class BuiltInPluginInfoTest { +- TestNotificationManager notificationManager; +- BuiltInPluginInfo plugin; +- +- void setUp() { +- notificationManager = new TestNotificationManager(); +- plugin = new BuiltInPluginInfo(null, 'test plugin', notificationManager, +- InstrumentationService.NULL_SERVICE); +- } +- +- test_addContextRoot() { +- ContextRoot contextRoot1 = new ContextRoot('/pkg1', []); +- plugin.addContextRoot(contextRoot1); +- expect(plugin.contextRoots, [contextRoot1]); +- plugin.addContextRoot(contextRoot1); +- expect(plugin.contextRoots, [contextRoot1]); +- } +- +- test_creation() { +- expect(plugin.pluginId, 'test plugin'); +- expect(plugin.notificationManager, notificationManager); +- expect(plugin.contextRoots, isEmpty); +- expect(plugin.currentSession, isNull); +- } +- +- test_removeContextRoot() { +- ContextRoot contextRoot1 = new ContextRoot('/pkg1', []); +- ContextRoot contextRoot2 = new ContextRoot('/pkg2', []); +- plugin.addContextRoot(contextRoot1); +- expect(plugin.contextRoots, unorderedEquals([contextRoot1])); +- plugin.addContextRoot(contextRoot2); +- expect(plugin.contextRoots, unorderedEquals([contextRoot1, contextRoot2])); +- plugin.removeContextRoot(contextRoot1); +- expect(plugin.contextRoots, unorderedEquals([contextRoot2])); +- plugin.removeContextRoot(contextRoot2); +- expect(plugin.contextRoots, isEmpty); +- } +- +- @failingTest +- test_start_notRunning() { +- fail('Not tested'); +- } +- +- test_start_running() async { +- plugin.currentSession = new PluginSession(plugin); +- try { +- await plugin.start('', ''); +- fail('Expected a StateError'); +- } on StateError { +- // Expected. +- } +- } +- +- test_stop_notRunning() { +- expect(() => plugin.stop(), throwsStateError); +- } +- +- test_stop_running() async { +- PluginSession session = new PluginSession(plugin); +- TestServerCommunicationChannel channel = +- new TestServerCommunicationChannel(session); +- plugin.currentSession = session; +- await plugin.stop(); +- expect(plugin.currentSession, isNull); +- expect(channel.sentRequests, hasLength(1)); +- expect(channel.sentRequests[0].method, 'plugin.shutdown'); +- } +-} +- +-@reflectiveTest +-class DiscoveredPluginInfoTest { +- MemoryResourceProvider resourceProvider; +- TestNotificationManager notificationManager; +- String pluginPath = '/pluginDir'; +- String executionPath = '/pluginDir/bin/plugin.dart'; +- String packagesPath = '/pluginDir/.packages'; +- DiscoveredPluginInfo plugin; +- +- void setUp() { +- resourceProvider = new MemoryResourceProvider(); +- notificationManager = new TestNotificationManager(); +- plugin = new DiscoveredPluginInfo(pluginPath, executionPath, packagesPath, +- notificationManager, InstrumentationService.NULL_SERVICE); +- } +- +- test_addContextRoot() { +- String optionsFilePath = '/pkg1/analysis_options.yaml'; +- ContextRoot contextRoot1 = new ContextRoot('/pkg1', []); +- contextRoot1.optionsFilePath = optionsFilePath; +- PluginSession session = new PluginSession(plugin); +- TestServerCommunicationChannel channel = +- new TestServerCommunicationChannel(session); +- plugin.currentSession = session; +- plugin.addContextRoot(contextRoot1); +- expect(plugin.contextRoots, [contextRoot1]); +- plugin.addContextRoot(contextRoot1); +- expect(plugin.contextRoots, [contextRoot1]); +- List sentRequests = channel.sentRequests; +- expect(sentRequests, hasLength(1)); +- List roots = sentRequests[0].params['roots']; +- expect(roots[0]['optionsFile'], optionsFilePath); +- } +- +- test_creation() { +- expect(plugin.path, pluginPath); +- expect(plugin.executionPath, executionPath); +- expect(plugin.notificationManager, notificationManager); +- expect(plugin.contextRoots, isEmpty); +- expect(plugin.currentSession, isNull); +- } +- +- test_removeContextRoot() { +- ContextRoot contextRoot1 = new ContextRoot('/pkg1', []); +- ContextRoot contextRoot2 = new ContextRoot('/pkg2', []); +- plugin.addContextRoot(contextRoot1); +- expect(plugin.contextRoots, unorderedEquals([contextRoot1])); +- plugin.addContextRoot(contextRoot2); +- expect(plugin.contextRoots, unorderedEquals([contextRoot1, contextRoot2])); +- plugin.removeContextRoot(contextRoot1); +- expect(plugin.contextRoots, unorderedEquals([contextRoot2])); +- plugin.removeContextRoot(contextRoot2); +- expect(plugin.contextRoots, isEmpty); +- } +- +- @failingTest +- test_start_notRunning() { +- fail('Not tested'); +- } +- +- test_start_running() async { +- plugin.currentSession = new PluginSession(plugin); +- try { +- await plugin.start('', ''); +- fail('Expected a StateError'); +- } on StateError { +- // Expected. +- } +- } +- +- test_stop_notRunning() { +- expect(() => plugin.stop(), throwsStateError); +- } +- +- test_stop_running() async { +- PluginSession session = new PluginSession(plugin); +- TestServerCommunicationChannel channel = +- new TestServerCommunicationChannel(session); +- plugin.currentSession = session; +- await plugin.stop(); +- expect(plugin.currentSession, isNull); +- expect(channel.sentRequests, hasLength(1)); +- expect(channel.sentRequests[0].method, 'plugin.shutdown'); +- } +-} +- +-@reflectiveTest +-class PluginManagerFromDiskTest extends PluginTestSupport { +- String byteStorePath = '/byteStore'; +- PluginManager manager; +- +- void setUp() { +- super.setUp(); +- manager = new PluginManager(resourceProvider, byteStorePath, '', +- notificationManager, InstrumentationService.NULL_SERVICE); +- } +- +- test_addPluginToContextRoot() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin(test: (String pluginPath) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, pluginPath); +- await manager.stopAll(); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- @failingTest +- test_addPluginToContextRoot_pubspec() async { +- // We can't successfully run pub until after the analyzer_plugin package has +- // been published. +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPubspecPlugin(test: (String pluginPath) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, pluginPath); +- String packagesPath = +- resourceProvider.pathContext.join(pluginPath, '.packages'); +- File packagesFile = resourceProvider.getFile(packagesPath); +- bool exists = packagesFile.exists; +- await manager.stopAll(); +- expect(exists, isTrue, reason: '.packages file was not created'); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_broadcastRequest_many() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin( +- pluginName: 'plugin1', +- test: (String plugin1Path) async { +- await withPlugin( +- pluginName: 'plugin2', +- test: (String plugin2Path) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, plugin1Path); +- await manager.addPluginToContextRoot(contextRoot, plugin2Path); +- +- Map> responses = +- manager.broadcastRequest( +- new CompletionGetSuggestionsParams( +- '/pkg1/lib/pkg1.dart', 100), +- contextRoot: contextRoot); +- expect(responses, hasLength(2)); +- +- await manager.stopAll(); +- }); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_broadcastRequest_many_noContextRoot() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin( +- pluginName: 'plugin1', +- test: (String plugin1Path) async { +- await withPlugin( +- pluginName: 'plugin2', +- test: (String plugin2Path) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, plugin1Path); +- await manager.addPluginToContextRoot(contextRoot, plugin2Path); +- +- Map> responses = +- manager.broadcastRequest(new CompletionGetSuggestionsParams( +- '/pkg1/lib/pkg1.dart', 100)); +- expect(responses, hasLength(2)); +- +- await manager.stopAll(); +- }); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_broadcastWatchEvent() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin( +- pluginName: 'plugin1', +- test: (String plugin1Path) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, plugin1Path); +- List plugins = manager.pluginsForContextRoot(contextRoot); +- expect(plugins, hasLength(1)); +- watcher.WatchEvent watchEvent = new watcher.WatchEvent( +- watcher.ChangeType.MODIFY, path.join(pkgPath, 'lib', 'lib.dart')); +- List> responses = +- await manager.broadcastWatchEvent(watchEvent); +- expect(responses, hasLength(1)); +- Response response = await responses[0]; +- expect(response, isNotNull); +- expect(response.error, isNull); +- await manager.stopAll(); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_pluginsForContextRoot_multiple() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin( +- pluginName: 'plugin1', +- test: (String plugin1Path) async { +- await withPlugin( +- pluginName: 'plugin2', +- test: (String plugin2Path) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, plugin1Path); +- await manager.addPluginToContextRoot(contextRoot, plugin2Path); +- +- List plugins = +- manager.pluginsForContextRoot(contextRoot); +- expect(plugins, hasLength(2)); +- List paths = plugins +- .map((PluginInfo plugin) => plugin.pluginId) +- .toList(); +- expect(paths, unorderedEquals([plugin1Path, plugin2Path])); +- +- await manager.stopAll(); +- }); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_pluginsForContextRoot_one() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin(test: (String pluginPath) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, pluginPath); +- +- List plugins = manager.pluginsForContextRoot(contextRoot); +- expect(plugins, hasLength(1)); +- expect(plugins[0].pluginId, pluginPath); +- +- await manager.stopAll(); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_removedContextRoot() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkgPath = pkg1Dir.resolveSymbolicLinksSync(); +- await withPlugin(test: (String pluginPath) async { +- ContextRoot contextRoot = new ContextRoot(pkgPath, []); +- await manager.addPluginToContextRoot(contextRoot, pluginPath); +- +- manager.removedContextRoot(contextRoot); +- +- await manager.stopAll(); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +- +- test_restartPlugins() async { +- io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1'); +- String pkg1Path = pkg1Dir.resolveSymbolicLinksSync(); +- io.Directory pkg2Dir = io.Directory.systemTemp.createTempSync('pkg2'); +- String pkg2Path = pkg2Dir.resolveSymbolicLinksSync(); +- await withPlugin( +- pluginName: 'plugin1', +- test: (String plugin1Path) async { +- await withPlugin( +- pluginName: 'plugin2', +- test: (String plugin2Path) async { +- ContextRoot contextRoot1 = new ContextRoot(pkg1Path, []); +- ContextRoot contextRoot2 = new ContextRoot(pkg2Path, []); +- await manager.addPluginToContextRoot(contextRoot1, plugin1Path); +- await manager.addPluginToContextRoot(contextRoot1, plugin2Path); +- await manager.addPluginToContextRoot(contextRoot2, plugin1Path); +- +- await manager.restartPlugins(); +- List plugins = manager.plugins; +- expect(plugins, hasLength(2)); +- expect(plugins[0].currentSession, isNotNull); +- expect(plugins[1].currentSession, isNotNull); +- if (plugins[0].pluginId.contains('plugin1')) { +- expect(plugins[0].contextRoots, +- unorderedEquals([contextRoot1, contextRoot2])); +- expect( +- plugins[1].contextRoots, unorderedEquals([contextRoot1])); +- } else { +- expect( +- plugins[0].contextRoots, unorderedEquals([contextRoot1])); +- expect(plugins[1].contextRoots, +- unorderedEquals([contextRoot1, contextRoot2])); +- } +- await manager.stopAll(); +- }); +- }); +- pkg1Dir.deleteSync(recursive: true); +- } +-} +- +-@reflectiveTest +-class PluginManagerTest { +- MemoryResourceProvider resourceProvider; +- String byteStorePath; +- String sdkPath; +- TestNotificationManager notificationManager; +- PluginManager manager; +- +- void setUp() { +- resourceProvider = new MemoryResourceProvider(); +- byteStorePath = resourceProvider.convertPath('/byteStore'); +- sdkPath = resourceProvider.convertPath('/sdk'); +- notificationManager = new TestNotificationManager(); +- manager = new PluginManager(resourceProvider, byteStorePath, sdkPath, +- notificationManager, InstrumentationService.NULL_SERVICE); +- } +- +- void test_broadcastRequest_none() { +- ContextRoot contextRoot = new ContextRoot('/pkg1', []); +- Map> responses = manager.broadcastRequest( +- new CompletionGetSuggestionsParams('/pkg1/lib/pkg1.dart', 100), +- contextRoot: contextRoot); +- expect(responses, hasLength(0)); +- } +- +- void test_creation() { +- expect(manager.resourceProvider, resourceProvider); +- expect(manager.byteStorePath, byteStorePath); +- expect(manager.sdkPath, sdkPath); +- expect(manager.notificationManager, notificationManager); +- } +- +- void test_pathsFor_withPackagesFile() { +- path.Context context = resourceProvider.pathContext; +- // +- // Build the minimal directory structure for a plugin package that includes +- // a .packages file. +- // +- String pluginDirPath = resourceProvider.convertPath('/plugin'); +- String pluginFilePath = context.join(pluginDirPath, 'bin', 'plugin.dart'); +- resourceProvider.newFile(pluginFilePath, ''); +- String packagesFilePath = context.join(pluginDirPath, '.packages'); +- resourceProvider.newFile(packagesFilePath, ''); +- // +- // Test path computation. +- // +- List paths = manager.pathsFor(pluginDirPath); +- expect(paths, hasLength(2)); +- expect(paths[0], pluginFilePath); +- expect(paths[1], packagesFilePath); +- } +- +- void test_pathsFor_withPubspec_inBazelWorkspace() { +- path.Context context = resourceProvider.pathContext; +- // +- // Build a Bazel workspace containing four packages, including the plugin. +- // +- String rootPath = resourceProvider.convertPath('/workspaceRoot'); +- resourceProvider.newFile(context.join(rootPath, 'WORKSPACE'), ''); +- resourceProvider.newFolder(context.join(rootPath, 'bazel-bin')); +- resourceProvider.newFolder(context.join(rootPath, 'bazel-genfiles')); +- +- String newPackage(String packageName, [List dependencies]) { +- String packageRoot = +- context.join(rootPath, 'third_party', 'dart', packageName); +- resourceProvider.newFile( +- context.join(packageRoot, 'lib', packageName + '.dart'), ''); +- StringBuffer buffer = new StringBuffer(); +- if (dependencies != null) { +- buffer.writeln('dependencies:'); +- for (String dependency in dependencies) { +- buffer.writeln(' $dependency: any'); +- } +- } +- resourceProvider.newFile( +- context.join(packageRoot, 'pubspec.yaml'), buffer.toString()); +- return packageRoot; +- } +- +- String pluginDirPath = newPackage('plugin', ['b', 'c']); +- newPackage('b', ['d']); +- newPackage('c', ['d']); +- newPackage('d'); +- String pluginFilePath = context.join(pluginDirPath, 'bin', 'plugin.dart'); +- resourceProvider.newFile(pluginFilePath, ''); +- // +- // Test path computation. +- // +- List paths = manager.pathsFor(pluginDirPath); +- expect(paths, hasLength(2)); +- expect(paths[0], pluginFilePath); +- File packagesFile = resourceProvider.getFile(paths[1]); +- expect(packagesFile.exists, isTrue); +- String content = packagesFile.readAsStringSync(); +- List lines = content.split('\n'); +- expect( +- lines, +- unorderedEquals([ +- 'plugin:file:///workspaceRoot/third_party/dart/plugin/lib', +- 'b:file:///workspaceRoot/third_party/dart/b/lib', +- 'c:file:///workspaceRoot/third_party/dart/c/lib', +- 'd:file:///workspaceRoot/third_party/dart/d/lib', +- '' +- ])); +- } +- +- void test_pluginsForContextRoot_none() { +- ContextRoot contextRoot = new ContextRoot('/pkg1', []); +- expect(manager.pluginsForContextRoot(contextRoot), isEmpty); +- } +- +- void test_stopAll_none() { +- manager.stopAll(); +- } +-} +- +-@reflectiveTest +-class PluginSessionFromDiskTest extends PluginTestSupport { +- test_start_notRunning() async { +- await withPlugin(test: (String pluginPath) async { +- String packagesPath = path.join(pluginPath, '.packages'); +- String mainPath = path.join(pluginPath, 'bin', 'plugin.dart'); +- String byteStorePath = path.join(pluginPath, 'byteStore'); +- new io.Directory(byteStorePath).createSync(); +- PluginInfo plugin = new DiscoveredPluginInfo( +- pluginPath, +- mainPath, +- packagesPath, +- notificationManager, +- InstrumentationService.NULL_SERVICE); +- PluginSession session = new PluginSession(plugin); +- plugin.currentSession = session; +- expect(await session.start(byteStorePath, ''), isTrue); +- await session.stop(); +- }); +- } +-} +- +-@reflectiveTest +-class PluginSessionTest { +- MemoryResourceProvider resourceProvider; +- TestNotificationManager notificationManager; +- String pluginPath; +- String executionPath; +- String packagesPath; +- String sdkPath; +- PluginInfo plugin; +- PluginSession session; +- +- void setUp() { +- resourceProvider = new MemoryResourceProvider(); +- notificationManager = new TestNotificationManager(); +- pluginPath = resourceProvider.convertPath('/pluginDir'); +- executionPath = resourceProvider.convertPath('/pluginDir/bin/plugin.dart'); +- packagesPath = resourceProvider.convertPath('/pluginDir/.packages'); +- sdkPath = resourceProvider.convertPath('/sdk'); +- plugin = new DiscoveredPluginInfo(pluginPath, executionPath, packagesPath, +- notificationManager, InstrumentationService.NULL_SERVICE); +- session = new PluginSession(plugin); +- } +- +- void test_handleNotification() { +- Notification notification = +- new AnalysisErrorsParams('/test.dart', []) +- .toNotification(); +- expect(notificationManager.notifications, hasLength(0)); +- session.handleNotification(notification); +- expect(notificationManager.notifications, hasLength(1)); +- expect(notificationManager.notifications[0], notification); +- } +- +- void test_handleOnDone() { +- TestServerCommunicationChannel channel = +- new TestServerCommunicationChannel(session); +- session.handleOnDone(); +- expect(channel.closeCount, 1); +- expect(session.pluginStoppedCompleter.isCompleted, isTrue); +- } +- +- @failingTest +- void test_handleOnError() { +- session.handleOnError(['message', 'trace']); +- fail('The method handleOnError is not implemented'); +- } +- +- test_handleResponse() async { +- new TestServerCommunicationChannel(session); +- Response response = new PluginVersionCheckResult( +- true, 'name', 'version', [], +- contactInfo: 'contactInfo') +- .toResponse('0', 1); +- Future future = +- session.sendRequest(new PluginVersionCheckParams('', '', '')); +- expect(session.pendingRequests, hasLength(1)); +- session.handleResponse(response); +- expect(session.pendingRequests, hasLength(0)); +- Response result = await future; +- expect(result, same(response)); +- } +- +- void test_nextRequestId() { +- expect(session.requestId, 0); +- expect(session.nextRequestId, '0'); +- expect(session.requestId, 1); +- } +- +- void test_sendRequest() { +- TestServerCommunicationChannel channel = +- new TestServerCommunicationChannel(session); +- session.sendRequest(new PluginVersionCheckParams('', '', '')); +- expect(channel.sentRequests, hasLength(1)); +- expect(channel.sentRequests[0].method, 'plugin.versionCheck'); +- } +- +- test_start_notCompatible() async { +- session.isCompatible = false; +- expect(await session.start(path.join(pluginPath, 'byteStore'), sdkPath), +- isFalse); +- } +- +- test_start_running() async { +- new TestServerCommunicationChannel(session); +- try { +- await session.start(null, ''); +- fail('Expected a StateError to be thrown'); +- } on StateError { +- // Expected behavior +- } +- } +- +- test_stop_notRunning() { +- expect(() => session.stop(), throwsStateError); +- } +- +- test_stop_running() async { +- TestServerCommunicationChannel channel = +- new TestServerCommunicationChannel(session); +- await session.stop(); +- expect(channel.sentRequests, hasLength(1)); +- expect(channel.sentRequests[0].method, 'plugin.shutdown'); +- } +-} +- +-/** +- * A class designed to be used as a superclass for test classes that define +- * tests that require plugins to be created on disk. +- */ +-abstract class PluginTestSupport { +- PhysicalResourceProvider resourceProvider; +- TestNotificationManager notificationManager; +- +- /** +- * The content to be used for the '.packages' file, or `null` if the content +- * has not yet been computed. +- */ +- String _packagesFileContent; +- +- void setUp() { +- resourceProvider = PhysicalResourceProvider.INSTANCE; +- notificationManager = new TestNotificationManager(); +- } +- +- /** +- * Create a directory structure representing a plugin on disk, run the given +- * [test] function, and then remove the directory. The directory will have the +- * following structure: +- * ``` +- * pluginDirectory +- * .packages +- * bin +- * plugin.dart +- * ``` +- * The name of the plugin directory will be the [pluginName], if one is +- * provided (in order to allow more than one plugin to be created by a single +- * test). The 'plugin.dart' file will contain the given [content], or default +- * content that implements a minimal plugin if the contents are not given. The +- * [test] function will be passed the path of the directory that was created. +- */ +- Future withPlugin( +- {String content, +- String pluginName, +- Future test(String pluginPath)}) async { +- io.Directory tempDirectory = +- io.Directory.systemTemp.createTempSync(pluginName ?? 'test_plugin'); +- try { +- String pluginPath = tempDirectory.resolveSymbolicLinksSync(); +- // +- // Create a .packages file. +- // +- io.File packagesFile = new io.File(path.join(pluginPath, '.packages')); +- packagesFile.writeAsStringSync(_getPackagesFileContent()); +- // +- // Create the 'bin' directory. +- // +- String binPath = path.join(pluginPath, 'bin'); +- new io.Directory(binPath).createSync(); +- // +- // Create the 'plugin.dart' file. +- // +- io.File pluginFile = new io.File(path.join(binPath, 'plugin.dart')); +- pluginFile.writeAsStringSync(content ?? _defaultPluginContent()); +- // +- // Run the actual test code. +- // +- await test(pluginPath); +- } finally { +- tempDirectory.deleteSync(recursive: true); +- } +- } +- +- /** +- * Create a directory structure representing a plugin on disk, run the given +- * [test] function, and then remove the directory. The directory will have the +- * following structure: +- * ``` +- * pluginDirectory +- * pubspec.yaml +- * bin +- * plugin.dart +- * ``` +- * The name of the plugin directory will be the [pluginName], if one is +- * provided (in order to allow more than one plugin to be created by a single +- * test). The 'plugin.dart' file will contain the given [content], or default +- * content that implements a minimal plugin if the contents are not given. The +- * [test] function will be passed the path of the directory that was created. +- */ +- Future withPubspecPlugin( +- {String content, +- String pluginName, +- Future test(String pluginPath)}) async { +- io.Directory tempDirectory = +- io.Directory.systemTemp.createTempSync(pluginName ?? 'test_plugin'); +- try { +- String pluginPath = tempDirectory.resolveSymbolicLinksSync(); +- // +- // Create a pubspec.yaml file. +- // +- io.File pubspecFile = new io.File(path.join(pluginPath, 'pubspec.yaml')); +- pubspecFile.writeAsStringSync(_getPubspecFileContent()); +- // +- // Create the 'bin' directory. +- // +- String binPath = path.join(pluginPath, 'bin'); +- new io.Directory(binPath).createSync(); +- // +- // Create the 'plugin.dart' file. +- // +- io.File pluginFile = new io.File(path.join(binPath, 'plugin.dart')); +- pluginFile.writeAsStringSync(content ?? _defaultPluginContent()); +- // +- // Run the actual test code. +- // +- await test(pluginPath); +- } finally { +- tempDirectory.deleteSync(recursive: true); +- } +- } +- +- /** +- * Convert the [sdkPackageMap] into a plugin-specific map by applying the +- * given relative path [delta] to each line. +- */ +- String _convertPackageMap(String sdkDirPath, List sdkPackageMap) { +- StringBuffer buffer = new StringBuffer(); +- for (String line in sdkPackageMap) { +- if (!line.startsWith('#')) { +- int index = line.indexOf(':'); +- String packageName = line.substring(0, index + 1); +- String relativePath = line.substring(index + 1); +- String absolutePath = path.join(sdkDirPath, relativePath); +- buffer.write(packageName); +- buffer.writeln(absolutePath); +- } +- } +- return buffer.toString(); +- } +- +- /** +- * The default content of the plugin. This is a minimal plugin that will only +- * respond correctly to version checks and to shutdown requests. +- */ +- String _defaultPluginContent() { +- return r''' +-import 'dart:isolate'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/physical_file_system.dart'; +-import 'package:analyzer_plugin/plugin/plugin.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/starter.dart'; +-import 'package:pub_semver/pub_semver.dart'; +- +-void main(List args, SendPort sendPort) { +- MinimalPlugin plugin = new MinimalPlugin(PhysicalResourceProvider.INSTANCE); +- new ServerPluginStarter(plugin).start(sendPort); +-} +- +-class MinimalPlugin extends ServerPlugin { +- MinimalPlugin(ResourceProvider provider) : super(provider); +- +- @override +- List get fileGlobsToAnalyze => ['**/*.dart']; +- +- @override +- String get name => 'minimal'; +- +- @override +- String get version => '0.0.1'; +- +- @override +- AnalysisHandleWatchEventsResult handleAnalysisHandleWatchEvents( +- AnalysisHandleWatchEventsParams parameters) => +- new AnalysisHandleWatchEventsResult(); +- +- @override +- bool isCompatibleWith(Version serverVersion) => true; +-} +-'''; +- } +- +- /** +- * Return the content to be used for the '.packages' file. +- */ +- String _getPackagesFileContent() { +- if (_packagesFileContent == null) { +- io.File sdkPackagesFile = new io.File(_sdkPackagesPath()); +- List sdkPackageMap = sdkPackagesFile.readAsLinesSync(); +- _packagesFileContent = +- _convertPackageMap(path.dirname(sdkPackagesFile.path), sdkPackageMap); +- } +- return _packagesFileContent; +- } +- +- /** +- * Return the content to be used for the 'pubspec.yaml' file. +- */ +- String _getPubspecFileContent() { +- return ''' +-name: 'test' +-dependencies: +- analyzer: any +- analyzer_plugin: any +-'''; +- } +- +- /** +- * Return the path to the '.packages' file in the root of the SDK checkout. +- */ +- String _sdkPackagesPath() { +- String packagesPath = io.Platform.script.toFilePath(); +- while (packagesPath.isNotEmpty && +- path.basename(packagesPath) != 'analysis_server') { +- packagesPath = path.dirname(packagesPath); +- } +- packagesPath = path.dirname(packagesPath); +- packagesPath = path.dirname(packagesPath); +- return path.join(packagesPath, '.packages'); +- } +-} +- +-class TestNotificationManager implements NotificationManager { +- List notifications = []; +- +- Map>> recordedErrors = +- >>{}; +- +- @override +- void handlePluginNotification(String pluginId, Notification notification) { +- notifications.add(notification); +- } +- +- @override +- noSuchMethod(Invocation invocation) { +- fail('Unexpected invocation of ${invocation.memberName}'); +- } +- +- @override +- void recordAnalysisErrors( +- String pluginId, String filePath, List errorData) { +- recordedErrors.putIfAbsent( +- pluginId, () => >{})[filePath] = errorData; +- } +-} +- +-class TestServerCommunicationChannel implements ServerCommunicationChannel { +- final PluginSession session; +- int closeCount = 0; +- List sentRequests = []; +- +- TestServerCommunicationChannel(this.session) { +- session.channel = this; +- } +- +- @override +- void close() { +- closeCount++; +- } +- +- void kill() { +- fail('Unexpected invocation of kill'); +- } +- +- @override +- void listen(void onResponse(Response response), +- void onNotification(Notification notification), +- {Function onError, void onDone()}) { +- fail('Unexpected invocation of listen'); +- } +- +- @override +- void sendRequest(Request request) { +- sentRequests.add(request); +- if (request.method == 'plugin.shutdown') { +- session.handleOnDone(); +- } +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart +deleted file mode 100644 +index 4d8291c7bd1..00000000000 +--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart ++++ /dev/null +@@ -1,187 +0,0 @@ +-// 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:typed_data'; +- +-import 'package:analysis_server/src/plugin/plugin_locator.dart'; +-import 'package:analysis_server/src/plugin/plugin_manager.dart'; +-import 'package:analysis_server/src/plugin/plugin_watcher.dart'; +-import 'package:analyzer/context/context_root.dart'; +-import 'package:analyzer/dart/analysis/session.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:analyzer/source/package_map_resolver.dart'; +-import 'package:analyzer/src/dart/analysis/driver.dart'; +-import 'package:analyzer/src/dart/analysis/file_state.dart'; +-import 'package:analyzer/src/dart/analysis/session.dart'; +-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:front_end/byte_store.dart'; +-import 'package:front_end/src/base/performance_logger.dart'; +-import 'package:path/path.dart' as path; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../mock_sdk.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(PluginWatcherTest); +- }); +-} +- +-@reflectiveTest +-class PluginWatcherTest { +- MemoryResourceProvider resourceProvider; +- TestPluginManager manager; +- PluginWatcher watcher; +- +- void setUp() { +- resourceProvider = new MemoryResourceProvider(); +- manager = new TestPluginManager(); +- watcher = new PluginWatcher(resourceProvider, manager); +- } +- +- test_addedDriver() async { +- String pkg1Path = resourceProvider.convertPath('/pkg1'); +- resourceProvider.newFile( +- resourceProvider.convertPath('/pkg1/lib/test1.dart'), ''); +- resourceProvider.newFile( +- resourceProvider.convertPath('/pkg2/lib/pkg2.dart'), ''); +- resourceProvider.newFile( +- resourceProvider.convertPath('/pkg2/pubspec.yaml'), 'name: pkg2'); +- resourceProvider.newFile( +- resourceProvider.convertPath( +- '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart'), +- ''); +- +- ContextRoot contextRoot = new ContextRoot(pkg1Path, []); +- TestDriver driver = new TestDriver(resourceProvider, contextRoot); +- driver.analysisOptions.enabledPluginNames = ['pkg2']; +- watcher.addedDriver(driver, contextRoot); +- expect(manager.addedContextRoots, isEmpty); +- // +- // Test to see whether the listener was configured correctly. +- // +- // Use a file in the package being analyzed. +- // +-// await driver.computeResult('package:pkg1/test1.dart'); +-// expect(manager.addedContextRoots, isEmpty); +- // +- // Use a file that imports a package with a plugin. +- // +-// await driver.computeResult('package:pkg2/pk2.dart'); +- // +- // Wait until the timer associated with the driver's FileSystemState is +- // guaranteed to have expired and the list of changed files will have been +- // delivered. +- // +- await new Future.delayed(new Duration(seconds: 1)); +- expect(manager.addedContextRoots, hasLength(1)); +- } +- +- test_addedDriver_missingPackage() async { +- String pkg1Path = resourceProvider.convertPath('/pkg1'); +- resourceProvider.newFile( +- resourceProvider.convertPath('/pkg1/lib/test1.dart'), ''); +- +- ContextRoot contextRoot = new ContextRoot(pkg1Path, []); +- TestDriver driver = new TestDriver(resourceProvider, contextRoot); +- driver.analysisOptions.enabledPluginNames = ['pkg3']; +- watcher.addedDriver(driver, contextRoot); +- expect(manager.addedContextRoots, isEmpty); +- // +- // Wait until the timer associated with the driver's FileSystemState is +- // guaranteed to have expired and the list of changed files will have been +- // delivered. +- // +- await new Future.delayed(new Duration(seconds: 1)); +- expect(manager.addedContextRoots, isEmpty); +- } +- +- void test_creation() { +- expect(watcher.resourceProvider, resourceProvider); +- expect(watcher.manager, manager); +- } +- +- test_removedDriver() { +- String pkg1Path = resourceProvider.convertPath('/pkg1'); +- ContextRoot contextRoot = new ContextRoot(pkg1Path, []); +- TestDriver driver = new TestDriver(resourceProvider, contextRoot); +- watcher.addedDriver(driver, contextRoot); +- watcher.removedDriver(driver); +- expect(manager.removedContextRoots, equals([contextRoot])); +- } +-} +- +-class TestDriver implements AnalysisDriver { +- final MemoryResourceProvider resourceProvider; +- +- SourceFactory sourceFactory; +- FileSystemState fsState; +- AnalysisSession currentSession; +- AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl(); +- +- final _resultController = new StreamController(); +- +- TestDriver(this.resourceProvider, ContextRoot contextRoot) { +- path.Context pathContext = resourceProvider.pathContext; +- MockSdk sdk = new MockSdk(resourceProvider: resourceProvider); +- String packageName = pathContext.basename(contextRoot.root); +- String libPath = pathContext.join(contextRoot.root, 'lib'); +- sourceFactory = new SourceFactory([ +- new DartUriResolver(sdk), +- new PackageMapUriResolver(resourceProvider, { +- packageName: [resourceProvider.getFolder(libPath)], +- 'pkg2': [ +- resourceProvider.getFolder(resourceProvider.convertPath('/pkg2/lib')) +- ] +- }) +- ]); +- fsState = new FileSystemState( +- new PerformanceLog(null), +- new MemoryByteStore(), +- null, +- resourceProvider, +- sourceFactory, +- new AnalysisOptionsImpl(), +- new Uint32List(0)); +- currentSession = new AnalysisSessionImpl(this); +- } +- +- Stream get results => _resultController.stream; +- +- Future computeResult(String uri) { +- FileState file = fsState.getFileForUri(Uri.parse(uri)); +- AnalysisResult result = new AnalysisResult( +- this, null, file.path, null, true, null, null, null, null, null, null); +- _resultController.add(result); +- return new Future.delayed(new Duration(milliseconds: 1)); +- } +- +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +-} +- +-class TestPluginManager implements PluginManager { +- List addedContextRoots = []; +- +- List removedContextRoots = []; +- +- @override +- Future addPluginToContextRoot( +- ContextRoot contextRoot, String path) async { +- addedContextRoots.add(contextRoot); +- return null; +- } +- +- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +- +- @override +- void recordPluginFailure(String hostPackageName, String message) {} +- +- @override +- void removedContextRoot(ContextRoot contextRoot) { +- removedContextRoots.add(contextRoot); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart +deleted file mode 100644 +index c0afe6a2a01..00000000000 +--- a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart ++++ /dev/null +@@ -1,192 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +- +-class ProtocolTestUtilities { +- static const List strings = const [ +- 'aa', +- 'ab', +- 'ac', +- 'ad', +- 'ae', +- 'af', +- 'ag', +- 'ah', +- 'ai', +- 'aj', +- 'ak', +- 'al', +- 'am', +- 'an', +- 'ao', +- 'ap', +- 'aq', +- 'ar', +- 'as', +- 'at', +- 'au', +- 'av', +- 'aw', +- 'ax', +- 'ay', +- 'az', +- 'ba', +- 'bb', +- 'bc', +- 'bd', +- 'be', +- 'bf', +- 'bg', +- 'bh', +- 'bi', +- 'bj', +- 'bk', +- 'bl', +- 'bm', +- 'bn', +- 'bo', +- 'bp', +- 'bq', +- 'br', +- 'bs', +- 'bt', +- 'bu', +- 'bv', +- 'bw', +- 'bx', +- 'by', +- 'bz', +- ]; +- +- /** +- * On return, increment [stringIndex] by 3 (or 4 if no [file] name is +- * provided) and [intIndex] by 4. +- */ +- AnalysisError analysisError(int stringIndex, int intIndex, {String file}) { +- return new AnalysisError( +- AnalysisErrorSeverity.ERROR, +- AnalysisErrorType.COMPILE_TIME_ERROR, +- location(stringIndex, intIndex, file: file), +- strings[stringIndex++], +- strings[stringIndex++], +- correction: strings[stringIndex++], +- hasFix: true); +- } +- +- /** +- * On return, increment [stringIndex] by 5 and [intIndex] by 5. +- */ +- Element element(int stringIndex, int intIndex, {ElementKind kind}) => +- new Element(kind ?? ElementKind.CLASS, strings[stringIndex++], intIndex++, +- location: new Location(fileName(stringIndex++), intIndex++, +- intIndex++, intIndex++, intIndex++), +- parameters: strings[stringIndex++], +- returnType: strings[stringIndex++], +- typeParameters: strings[stringIndex++]); +- +- String fileName(int stringIndex) => '${strings[stringIndex]}.dart'; +- +- FoldingRegion foldingRegion(int offset, int length) => +- new FoldingRegion(FoldingKind.COMMENT, offset, length); +- +- HighlightRegion highlightRegion(int offset, int length) => +- new HighlightRegion(HighlightRegionType.FIELD, offset, length); +- +- /** +- * On return, increment [stringIndex] by 1 and [intIndex] by 4. +- */ +- Location location(int stringIndex, int intIndex, {String file}) => +- new Location(file ?? fileName(stringIndex), intIndex++, intIndex++, +- intIndex++, intIndex++); +- +- /** +- * On return, increment [stringIndex] by 5 and [intIndex] by 7. +- */ +- Occurrences occurrences(int stringIndex, int intIndex) { +- Element referencedElement = element(stringIndex, intIndex); +- return new Occurrences(referencedElement, [intIndex + 5, intIndex + 6], +- referencedElement.name.length); +- } +- +- /** +- * On return, increment [stringIndex] by 10 and [intIndex] by 14. +- */ +- Outline outline(int stringIndex, int intIndex) => +- new Outline(element(stringIndex, intIndex), intIndex + 5, intIndex + 6, +- children: [ +- new Outline( +- element(stringIndex + 5, intIndex + 7, +- kind: ElementKind.METHOD), +- intIndex + 12, +- intIndex + 13) +- ]); +- +- /** +- * On return, increment [stringIndex] by 2 (or 3 if no [file] name is +- * provided) and [intIndex] by 4. +- */ +- plugin.AnalysisNavigationParams pluginNavigationParams( +- int stringIndex, int intIndex, {String file}) => +- new plugin.AnalysisNavigationParams( +- file ?? fileName(stringIndex++), [ +- new NavigationRegion(intIndex++, 2, [0]) +- ], [ +- new NavigationTarget( +- ElementKind.FIELD, 0, intIndex++, 2, intIndex++, intIndex++) +- ], [ +- strings[stringIndex++], +- strings[stringIndex++] +- ]); +- +- /** +- * On return, increment [stringIndex] by 2 and [intIndex] by 4. +- */ +- RefactoringProblem refactoringProblem(int stringIndex, int intIndex) { +- return new RefactoringProblem( +- RefactoringProblemSeverity.FATAL, strings[stringIndex++], +- location: location(stringIndex, intIndex)); +- } +- +- /** +- * On return, increment [stringIndex] by 2 (or 3 if no [file] name is +- * provided) and [intIndex] by 4. +- */ +- server.AnalysisNavigationParams serverNavigationParams( +- int stringIndex, int intIndex, {String file}) => +- new server.AnalysisNavigationParams( +- file ?? fileName(stringIndex++), [ +- new NavigationRegion(intIndex++, 2, [0]) +- ], [ +- new NavigationTarget( +- ElementKind.FIELD, 0, intIndex++, 2, intIndex++, intIndex++) +- ], [ +- strings[stringIndex++], +- strings[stringIndex++] +- ]); +- +- /** +- * On return, increment [stringIndex] by 6 and [intIndex] by 6. +- */ +- SourceChange sourceChange(int stringIndex, int intIndex) => +- new SourceChange(strings[stringIndex++], +- edits: [ +- new SourceFileEdit(fileName(stringIndex), intIndex++, +- edits: [ +- new SourceEdit(intIndex++, intIndex++, strings[stringIndex++]) +- ]) +- ], +- linkedEditGroups: [ +- new LinkedEditGroup( +- [new Position(fileName(stringIndex), intIndex++)], +- intIndex++, +- [ +- new LinkedEditSuggestion( +- strings[stringIndex++], LinkedEditSuggestionKind.METHOD) +- ]) +- ], +- selection: new Position(fileName(stringIndex), intIndex++)); +-} +diff --git a/pkg/analysis_server/test/src/plugin/request_converter_test.dart b/pkg/analysis_server/test/src/plugin/request_converter_test.dart +deleted file mode 100644 +index f306b92a480..00000000000 +--- a/pkg/analysis_server/test/src/plugin/request_converter_test.dart ++++ /dev/null +@@ -1,82 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analysis_server/src/plugin/request_converter.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart' as server; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'protocol_test_utilities.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(RequestConverterTest); +- }); +-} +- +-@reflectiveTest +-class RequestConverterTest extends ProtocolTestUtilities { +- RequestConverter converter = new RequestConverter(); +- +- void test_convertAnalysisService() { +- Map kindMap = +- { +- plugin.AnalysisService.FOLDING: server.AnalysisService.FOLDING, +- plugin.AnalysisService.HIGHLIGHTS: server.AnalysisService.HIGHLIGHTS, +- plugin.AnalysisService.NAVIGATION: server.AnalysisService.NAVIGATION, +- plugin.AnalysisService.OCCURRENCES: server.AnalysisService.OCCURRENCES, +- plugin.AnalysisService.OUTLINE: server.AnalysisService.OUTLINE, +- }; +- kindMap.forEach( +- (plugin.AnalysisService pluginKind, server.AnalysisService serverKind) { +- expect(converter.convertAnalysisService(serverKind), pluginKind); +- }); +- } +- +- void test_convertAnalysisSetPriorityFilesParams() { +- List files = ['a', 'b', 'c']; +- plugin.AnalysisSetPriorityFilesParams result = +- converter.convertAnalysisSetPriorityFilesParams( +- new server.AnalysisSetPriorityFilesParams(files)); +- expect(result, isNotNull); +- expect(result.files, files); +- } +- +- void test_convertAnalysisSetSubscriptionsParams() { +- Map> serverSubscriptions = +- >{ +- server.AnalysisService.HIGHLIGHTS: ['a', 'b'], +- server.AnalysisService.OUTLINE: ['c'], +- server.AnalysisService.OVERRIDES: ['d', 'e'] +- }; +- plugin.AnalysisSetSubscriptionsParams result = +- converter.convertAnalysisSetSubscriptionsParams( +- new server.AnalysisSetSubscriptionsParams(serverSubscriptions)); +- expect(result, isNotNull); +- Map> pluginSubscriptions = +- result.subscriptions; +- expect(pluginSubscriptions, hasLength(2)); +- expect( +- pluginSubscriptions[plugin.AnalysisService.HIGHLIGHTS], hasLength(2)); +- expect(pluginSubscriptions[plugin.AnalysisService.OUTLINE], hasLength(1)); +- } +- +- void test_convertAnalysisUpdateContentParams() { +- Map serverFiles = { +- 'file1': new AddContentOverlay('content1'), +- 'file2': new AddContentOverlay('content2'), +- }; +- plugin.AnalysisUpdateContentParams result = +- converter.convertAnalysisUpdateContentParams( +- new server.AnalysisUpdateContentParams(serverFiles)); +- expect(result, isNotNull); +- Map pluginFiles = result.files; +- expect(pluginFiles, hasLength(2)); +- expect(pluginFiles['file1'], new isInstanceOf()); +- expect(pluginFiles['file2'], new isInstanceOf()); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/result_collector_test.dart b/pkg/analysis_server/test/src/plugin/result_collector_test.dart +deleted file mode 100644 +index e6372c6f268..00000000000 +--- a/pkg/analysis_server/test/src/plugin/result_collector_test.dart ++++ /dev/null +@@ -1,110 +0,0 @@ +-// 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 'package:analysis_server/src/plugin/result_collector.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ResultCollectorTest); +- }); +-} +- +-@reflectiveTest +-class ResultCollectorTest { +- static const String serverId = 'server'; +- +- ResultCollector collector = new ResultCollector(serverId); +- +- void test_clearResultsForFile() { +- String filePath1 = 'test1.dart'; +- String filePath2 = 'test2.dart'; +- String value1 = 'r1'; +- String value2 = 'r2'; +- collector.startCollectingFor(filePath1); +- collector.startCollectingFor(filePath2); +- collector.putResults(filePath1, 'p', value1); +- collector.putResults(filePath2, 'p', value2); +- expect(collector.getResults(filePath1), contains(value1)); +- expect(collector.getResults(filePath2), contains(value2)); +- +- collector.clearResultsForFile(filePath2); +- expect(collector.getResults(filePath1), contains(value1)); +- expect(collector.getResults(filePath2), isEmpty); +- } +- +- void test_clearResultsFromPlugin() { +- String filePath = 'test.dart'; +- String p1Name = 'p1'; +- String p2Name = 'p2'; +- String p1Value = 'r1'; +- String p2Value = 'r2'; +- +- collector.startCollectingFor(filePath); +- collector.putResults(filePath, p1Name, p1Value); +- collector.putResults(filePath, p2Name, p2Value); +- expect(collector.getResults(filePath), contains(p1Value)); +- expect(collector.getResults(filePath), contains(p2Value)); +- +- collector.clearResultsFromPlugin(p1Name); +- expect(collector.getResults(filePath), isNot(contains(p1Value))); +- expect(collector.getResults(filePath), contains(p2Value)); +- } +- +- void test_getResults_emptyCollector() { +- expect(collector.getResults('test.dart'), isEmpty); +- } +- +- void test_getResults_serverFirst() { +- // This is a flaky test in that it is possible for the test to pass even +- // when the code is broken. +- String filePath = 'test.dart'; +- String value1 = 'r1'; +- String value2 = 'r2'; +- collector.startCollectingFor(filePath); +- collector.putResults(filePath, 'p', value1); +- collector.putResults(filePath, serverId, value2); +- expect(collector.getResults(filePath), [value2, value1]); +- } +- +- void test_putResults_collecting() { +- String filePath1 = 'test1.dart'; +- String filePath2 = 'test2.dart'; +- String value1 = 'r1'; +- String value2 = 'r2'; +- expect(collector.getResults(filePath1), isEmpty); +- expect(collector.getResults(filePath2), isEmpty); +- +- collector.startCollectingFor(filePath1); +- collector.startCollectingFor(filePath2); +- collector.putResults(filePath1, 'p', value1); +- collector.putResults(filePath2, 'p', value2); +- expect(collector.getResults(filePath1), contains(value1)); +- expect(collector.getResults(filePath1), isNot(contains(value2))); +- expect(collector.getResults(filePath2), contains(value2)); +- expect(collector.getResults(filePath2), isNot(contains(value1))); +- } +- +- void test_putResults_notCollecting() { +- String filePath = 'test.dart'; +- expect(collector.getResults(filePath), isEmpty); +- +- collector.putResults(filePath, 'p', 'r'); +- expect(collector.getResults(filePath), isEmpty); +- } +- +- void test_stopCollectingFor() { +- String filePath = 'test.dart'; +- String value = 'r'; +- collector.startCollectingFor(filePath); +- collector.putResults(filePath, 'p', value); +- expect(collector.getResults(filePath), contains(value)); +- +- collector.stopCollectingFor(filePath); +- expect(collector.getResults(filePath), isEmpty); +- collector.putResults(filePath, 'p', value); +- expect(collector.getResults(filePath), isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/result_converter_test.dart b/pkg/analysis_server/test/src/plugin/result_converter_test.dart +deleted file mode 100644 +index ffe30cdb91b..00000000000 +--- a/pkg/analysis_server/test/src/plugin/result_converter_test.dart ++++ /dev/null +@@ -1,128 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart' as server; +-import 'package:analysis_server/src/plugin/result_converter.dart'; +-import 'package:analysis_server/src/protocol/protocol_internal.dart' as server; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'protocol_test_utilities.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ResultConverterTest); +- }); +-} +- +-@reflectiveTest +-class ResultConverterTest extends ProtocolTestUtilities { +- static const List strings = const [ +- 'a', +- 'b', +- 'c', +- 'd', +- 'e', +- 'f', +- 'g', +- 'h', +- 'i', +- 'j', +- 'k', +- 'l', +- 'm', +- 'n' +- ]; +- +- ResultConverter converter = new ResultConverter(); +- +- void test_convertAnalysisErrorFixes() { +- AnalysisError error = analysisError(0, 0); +- SourceChange change = sourceChange(4, 4); +- plugin.AnalysisErrorFixes initial = new plugin.AnalysisErrorFixes(error, +- fixes: [ +- new plugin.PrioritizedSourceChange(100, change) +- ]); +- server.AnalysisErrorFixes expected = +- new server.AnalysisErrorFixes(error, fixes: [change]); +- expect(converter.convertAnalysisErrorFixes(initial), expected); +- } +- +- void test_convertAnalysisNavigationParams() { +- plugin.AnalysisNavigationParams initial = +- new plugin.AnalysisNavigationParams('a.dart', [ +- new NavigationRegion(1, 2, [3, 4]) +- ], [ +- new NavigationTarget(ElementKind.FIELD, 5, 6, 7, 8, 9) +- ], [ +- 'a', +- 'b' +- ]); +- server.AnalysisNavigationParams expected = +- new server.AnalysisNavigationParams('a.dart', [ +- new NavigationRegion(1, 2, [3, 4]) +- ], [ +- new NavigationTarget(ElementKind.FIELD, 5, 6, 7, 8, 9) +- ], [ +- 'a', +- 'b' +- ]); +- expect(converter.convertAnalysisNavigationParams(initial), expected); +- } +- +- void test_convertEditGetRefactoringResult_inlineMethod() { +- RefactoringProblem problem1 = refactoringProblem(0, 0); +- RefactoringProblem problem2 = refactoringProblem(2, 4); +- RefactoringProblem problem3 = refactoringProblem(4, 8); +- SourceChange change = sourceChange(6, 12); +- plugin.EditGetRefactoringResult initial = +- new plugin.EditGetRefactoringResult([problem1], +- [problem2], [problem3], +- feedback: +- new plugin.InlineMethodFeedback('a', true, className: 'b'), +- change: change, +- potentialEdits: ['f']); +- server.EditGetRefactoringResult expected = +- new server.EditGetRefactoringResult([problem1], +- [problem2], [problem3], +- feedback: +- new server.InlineMethodFeedback('a', true, className: 'b'), +- change: change, +- potentialEdits: ['f']); +- expect( +- converter.convertEditGetRefactoringResult( +- RefactoringKind.INLINE_METHOD, initial), +- expected); +- } +- +- void test_convertEditGetRefactoringResult_moveFile() { +- RefactoringProblem problem1 = refactoringProblem(0, 0); +- RefactoringProblem problem2 = refactoringProblem(2, 4); +- RefactoringProblem problem3 = refactoringProblem(4, 8); +- SourceChange change = sourceChange(6, 12); +- plugin.EditGetRefactoringResult initial = +- new plugin.EditGetRefactoringResult([problem1], +- [problem2], [problem3], +- feedback: new plugin.MoveFileFeedback(), +- change: change, +- potentialEdits: ['f']); +- server.EditGetRefactoringResult expected = +- new server.EditGetRefactoringResult([problem1], +- [problem2], [problem3], +- change: change, potentialEdits: ['f']); +- expect( +- converter.convertEditGetRefactoringResult( +- RefactoringKind.MOVE_FILE, initial), +- expected); +- } +- +- void test_convertPrioritizedSourceChange() { +- SourceChange change = sourceChange(0, 0); +- plugin.PrioritizedSourceChange initial = +- new plugin.PrioritizedSourceChange(100, change); +- expect(converter.convertPrioritizedSourceChange(initial), change); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/result_merger_test.dart b/pkg/analysis_server/test/src/plugin/result_merger_test.dart +deleted file mode 100644 +index 98a63fda6b5..00000000000 +--- a/pkg/analysis_server/test/src/plugin/result_merger_test.dart ++++ /dev/null +@@ -1,738 +0,0 @@ +-// 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 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analysis_server/src/plugin/result_merger.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(ResultMergerTest); +- }); +-} +- +-@reflectiveTest +-class ResultMergerTest { +- // +- // The tests in this class should always perform the merge operation twice +- // using the same input values in order to ensure that the input values are +- // not modified by the merge operation. +- // +- +- ResultMerger merger = new ResultMerger(); +- +- void test_mergeAnalysisErrorFixes() { +- AnalysisError createError(int offset) { +- AnalysisErrorSeverity severity = AnalysisErrorSeverity.ERROR; +- AnalysisErrorType type = AnalysisErrorType.HINT; +- Location location = new Location('test.dart', offset, 2, 3, 4); +- return new AnalysisError(severity, type, location, '', ''); +- } +- +- AnalysisError error1 = createError(10); +- AnalysisError error2 = createError(20); +- AnalysisError error3 = createError(30); +- AnalysisError error4 = createError(40); +- plugin.PrioritizedSourceChange change1 = +- new plugin.PrioritizedSourceChange(1, new SourceChange('a')); +- plugin.PrioritizedSourceChange change2 = +- new plugin.PrioritizedSourceChange(2, new SourceChange('b')); +- plugin.PrioritizedSourceChange change3 = +- new plugin.PrioritizedSourceChange(3, new SourceChange('c')); +- plugin.PrioritizedSourceChange change4 = +- new plugin.PrioritizedSourceChange(4, new SourceChange('d')); +- plugin.PrioritizedSourceChange change5 = +- new plugin.PrioritizedSourceChange(5, new SourceChange('e')); +- plugin.AnalysisErrorFixes fix1 = +- new plugin.AnalysisErrorFixes(error1, fixes: [change1]); +- plugin.AnalysisErrorFixes fix2 = +- new plugin.AnalysisErrorFixes(error2, fixes: [change2]); +- plugin.AnalysisErrorFixes fix3 = +- new plugin.AnalysisErrorFixes(error2, fixes: [change3]); +- plugin.AnalysisErrorFixes fix4 = +- new plugin.AnalysisErrorFixes(error3, fixes: [change4]); +- plugin.AnalysisErrorFixes fix5 = +- new plugin.AnalysisErrorFixes(error4, fixes: [change5]); +- plugin.AnalysisErrorFixes fix2and3 = +- new plugin.AnalysisErrorFixes(error2, fixes: [change2, change3]); +- +- void runTest() { +- expect( +- merger.mergeAnalysisErrorFixes([ +- [fix1, fix2], +- [fix3, fix4], +- [fix5], +- [] +- ]), +- unorderedEquals([fix1, fix2and3, fix4, fix5])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeAnalysisErrors() { +- AnalysisError createError(int offset) { +- AnalysisErrorSeverity severity = AnalysisErrorSeverity.ERROR; +- AnalysisErrorType type = AnalysisErrorType.HINT; +- Location location = new Location('test.dart', offset, 2, 3, 4); +- return new AnalysisError(severity, type, location, '', ''); +- } +- +- AnalysisError error1 = createError(10); +- AnalysisError error2 = createError(20); +- AnalysisError error3 = createError(30); +- AnalysisError error4 = createError(40); +- +- void runTest() { +- expect( +- merger.mergeAnalysisErrors([ +- [error1, error2], +- [error3], +- [], +- [error4] +- ]), +- unorderedEquals([error1, error2, error3, error4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeCompletionSuggestions() { +- CompletionSuggestion createSuggestion(String completion) => +- new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER, 50, +- completion, 0, 3, false, false); +- +- CompletionSuggestion suggestion1 = createSuggestion('a'); +- CompletionSuggestion suggestion2 = createSuggestion('b'); +- CompletionSuggestion suggestion3 = createSuggestion('c'); +- CompletionSuggestion suggestion4 = createSuggestion('d'); +- +- void runTest() { +- expect( +- merger.mergeCompletionSuggestions([ +- [suggestion1], +- [suggestion2, suggestion3, suggestion4], +- [] +- ]), +- unorderedEquals( +- [suggestion1, suggestion2, suggestion3, suggestion4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeFoldingRegion() { +- FoldingKind kind = FoldingKind.COMMENT; +- FoldingRegion region1 = new FoldingRegion(kind, 30, 5); +- FoldingRegion region2 = new FoldingRegion(kind, 0, 4); +- FoldingRegion region3 = new FoldingRegion(kind, 20, 6); +- FoldingRegion region4 = new FoldingRegion(kind, 10, 3); +- FoldingRegion region5 = new FoldingRegion(kind, 2, 6); // overlaps +- +- void runTest() { +- expect( +- merger.mergeFoldingRegions([ +- [region1, region2], +- [], +- [region3], +- [region4, region5] +- ]), +- unorderedEquals([region1, region2, region3, region4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeHighlightRegions() { +- HighlightRegionType type = HighlightRegionType.COMMENT_BLOCK; +- HighlightRegion region1 = new HighlightRegion(type, 30, 5); +- HighlightRegion region2 = new HighlightRegion(type, 0, 4); +- HighlightRegion region3 = new HighlightRegion(type, 20, 6); +- HighlightRegion region4 = new HighlightRegion(type, 10, 3); +- +- void runTest() { +- expect( +- merger.mergeHighlightRegions([ +- [region1, region2], +- [], +- [region3], +- [region4] +- ]), +- unorderedEquals([region1, region2, region3, region4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeNavigation() { +- NavigationTarget target(int fileIndex, int offset) { +- return new NavigationTarget( +- ElementKind.CLASS, fileIndex, offset, 1, 0, 0); +- } +- +- // +- // Create the parameters from the server. +- // +- NavigationTarget target1_1 = target(0, 1); +- NavigationTarget target1_2 = target(0, 2); +- NavigationTarget target2_1 = target(1, 3); +- NavigationTarget target2_2 = target(1, 4); +- NavigationRegion region1_1 = new NavigationRegion(10, 4, [0]); +- NavigationRegion region1_2 = new NavigationRegion(20, 4, [1]); +- NavigationRegion region2_1 = new NavigationRegion(30, 4, [2]); +- NavigationRegion region2_2 = new NavigationRegion(40, 4, [3]); +- AnalysisNavigationParams params1 = new AnalysisNavigationParams( +- 'a.dart', +- [region1_1, region1_2, region2_1, region2_2], +- [target1_1, target1_2, target2_1, target2_2], +- ['one.dart', 'two.dart']); +- // +- // Create the parameters from the second plugin. +- // +- // same file and offset as target 2_2 +- NavigationTarget target2_3 = target(0, 4); +- NavigationTarget target2_4 = target(0, 5); +- NavigationTarget target3_1 = target(1, 6); +- NavigationTarget target3_2 = target(1, 7); +- // same region and target as region2_2 +- NavigationRegion region2_3 = new NavigationRegion(40, 4, [0]); +- // same region as region2_2, but a different target +- NavigationRegion region2_4 = new NavigationRegion(40, 4, [2]); +- NavigationRegion region2_5 = new NavigationRegion(50, 4, [1]); +- NavigationRegion region3_1 = new NavigationRegion(60, 4, [2]); +- NavigationRegion region3_2 = new NavigationRegion(70, 4, [3]); +- AnalysisNavigationParams params2 = new AnalysisNavigationParams( +- 'a.dart', +- [region2_3, region2_4, region2_5, region3_1, region3_2], +- [target2_3, target2_4, target3_1, target3_2], +- ['two.dart', 'three.dart']); +- AnalysisNavigationParams expected = new AnalysisNavigationParams('a.dart', [ +- region1_1, +- region1_2, +- region2_1, +- new NavigationRegion(40, 4, [3, 5]), // union of region2_2 and region2_4 +- new NavigationRegion(50, 4, [4]), // region2_5 +- new NavigationRegion(60, 4, [5]), // region3_1 +- new NavigationRegion(70, 4, [6]), // region3_2 +- ], [ +- target1_1, +- target1_2, +- target2_1, +- target2_2, +- target(1, 5), // target2_4 +- target(2, 6), // target3_1 +- target(2, 7), // target3_2 +- ], [ +- 'one.dart', +- 'two.dart', +- 'three.dart' +- ]); +- +- void runTest() { +- expect(merger.mergeNavigation([params1, params2]), expected); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeOccurrences() { +- Element element1 = new Element(ElementKind.CLASS, 'e1', 0); +- Element element2 = new Element(ElementKind.CLASS, 'e2', 0); +- Element element3 = new Element(ElementKind.CLASS, 'e3', 0); +- Occurrences occurrence1 = new Occurrences(element1, [1, 2, 4], 2); +- Occurrences occurrence2 = new Occurrences(element2, [5], 2); +- Occurrences occurrence3 = new Occurrences(element1, [2, 3], 2); +- Occurrences occurrence4 = new Occurrences(element3, [8], 2); +- Occurrences occurrence5 = new Occurrences(element2, [6], 2); +- Occurrences occurrence6 = new Occurrences(element3, [7, 9], 2); +- Occurrences result1 = new Occurrences(element1, [1, 2, 3, 4], 2); +- Occurrences result2 = new Occurrences(element2, [5, 6], 2); +- Occurrences result3 = new Occurrences(element3, [7, 8, 9], 2); +- +- void runTest() { +- expect( +- merger.mergeOccurrences([ +- [occurrence1, occurrence2], +- [], +- [occurrence3, occurrence4], +- [occurrence5, occurrence6] +- ]), +- unorderedEquals([result1, result2, result3])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeOutline() { +- Element element(ElementKind kind, int offset) { +- Location location = new Location('', offset, 0, 0, 0); +- return new Element(kind, '', 0, location: location); +- } +- +- Element element1 = element(ElementKind.CLASS, 100); +- Element element1_1 = element(ElementKind.METHOD, 110); +- Element element1_2 = element(ElementKind.METHOD, 120); +- Element element2 = element(ElementKind.CLASS, 200); +- Element element2_1 = element(ElementKind.METHOD, 210); +- Element element2_2 = element(ElementKind.METHOD, 220); +- Element element3_1 = element(ElementKind.METHOD, 220); // same as 2_2 +- Element element3_2 = element(ElementKind.METHOD, 230); +- Element element4 = element(ElementKind.CLASS, 300); +- Element element4_1 = element(ElementKind.METHOD, 310); +- // +- // Unique, contributed from first plugin. +- // +- // element1 +- // - element1_1 +- // - element1_2 +- // +- Outline outline1_1 = new Outline(element1_1, 0, 0, children: []); +- Outline outline1_2 = new Outline(element1_2, 0, 0, children: []); +- Outline outline1 = +- new Outline(element1, 0, 0, children: [outline1_1, outline1_2]); +- // +- // Same top level element, common child. +- // +- // element2 +- // - element2_1 +- // - element2_2 +- // element2 +- // - element3_1 +- // - element3_2 +- // +- Outline outline2_1 = new Outline(element2_1, 0, 0, children: []); +- Outline outline2_2 = new Outline(element2_2, 0, 0, children: []); +- Outline outline3_1 = new Outline(element3_1, 0, 0, children: []); +- Outline outline3_2 = new Outline(element3_2, 0, 0, children: []); +- Outline outline2 = +- new Outline(element2, 0, 0, children: [outline2_1, outline2_2]); +- Outline outline3 = +- new Outline(element2, 0, 0, children: [outline3_1, outline3_2]); +- Outline outline2and3 = new Outline(element2, 0, 0, +- children: [outline2_1, outline2_2, outline3_2]); +- // +- // Unique, contributed from second plugin. +- // +- // element4 +- // - element4_1 +- // +- Outline outline4_1 = new Outline(element4_1, 0, 0, children: []); +- Outline outline4 = new Outline(element4, 0, 0, children: [outline4_1]); +- +- void runTest() { +- expect( +- merger.mergeOutline([ +- [outline1, outline2], +- [], +- [outline3, outline4] +- ]), +- unorderedEquals([outline1, outline2and3, outline4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergePrioritizedSourceChanges() { +- plugin.PrioritizedSourceChange kind1 = +- new plugin.PrioritizedSourceChange(1, new SourceChange('')); +- plugin.PrioritizedSourceChange kind2 = +- new plugin.PrioritizedSourceChange(1, new SourceChange('')); +- plugin.PrioritizedSourceChange kind3 = +- new plugin.PrioritizedSourceChange(1, new SourceChange('')); +- plugin.PrioritizedSourceChange kind4 = +- new plugin.PrioritizedSourceChange(1, new SourceChange('')); +- +- void runTest() { +- expect( +- merger.mergePrioritizedSourceChanges([ +- [kind3, kind2], +- [], +- [kind4], +- [kind1] +- ]), +- unorderedEquals([kind1, kind2, kind3, kind4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_convertGetterToMethodFeedback() { +- RefactoringFeedback feedback1 = new ConvertGetterToMethodFeedback(); +- RefactoringFeedback feedback2 = new ConvertGetterToMethodFeedback(); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(feedback1)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_convertMethodToGetterFeedback() { +- RefactoringFeedback feedback1 = new ConvertMethodToGetterFeedback(); +- RefactoringFeedback feedback2 = new ConvertMethodToGetterFeedback(); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(feedback1)); +- } +- +- runTest(); +- runTest(); +- } +- +- void +- test_mergeRefactoringFeedbacks_extractLocalVariableFeedback_addEverything() { +- List names1 = ['a', 'b', 'c']; +- List offsets1 = [10, 20]; +- List lengths1 = [4, 5]; +- List coveringOffsets1 = [100, 150, 200]; +- List coveringLengths1 = [200, 100, 20]; +- RefactoringFeedback feedback1 = new ExtractLocalVariableFeedback( +- names1, offsets1, lengths1, +- coveringExpressionOffsets: coveringOffsets1, +- coveringExpressionLengths: coveringLengths1); +- List names2 = ['c', 'd']; +- List offsets2 = [30]; +- List lengths2 = [6]; +- List coveringOffsets2 = [210]; +- List coveringLengths2 = [5]; +- RefactoringFeedback feedback2 = new ExtractLocalVariableFeedback( +- names2, offsets2, lengths2, +- coveringExpressionOffsets: coveringOffsets2, +- coveringExpressionLengths: coveringLengths2); +- List resultNames = ['a', 'b', 'c', 'd']; +- List resultOffsets = new List.from(offsets1)..addAll(offsets2); +- List resultLengths = new List.from(lengths1)..addAll(lengths2); +- List resultCoveringOffsets = new List.from(coveringOffsets1) +- ..addAll(coveringOffsets2); +- List resultCoveringLengths = new List.from(coveringLengths1) +- ..addAll(coveringLengths2); +- RefactoringFeedback result = new ExtractLocalVariableFeedback( +- resultNames, resultOffsets, resultLengths, +- coveringExpressionOffsets: resultCoveringOffsets, +- coveringExpressionLengths: resultCoveringLengths); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(result)); +- } +- +- runTest(); +- runTest(); +- } +- +- void +- test_mergeRefactoringFeedbacks_extractLocalVariableFeedback_addOffsetsAndLengths() { +- List names1 = ['a', 'b', 'c']; +- List offsets1 = [10, 20]; +- List lengths1 = [4, 5]; +- List coveringOffsets1 = [100, 150, 200]; +- List coveringLengths1 = [200, 100, 20]; +- RefactoringFeedback feedback1 = new ExtractLocalVariableFeedback( +- names1, offsets1, lengths1, +- coveringExpressionOffsets: coveringOffsets1, +- coveringExpressionLengths: coveringLengths1); +- List names2 = []; +- List offsets2 = [30]; +- List lengths2 = [6]; +- RefactoringFeedback feedback2 = +- new ExtractLocalVariableFeedback(names2, offsets2, lengths2); +- List resultOffsets = new List.from(offsets1)..addAll(offsets2); +- List resultLengths = new List.from(lengths1)..addAll(lengths2); +- RefactoringFeedback result = new ExtractLocalVariableFeedback( +- names1, resultOffsets, resultLengths, +- coveringExpressionOffsets: coveringOffsets1, +- coveringExpressionLengths: coveringLengths1); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(result)); +- } +- +- runTest(); +- runTest(); +- } +- +- void +- test_mergeRefactoringFeedbacks_extractLocalVariableFeedback_noCoverings() { +- List names1 = ['a', 'b', 'c']; +- List offsets1 = [10, 20]; +- List lengths1 = [4, 5]; +- RefactoringFeedback feedback1 = +- new ExtractLocalVariableFeedback(names1, offsets1, lengths1); +- List names2 = []; +- List offsets2 = [30]; +- List lengths2 = [6]; +- RefactoringFeedback feedback2 = +- new ExtractLocalVariableFeedback(names2, offsets2, lengths2); +- List resultOffsets = new List.from(offsets1)..addAll(offsets2); +- List resultLengths = new List.from(lengths1)..addAll(lengths2); +- RefactoringFeedback result = +- new ExtractLocalVariableFeedback(names1, resultOffsets, resultLengths); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(result)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_extractMethodFeedback() { +- int offset1 = 20; +- int length1 = 5; +- String returnType1 = 'int'; +- List names1 = ['a', 'b', 'c']; +- bool canCreateGetter1 = false; +- List parameters1 = +- []; +- List offsets1 = [10, 20]; +- List lengths1 = [4, 5]; +- RefactoringFeedback feedback1 = new ExtractMethodFeedback(offset1, length1, +- returnType1, names1, canCreateGetter1, parameters1, offsets1, lengths1); +- List names2 = ['c', 'd']; +- bool canCreateGetter2 = true; +- List parameters2 = +- []; +- List offsets2 = [30]; +- List lengths2 = [6]; +- RefactoringFeedback feedback2 = new ExtractMethodFeedback( +- 0, 0, '', names2, canCreateGetter2, parameters2, offsets2, lengths2); +- List resultNames = ['a', 'b', 'c', 'd']; +- List resultOffsets = new List.from(offsets1)..addAll(offsets2); +- List resultLengths = new List.from(lengths1)..addAll(lengths2); +- RefactoringFeedback result = new ExtractMethodFeedback( +- offset1, +- length1, +- returnType1, +- resultNames, +- false, +- parameters1, +- resultOffsets, +- resultLengths); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(result)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_inlineLocalVariableFeedback() { +- RefactoringFeedback feedback1 = new InlineLocalVariableFeedback('a', 2); +- RefactoringFeedback feedback2 = new InlineLocalVariableFeedback('a', 3); +- RefactoringFeedback result = new InlineLocalVariableFeedback('a', 5); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(result)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_inlineMethodFeedback() { +- RefactoringFeedback feedback1 = new InlineMethodFeedback('a', false); +- RefactoringFeedback feedback2 = new InlineMethodFeedback('a', false); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(feedback1)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_moveFileFeedback() { +- RefactoringFeedback feedback1 = new MoveFileFeedback(); +- RefactoringFeedback feedback2 = new MoveFileFeedback(); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(feedback1)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringFeedbacks_renameFeedback() { +- RefactoringFeedback feedback1 = new RenameFeedback(10, 0, '', ''); +- RefactoringFeedback feedback2 = new RenameFeedback(20, 0, '', ''); +- +- void runTest() { +- expect(merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- equals(feedback1)); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactoringKinds() { +- RefactoringKind kind1 = RefactoringKind.CONVERT_GETTER_TO_METHOD; +- RefactoringKind kind2 = RefactoringKind.EXTRACT_LOCAL_VARIABLE; +- RefactoringKind kind3 = RefactoringKind.INLINE_LOCAL_VARIABLE; +- RefactoringKind kind4 = RefactoringKind.MOVE_FILE; +- RefactoringKind kind5 = RefactoringKind.EXTRACT_LOCAL_VARIABLE; +- +- void runTest() { +- expect( +- merger.mergeRefactoringKinds([ +- [kind1, kind2], +- [kind3], +- [], +- [kind4, kind5] +- ]), +- unorderedEquals([kind1, kind2, kind3, kind4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeRefactorings() { +- RefactoringProblem problem(String message) => +- new RefactoringProblem(RefactoringProblemSeverity.ERROR, message); +- RefactoringProblem problem1 = problem('1'); +- RefactoringProblem problem2 = problem('2'); +- RefactoringProblem problem3 = problem('3'); +- RefactoringProblem problem4 = problem('4'); +- RefactoringProblem problem5 = problem('5'); +- RefactoringProblem problem6 = problem('6'); +- +- List initialProblems1 = [ +- problem1, +- problem2 +- ]; +- List optionsProblems1 = [problem3]; +- List finalProblems1 = [problem4]; +- RefactoringFeedback feedback1 = new RenameFeedback(10, 0, '', ''); +- SourceFileEdit edit1 = +- new SourceFileEdit('file1.dart', 11, edits: [ +- new SourceEdit(12, 2, 'w', id: 'e1'), +- new SourceEdit(13, 3, 'x'), +- ]); +- SourceChange change1 = +- new SourceChange('c1', edits: [edit1]); +- List potentialEdits1 = ['e1']; +- EditGetRefactoringResult result1 = new EditGetRefactoringResult( +- initialProblems1, optionsProblems1, finalProblems1, +- feedback: feedback1, change: change1, potentialEdits: potentialEdits1); +- List initialProblems2 = [problem5]; +- List optionsProblems2 = []; +- List finalProblems2 = [problem6]; +- RefactoringFeedback feedback2 = new RenameFeedback(20, 0, '', ''); +- SourceFileEdit edit2 = +- new SourceFileEdit('file2.dart', 21, edits: [ +- new SourceEdit(12, 2, 'y', id: 'e2'), +- new SourceEdit(13, 3, 'z'), +- ]); +- SourceChange change2 = +- new SourceChange('c2', edits: [edit2]); +- List potentialEdits2 = ['e2']; +- EditGetRefactoringResult result2 = new EditGetRefactoringResult( +- initialProblems2, optionsProblems2, finalProblems2, +- feedback: feedback2, change: change2, potentialEdits: potentialEdits2); +- List mergedInitialProblems = [ +- problem1, +- problem2, +- problem5 +- ]; +- List mergedOptionsProblems = [ +- problem3 +- ]; +- List mergedFinalProblems = [ +- problem4, +- problem6 +- ]; +- SourceChange mergedChange = +- new SourceChange('c1', edits: [edit1, edit2]); +- List mergedPotentialEdits = ['e1', 'e2']; +- EditGetRefactoringResult mergedResult = new EditGetRefactoringResult( +- mergedInitialProblems, mergedOptionsProblems, mergedFinalProblems, +- feedback: merger.mergeRefactoringFeedbacks([feedback1, feedback2]), +- change: mergedChange, +- potentialEdits: mergedPotentialEdits); +- +- void runTest() { +- expect(merger.mergeRefactorings([result1, result2]), mergedResult); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_mergeSourceChanges() { +- SourceChange kind1 = new SourceChange(''); +- SourceChange kind2 = new SourceChange(''); +- SourceChange kind3 = new SourceChange(''); +- SourceChange kind4 = new SourceChange(''); +- +- void runTest() { +- expect( +- merger.mergeSourceChanges([ +- [kind1, kind2], +- [], +- [kind3], +- [kind4] +- ]), +- unorderedEquals([kind1, kind2, kind3, kind4])); +- } +- +- runTest(); +- runTest(); +- } +- +- void test_overlaps_false_nested_left() { +- expect(merger.overlaps(3, 5, 1, 7, allowNesting: true), isFalse); +- } +- +- void test_overlaps_false_nested_right() { +- expect(merger.overlaps(1, 7, 3, 5, allowNesting: true), isFalse); +- } +- +- void test_overlaps_false_onLeft() { +- expect(merger.overlaps(1, 3, 5, 7), isFalse); +- } +- +- void test_overlaps_false_onRight() { +- expect(merger.overlaps(5, 7, 1, 3), isFalse); +- } +- +- void test_overlaps_true_nested_left() { +- expect(merger.overlaps(3, 5, 1, 7), isTrue); +- } +- +- void test_overlaps_true_nested_right() { +- expect(merger.overlaps(1, 7, 3, 5), isTrue); +- } +- +- void test_overlaps_true_onLeft() { +- expect(merger.overlaps(1, 5, 3, 7), isTrue); +- } +- +- void test_overlaps_true_onRight() { +- expect(merger.overlaps(3, 7, 1, 5), isTrue); +- } +-} +diff --git a/pkg/analysis_server/test/src/plugin/test_all.dart b/pkg/analysis_server/test/src/plugin/test_all.dart +deleted file mode 100644 +index a1f75646d00..00000000000 +--- a/pkg/analysis_server/test/src/plugin/test_all.dart ++++ /dev/null +@@ -1,27 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'notification_manager_test.dart' as notification_manager_test; +-import 'plugin_locator_test.dart' as plugin_locator_test; +-import 'plugin_manager_test.dart' as plugin_manager_test; +-import 'plugin_watcher_test.dart' as plugin_watcher_test; +-import 'request_converter_test.dart' as request_converter_test; +-import 'result_collector_test.dart' as result_collector_test; +-import 'result_converter_test.dart' as result_converter_test; +-import 'result_merger_test.dart' as result_merger_test; +- +-main() { +- defineReflectiveSuite(() { +- notification_manager_test.main(); +- plugin_locator_test.main(); +- plugin_manager_test.main(); +- plugin_watcher_test.main(); +- request_converter_test.main(); +- result_collector_test.main(); +- result_converter_test.main(); +- result_merger_test.main(); +- }); +-} +diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart +deleted file mode 100644 +index 70858b061d0..00000000000 +--- a/pkg/analysis_server/test/src/test_all.dart ++++ /dev/null +@@ -1,24 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'computer/test_all.dart' as computer_all; +-import 'domain_abstract_test.dart' as domain_abstract_test; +-import 'plugin/test_all.dart' as plugin_all; +-import 'utilities/test_all.dart' as utilities_all; +-import 'watch_manager_test.dart' as watch_manager_test; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- defineReflectiveSuite(() { +- computer_all.main(); +- domain_abstract_test.main(); +- plugin_all.main(); +- utilities_all.main(); +- watch_manager_test.main(); +- }, name: 'src'); +-} +diff --git a/pkg/analysis_server/test/src/utilities/flutter_test.dart b/pkg/analysis_server/test/src/utilities/flutter_test.dart +deleted file mode 100644 +index 26e38eb9a81..00000000000 +--- a/pkg/analysis_server/test/src/utilities/flutter_test.dart ++++ /dev/null +@@ -1,156 +0,0 @@ +-// 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 'package:analysis_server/src/utilities/flutter.dart'; +-import 'package:analyzer/dart/ast/ast.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../../abstract_single_unit.dart'; +-import 'flutter_util.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(FlutterTest); +- }); +-} +- +-@reflectiveTest +-class FlutterTest extends AbstractSingleUnitTest { +- @override +- void setUp() { +- super.setUp(); +- Folder libFolder = configureFlutterPackage(provider); +- packageMap['flutter'] = [libFolder]; +- } +- +- test_getWidgetPresentationText_icon() async { +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = const Icon(Icons.book); +-'''); +- var w = _getTopVariableCreation('w'); +- expect(getWidgetPresentationText(w), "Icon(Icons.book)"); +- } +- +- test_getWidgetPresentationText_icon_withoutArguments() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = const Icon(); +-'''); +- var w = _getTopVariableCreation('w'); +- expect(getWidgetPresentationText(w), "Icon"); +- } +- +- test_getWidgetPresentationText_notWidget() async { +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = new Object(); +-'''); +- var w = _getTopVariableCreation('w'); +- expect(getWidgetPresentationText(w), isNull); +- } +- +- test_getWidgetPresentationText_text() async { +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = const Text('foo'); +-'''); +- var w = _getTopVariableCreation('w'); +- expect(getWidgetPresentationText(w), "Text('foo')"); +- } +- +- test_getWidgetPresentationText_text_longText() async { +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = const Text('${'abc' * 100}'); +-'''); +- var w = _getTopVariableCreation('w'); +- expect( +- getWidgetPresentationText(w), "Text('abcabcabcabcab...cabcabcabcabc')"); +- } +- +- test_getWidgetPresentationText_text_withoutArguments() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = const Text(); +-'''); +- var w = _getTopVariableCreation('w'); +- expect(getWidgetPresentationText(w), "Text"); +- } +- +- test_getWidgetPresentationText_unresolved() async { +- verifyNoTestUnitErrors = false; +- await resolveTestUnit(''' +-import 'package:flutter/material.dart'; +-var w = new Foo(); +-'''); +- var w = _getTopVariableCreation('w'); +- expect(getWidgetPresentationText(w), isNull); +- } +- +- test_isWidget() async { +- await resolveTestUnit(''' +-import 'package:flutter/widgets.dart'; +- +-class MyStatelessWidget extends StatelessWidget {} +-class MyStatefulWidget extends StatefulWidget {} +-class MyContainer extends Container {} +-class NotFlutter {} +-class NotWidget extends State {} +-'''); +- var myStatelessWidget = testUnitElement.getType('MyStatelessWidget'); +- expect(isWidget(myStatelessWidget), isTrue); +- +- var myStatefulWidget = testUnitElement.getType('MyStatefulWidget'); +- expect(isWidget(myStatefulWidget), isTrue); +- +- var myContainer = testUnitElement.getType('MyContainer'); +- expect(isWidget(myContainer), isTrue); +- +- var notFlutter = testUnitElement.getType('NotFlutter'); +- expect(isWidget(notFlutter), isFalse); +- +- var notWidget = testUnitElement.getType('NotWidget'); +- expect(isWidget(notWidget), isFalse); +- } +- +- test_isWidgetCreation() async { +- await resolveTestUnit(''' +-import 'package:flutter/widgets.dart'; +- +-var a = new Object(); +-var b = new Text('bbb'); +-'''); +- InstanceCreationExpression a = _getTopVariableCreation('a'); +- expect(isWidgetCreation(a), isFalse); +- +- InstanceCreationExpression b = _getTopVariableCreation('b'); +- expect(isWidgetCreation(b), isTrue); +- } +- +- VariableDeclaration _getTopVariable(String name, [CompilationUnit unit]) { +- unit ??= testUnit; +- for (var topDeclaration in unit.declarations) { +- if (topDeclaration is TopLevelVariableDeclaration) { +- for (var variable in topDeclaration.variables.variables) { +- if (variable.name.name == name) { +- return variable; +- } +- } +- } +- } +- fail('Not found $name in $unit'); +- return null; +- } +- +- InstanceCreationExpression _getTopVariableCreation(String name, +- [CompilationUnit unit]) { +- return _getTopVariable(name, unit).initializer +- as InstanceCreationExpression; +- } +-} +diff --git a/pkg/analysis_server/test/src/utilities/flutter_util.dart b/pkg/analysis_server/test/src/utilities/flutter_util.dart +deleted file mode 100644 +index 5ff909a0c2d..00000000000 +--- a/pkg/analysis_server/test/src/utilities/flutter_util.dart ++++ /dev/null +@@ -1,205 +0,0 @@ +-// 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 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +- +-String flutterPkgLibPath = '/packages/flutter/lib'; +- +-String get flutter_framework_code => ''' +-class Widget {} +-class RenderObjectWidget extends Widget {} +-class StatelessWidget extends Widget {} +-abstract class StatefulWidget extends Widget { } +-class SingleChildRenderObjectWidget extends RenderObjectWidget {} +-class Transform extends SingleChildRenderObjectWidget {} +-class ClipRect extends SingleChildRenderObjectWidget { ClipRect.rect(){} } +-class AspectRatio extends SingleChildRenderObjectWidget {} +-class Container extends StatelessWidget { Container({child: null, width: null, height: null}){}} +-class Center extends StatelessWidget { Center({child: null, key: null}){}} +-class DefaultTextStyle extends StatelessWidget { DefaultTextStyle({child: null}){}} +-class Row extends Widget { Row({List children: null, key: null}){}} +-class GestureDetector extends SingleChildRenderObjectWidget { GestureDetector({child: null, onTap: null}){}} +-class AppBar extends StatefulWidget implements PreferredSizeWidget { AppBar(title: null, color: null, key: null) } +-class Scaffold extends Widget { Scaffold({body: null, PreferredSizeWidget appBar: null}){}} +-class PreferredSizeWidget implements Widget {} +-'''; +- +-/** +- * Add some Flutter libraries and types to the given [provider] and return +- * the `lib` folder. +- */ +-Folder configureFlutterPackage(MemoryResourceProvider provider) { +- File newFile(String path, String content) => +- provider.newFile(provider.convertPath(path), content ?? ''); +- +- Folder newFolder(String path) => +- provider.newFolder(provider.convertPath(path)); +- +- newFile('/flutter/lib/material.dart', r''' +-export 'widgets.dart'; +-export 'src/material/icons.dart'; +-'''); +- +- newFile('/flutter/lib/widgets.dart', r''' +-export 'src/widgets/basic.dart'; +-export 'src/widgets/container.dart'; +-export 'src/widgets/framework.dart'; +-export 'src/widgets/icon.dart'; +-export 'src/widgets/text.dart'; +-'''); +- +- void createSrcMaterial() { +- newFile('/flutter/lib/src/material/icons.dart', r''' +-import 'package:flutter/widgets.dart'; +- +-class Icons { +- static const IconData alarm = +- const IconData(0xe855, fontFamily: 'MaterialIcons'); +- static const IconData book = +- const IconData(0xe865, fontFamily: 'MaterialIcons'); +- Icons._(); +-} +-'''); +- } +- +- void createSrcWidgets() { +- newFile('/flutter/lib/src/widgets/basic.dart', r''' +-import 'framework.dart'; +- +-class Column extends Flex { +- Column({ +- Key key, +- List children: const [], +- }); +-} +- +-class Row extends Flex { +- Row({ +- Key key, +- List children: const [], +- }); +-} +- +-class Flex extends Widget { +- Flex({ +- Key key, +- List children: const [], +- }); +-} +-'''); +- +- newFile('/flutter/lib/src/widgets/container.dart', r''' +-import 'framework.dart'; +- +-class Container extends StatelessWidget { +- final Widget child; +- Container({ +- Key key, +- double width, +- double height, +- this.child, +- }) +- : super(key: key); +- +- @override +- Widget build(BuildContext context) => child; +-} +-'''); +- +- newFile('/flutter/lib/src/widgets/framework.dart', r''' +-typedef void VoidCallback(); +- +-abstract class BuildContext { +- Widget get widget; +-} +- +-abstract class Key { +- const factory Key(String value) = ValueKey; +- +- const Key._(); +-} +- +-abstract class LocalKey extends Key { +- const LocalKey() : super._(); +-} +- +-abstract class State { +- BuildContext get context => null; +- +- T get widget => null; +- +- Widget build(BuildContext context) {} +- +- void dispose() {} +- +- void setState(VoidCallback fn) {} +-} +- +-abstract class StatefulWidget extends Widget { +- const StatefulWidget({Key key}) : super(key: key); +- +- State createState() => null +-} +- +-abstract class StatelessWidget extends Widget { +- const StatelessWidget({Key key}) : super(key: key); +- +- Widget build(BuildContext context) => null; +-} +- +-class ValueKey extends LocalKey { +- final T value; +- +- const ValueKey(this.value); +-} +- +-class Widget { +- final Key key; +- +- const Widget({this.key}); +-} +-'''); +- +- newFile('/flutter/lib/src/widgets/icon.dart', r''' +-import 'framework.dart'; +- +-class Icon extends StatelessWidget { +- final IconData icon; +- const Icon( +- this.icon, { +- Key key, +- }) +- : super(key: key); +-} +- +-class IconData { +- final int codePoint; +- final String fontFamily; +- const IconData( +- this.codePoint, { +- this.fontFamily, +- }); +-} +-'''); +- +- newFile('/flutter/lib/src/widgets/text.dart', r''' +-import 'framework.dart'; +- +-class Text extends StatelessWidget { +- final String data; +- const Text( +- this.data, { +- Key key, +- }) +- : super(key: key); +-} +-'''); +- } +- +- createSrcMaterial(); +- createSrcWidgets(); +- +- return newFolder('/flutter/lib'); +-} +diff --git a/pkg/analysis_server/test/src/utilities/profiling_test.dart b/pkg/analysis_server/test/src/utilities/profiling_test.dart +deleted file mode 100644 +index 4906c4bc7b7..00000000000 +--- a/pkg/analysis_server/test/src/utilities/profiling_test.dart ++++ /dev/null +@@ -1,30 +0,0 @@ +-// 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:io'; +- +-import 'package:analysis_server/src/utilities/profiling.dart'; +-import 'package:test/test.dart'; +- +-main() { +- group('ProcessProfiler', () { +- // Skip on windows. +- if (Platform.isWindows) { +- return; +- } +- +- test('getProfilerForPlatform', () async { +- expect(ProcessProfiler.getProfilerForPlatform(), isNotNull); +- }); +- +- test('getProcessUsage', () async { +- ProcessProfiler profiler = ProcessProfiler.getProfilerForPlatform(); +- UsageInfo info = await profiler.getProcessUsage(pid); +- +- expect(info, isNotNull); +- expect(info.cpuPercentage, greaterThanOrEqualTo(0.0)); +- expect(info.memoryKB, greaterThanOrEqualTo(0)); +- }); +- }); +-} +diff --git a/pkg/analysis_server/test/src/utilities/test_all.dart b/pkg/analysis_server/test/src/utilities/test_all.dart +deleted file mode 100644 +index cf5d6fca361..00000000000 +--- a/pkg/analysis_server/test/src/utilities/test_all.dart ++++ /dev/null +@@ -1,15 +0,0 @@ +-// 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 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import 'flutter_test.dart' as flutter_test; +-import 'profiling_test.dart' as profiling_test; +- +-main() { +- defineReflectiveSuite(() { +- flutter_test.main(); +- profiling_test.main(); +- }); +-} +diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart +deleted file mode 100644 +index 19b72c91f58..00000000000 +--- a/pkg/analysis_server/test/src/watch_manager_test.dart ++++ /dev/null +@@ -1,350 +0,0 @@ +-// Copyright (c) 2015, 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 'package:analysis_server/src/watch_manager.dart'; +-import 'package:analyzer/file_system/file_system.dart'; +-import 'package:analyzer/file_system/memory_file_system.dart'; +-import 'package:test/test.dart'; +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +-import 'package:watcher/watcher.dart'; +- +-import '../mocks.dart'; +- +-main() { +- defineReflectiveSuite(() { +- defineReflectiveTests(WatchManagerTest); +- defineReflectiveTests(WatchNodeTest); +- }); +-} +- +-/** +- * Tokens that can be used for testing purposes. +- */ +-class Token { +- /** +- * A name used for debugging. +- */ +- final String name; +- +- /** +- * Initialize a newly created token to have the given name. +- */ +- Token(this.name); +- +- @override +- String toString() => name; +-} +- +-/** +- * A listener that captures the state of watch events so that they can be +- * tested. +- */ +-class WatchListener { +- /** +- * The event that was passed to the listener method. +- */ +- WatchEvent event; +- +- /** +- * The tokens that were passed to the listener method. +- */ +- List tokens; +- +- /** +- * Clear the state so that we can distinguish between not receiving an event +- * and receiving the wrong event. +- */ +- void clear() { +- this.event = null; +- this.tokens = null; +- } +- +- /** +- * The listener method. +- */ +- void handleWatchEvent(WatchEvent event, List tokens) { +- this.event = event; +- this.tokens = tokens; +- } +-} +- +-@reflectiveTest +-class WatchManagerTest { +- MemoryResourceProvider provider; +- WatchListener listener; +- WatchManager manager; +- +- void setUp() { +- provider = new MemoryResourceProvider(); +- listener = new WatchListener(); +- manager = new WatchManager(provider, listener.handleWatchEvent); +- } +- +- Future test_addFolder_folderAndSubfolder() async { +- Folder topFolder = provider.getFolder('/a/b'); +- Folder childFolder = provider.getFolder('/a/b/c/d'); +- Token topToken = new Token('topToken'); +- Token childToken = new Token('childToken'); +- manager.addFolder(topFolder, topToken); +- manager.addFolder(childFolder, childToken); +- +- File newFile1 = provider.newFile('/a/b/c/lib.dart', ''); +- await _expectEvent(ChangeType.ADD, newFile1.path, [topToken]); +- +- File newFile2 = provider.newFile('/a/b/c/d/lib.dart', ''); +- return _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]); +- } +- +- Future test_addFolder_singleFolder_multipleTokens() { +- Folder folder = provider.getFolder('/a/b'); +- Token token1 = new Token('token1'); +- Token token2 = new Token('token2'); +- manager.addFolder(folder, token1); +- manager.addFolder(folder, token2); +- +- File newFile = provider.newFile('/a/b/lib.dart', ''); +- return _expectEvent(ChangeType.ADD, newFile.path, [token1, token2]); +- } +- +- Future test_addFolder_singleFolder_singleToken() async { +- Folder folder = provider.getFolder('/a/b'); +- Token token = new Token('token'); +- manager.addFolder(folder, token); +- +- Folder newFolder = provider.newFolder('/a/b/c'); +- await _expectEvent(ChangeType.ADD, newFolder.path, [token]); +- +- File newFile = provider.newFile('/a/b/c/lib.dart', ''); +- return _expectEvent(ChangeType.ADD, newFile.path, [token]); +- } +- +- Future test_addFolder_unrelatedFolders() async { +- Folder folder1 = provider.getFolder('/a/b'); +- Folder folder2 = provider.getFolder('/c/d'); +- Token token1 = new Token('token1'); +- Token token2 = new Token('token2'); +- manager.addFolder(folder1, token1); +- manager.addFolder(folder2, token2); +- +- File newFile1 = provider.newFile('/a/b/lib.dart', ''); +- await _expectEvent(ChangeType.ADD, newFile1.path, [token1]); +- +- File newFile2 = provider.newFile('/c/d/lib.dart', ''); +- return _expectEvent(ChangeType.ADD, newFile2.path, [token2]); +- } +- +- void test_creation() { +- expect(manager, isNotNull); +- } +- +- Future test_removeFolder_multipleTokens() { +- Folder folder = provider.getFolder('/a/b'); +- Token token1 = new Token('token1'); +- Token token2 = new Token('token2'); +- manager.addFolder(folder, token1); +- manager.addFolder(folder, token2); +- manager.removeFolder(folder, token2); +- +- File newFile = provider.newFile('/a/b/lib.dart', ''); +- return _expectEvent(ChangeType.ADD, newFile.path, [token1]); +- } +- +- Future test_removeFolder_withChildren() async { +- Folder topFolder = provider.getFolder('/a/b'); +- Folder childFolder = provider.getFolder('/a/b/c/d'); +- Token topToken = new Token('topToken'); +- Token childToken = new Token('childToken'); +- manager.addFolder(topFolder, topToken); +- manager.addFolder(childFolder, childToken); +- manager.removeFolder(topFolder, topToken); +- +- File newFile = provider.newFile('/a/b/c/d/lib.dart', ''); +- await _expectEvent(ChangeType.ADD, newFile.path, [childToken]); +- +- provider.newFile('/a/b/lib.dart', ''); +- return _expectNoEvent(); +- } +- +- Future test_removeFolder_withNoChildren() { +- Folder folder = provider.getFolder('/a/b'); +- Token token = new Token('token'); +- manager.addFolder(folder, token); +- manager.removeFolder(folder, token); +- +- provider.newFile('/a/b/lib.dart', ''); +- return _expectNoEvent(); +- } +- +- Future _expectEvent(ChangeType expectedType, String expectedPath, +- List expectedTokens) async { +- await pumpEventQueue(); +- WatchEvent event = listener.event; +- expect(event, isNotNull); +- expect(event.type, expectedType); +- expect(event.path, expectedPath); +- expect(listener.tokens, unorderedEquals(expectedTokens)); +- listener.clear(); +- } +- +- Future _expectNoEvent() async { +- await pumpEventQueue(); +- expect(listener.event, isNull); +- expect(listener.tokens, isNull); +- } +-} +- +-@reflectiveTest +-class WatchNodeTest { +- MemoryResourceProvider provider = new MemoryResourceProvider(); +- +- void test_creation_folder() { +- Folder folder = provider.getFolder('/a/b'); +- WatchNode node = new WatchNode(folder); +- expect(node, isNotNull); +- expect(node.children, isEmpty); +- expect(node.folder, folder); +- expect(node.parent, isNull); +- expect(node.subscription, isNull); +- expect(node.tokens, isEmpty); +- } +- +- void test_creation_noFolder() { +- WatchNode node = new WatchNode(null); +- expect(node, isNotNull); +- expect(node.children, isEmpty); +- expect(node.folder, isNull); +- expect(node.parent, isNull); +- expect(node.subscription, isNull); +- expect(node.tokens, isEmpty); +- } +- +- void test_delete_nested_child() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- WatchNode grandchildNode = new WatchNode(provider.getFolder('/a/b/c/d/e')); +- rootNode.insert(topNode); +- rootNode.insert(childNode); +- rootNode.insert(grandchildNode); +- +- childNode.delete(); +- expect(rootNode.children, equals([topNode])); +- expect(topNode.children, equals([grandchildNode])); +- expect(topNode.parent, rootNode); +- expect(grandchildNode.parent, topNode); +- } +- +- void test_delete_nested_noChild() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- rootNode.insert(topNode); +- rootNode.insert(childNode); +- +- childNode.delete(); +- expect(rootNode.children, equals([topNode])); +- expect(topNode.children, isEmpty); +- expect(topNode.parent, rootNode); +- } +- +- void test_delete_top_child() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- rootNode.insert(topNode); +- rootNode.insert(childNode); +- +- topNode.delete(); +- expect(rootNode.children, equals([childNode])); +- expect(childNode.parent, rootNode); +- } +- +- void test_delete_top_noChild() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- rootNode.insert(topNode); +- +- topNode.delete(); +- expect(rootNode.children, isEmpty); +- } +- +- void test_findParent_childOfLeaf() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- rootNode.insert(topNode); +- +- expect(rootNode.findParent('/a/b/c'), topNode); +- } +- +- void test_findParent_childOfNonLeaf() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- rootNode.insert(topNode); +- rootNode.insert(childNode); +- +- expect(rootNode.findParent('/a/b/c'), topNode); +- } +- +- void test_findParent_noMatch() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- rootNode.insert(topNode); +- +- expect(rootNode.findParent('/c/d'), rootNode); +- } +- +- void test_insert_intermediate_afterParentAndChild() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- WatchNode intermediateNode = new WatchNode(provider.getFolder('/a/b/c')); +- +- rootNode.insert(topNode); +- rootNode.insert(childNode); +- rootNode.insert(intermediateNode); +- expect(topNode.parent, rootNode); +- expect(topNode.children, equals([intermediateNode])); +- expect(intermediateNode.parent, topNode); +- expect(intermediateNode.children, equals([childNode])); +- expect(childNode.parent, intermediateNode); +- expect(childNode.children, isEmpty); +- } +- +- void test_insert_nested_afterParent() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- +- rootNode.insert(topNode); +- rootNode.insert(childNode); +- expect(childNode.parent, topNode); +- expect(childNode.children, isEmpty); +- expect(topNode.children, equals([childNode])); +- } +- +- void test_insert_nested_beforeParent() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); +- +- rootNode.insert(childNode); +- rootNode.insert(topNode); +- expect(childNode.parent, topNode); +- expect(childNode.children, isEmpty); +- expect(topNode.children, equals([childNode])); +- } +- +- void test_insert_top() { +- WatchNode rootNode = new WatchNode(null); +- WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); +- +- rootNode.insert(topNode); +- expect(rootNode.children, equals([topNode])); +- expect(topNode.parent, rootNode); +- expect(topNode.children, isEmpty); +- } +-} +diff --git a/pkg/analysis_server/test/stress/replay/operation.dart b/pkg/analysis_server/test/stress/replay/operation.dart +deleted file mode 100644 +index dbacce9f95a..00000000000 +--- a/pkg/analysis_server/test/stress/replay/operation.dart ++++ /dev/null +@@ -1,80 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-/** +- * Operations to be performed during the simulation. +- */ +-import '../utilities/server.dart'; +- +-/** +- * An operation that will send an 'analysis.updateContent' request. +- */ +-class Analysis_UpdateContent extends ServerOperation { +- /** +- * The path of the file whose content is being updated. +- */ +- final String filePath; +- +- /** +- * The overlay used to update the content. +- */ +- final dynamic overlay; +- +- /** +- * Initialize an operation to send an 'analysis.updateContent' request with +- * the given [filePath] and [overlay] as parameters. +- */ +- Analysis_UpdateContent(this.filePath, this.overlay); +- +- @override +- void perform(Server server) { +- server.sendAnalysisUpdateContent({filePath: overlay}); +-// if (overlay is ChangeContentOverlay) { +-// List edits = (overlay as ChangeContentOverlay).edits; +-// if (edits.length == 1) { +-// SourceEdit edit = edits[0]; +-// if (edit.replacement.endsWith('.')) { +-// int offset = edit.offset + edit.replacement.length - 1; +-// server.sendCompletionGetSuggestions(filePath, offset); +-// } +-// } +-// } +- } +-} +- +-/** +- * An operation that will send a 'completion.getSuggestions' request. +- */ +-class Completion_GetSuggestions extends ServerOperation { +- /** +- * The path of the file in which completions are being requested. +- */ +- final String filePath; +- +- /** +- * The offset at which completions are being requested. +- */ +- final int offset; +- +- /** +- * Initialize an operation to send a 'completion.getSuggestions' request with +- * the given [filePath] and [offset] as parameters. +- */ +- Completion_GetSuggestions(this.filePath, this.offset); +- +- @override +- void perform(Server server) { +- server.sendCompletionGetSuggestions(filePath, offset); +- } +-} +- +-/** +- * An operation to be performed during the simulation. +- */ +-abstract class ServerOperation { +- /** +- * Perform this operation by communicating with the given [server]. +- */ +- void perform(Server server); +-} +diff --git a/pkg/analysis_server/test/stress/replay/replay.dart b/pkg/analysis_server/test/stress/replay/replay.dart +deleted file mode 100644 +index 36ef8fddc90..00000000000 +--- a/pkg/analysis_server/test/stress/replay/replay.dart ++++ /dev/null +@@ -1,707 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-/** +- * A stress test for the analysis server. +- */ +-import 'dart:async'; +-import 'dart:io'; +-import 'dart:math' as math; +- +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer/dart/ast/token.dart'; +-import 'package:analyzer/error/listener.dart' as error; +-import 'package:analyzer/src/dart/scanner/reader.dart'; +-import 'package:analyzer/src/dart/scanner/scanner.dart'; +-import 'package:analyzer/src/generated/java_engine.dart'; +-import 'package:analyzer/src/generated/source.dart'; +-import 'package:analyzer/src/util/glob.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:args/args.dart'; +-import 'package:path/path.dart' as path; +- +-import '../utilities/git.dart'; +-import '../utilities/logger.dart'; +-import '../utilities/server.dart'; +-import 'operation.dart'; +- +-/** +- * Run the simulation based on the given command-line [arguments]. +- */ +-Future main(List arguments) async { +- Driver driver = new Driver(); +- await driver.run(arguments); +-} +- +-/** +- * The driver class that runs the simulation. +- */ +-class Driver { +- /** +- * The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications +- * to a file should be represented by an add overlay, followed by zero or more +- * change overlays, followed by a remove overlay. +- */ +- static String CHANGE_OVERLAY_STYLE = 'change'; +- +- /** +- * The name of the command-line flag that will print help text. +- */ +- static String HELP_FLAG_NAME = 'help'; +- +- /** +- * The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications +- * to a file should be represented by an add overlay, followed by zero or more +- * additional add overlays, followed by a remove overlay. +- */ +- static String MULTIPLE_ADD_OVERLAY_STYLE = 'multipleAdd'; +- +- /** +- * The name of the command-line option used to specify the style of +- * interaction to use when making `analysis.updateContent` requests. +- */ +- static String OVERLAY_STYLE_OPTION_NAME = 'overlay-style'; +- +- /** +- * The name of the pubspec file. +- */ +- static const String PUBSPEC_FILE_NAME = 'pubspec.yaml'; +- +- /** +- * The name of the branch used to clean-up after making temporary changes. +- */ +- static const String TEMP_BRANCH_NAME = 'temp'; +- +- /** +- * The name of the command-line flag that will cause verbose output to be +- * produced. +- */ +- static String VERBOSE_FLAG_NAME = 'verbose'; +- +- /** +- * The style of interaction to use for analysis.updateContent requests. +- */ +- OverlayStyle overlayStyle; +- +- /** +- * The absolute path of the repository. +- */ +- String repositoryPath; +- +- /** +- * The absolute paths to the analysis roots. +- */ +- List analysisRoots; +- +- /** +- * The git repository. +- */ +- GitRepository repository; +- +- /** +- * The connection to the analysis server. +- */ +- Server server; +- +- /** +- * A list of the glob patterns used to identify the files being analyzed by +- * the server. +- */ +- List fileGlobs; +- +- /** +- * An object gathering statistics about the simulation. +- */ +- Statistics statistics; +- +- /** +- * A flag indicating whether verbose output should be provided. +- */ +- bool verbose = false; +- +- /** +- * The logger to which verbose logging data will be written. +- */ +- Logger logger; +- +- /** +- * Initialize a newly created driver. +- */ +- Driver() { +- statistics = new Statistics(this); +- } +- +- /** +- * Allow the output from the server to be read and processed. +- */ +- Future readServerOutput() async { +- await new Future.delayed(new Duration(milliseconds: 2)); +- } +- +- /** +- * Run the simulation based on the given command-line arguments ([args]). +- */ +- Future run(List args) async { +- // +- // Process the command-line arguments. +- // +- if (!_processCommandLine(args)) { +- return null; +- } +- if (verbose) { +- stdout.writeln(); +- stdout.writeln('-' * 80); +- stdout.writeln(); +- } +- // +- // Simulate interactions with the server. +- // +- await _runSimulation(); +- // +- // Print out statistics gathered while performing the simulation. +- // +- if (verbose) { +- stdout.writeln(); +- stdout.writeln('-' * 80); +- } +- stdout.writeln(); +- statistics.print(); +- if (verbose) { +- stdout.writeln(); +- server.printStatistics(); +- } +- exit(0); +- return null; +- } +- +- /** +- * Create and return a parser that can be used to parse the command-line +- * arguments. +- */ +- ArgParser _createArgParser() { +- ArgParser parser = new ArgParser(); +- parser.addFlag(HELP_FLAG_NAME, +- abbr: 'h', +- help: 'Print usage information', +- defaultsTo: false, +- negatable: false); +- parser.addOption(OVERLAY_STYLE_OPTION_NAME, +- help: +- 'The style of interaction to use for analysis.updateContent requests', +- allowed: [CHANGE_OVERLAY_STYLE, MULTIPLE_ADD_OVERLAY_STYLE], +- allowedHelp: { +- CHANGE_OVERLAY_STYLE: ' * ', +- MULTIPLE_ADD_OVERLAY_STYLE: '+ ' +- }, +- defaultsTo: 'change'); +- parser.addFlag(VERBOSE_FLAG_NAME, +- abbr: 'v', +- help: 'Produce verbose output for debugging', +- defaultsTo: false, +- negatable: false); +- return parser; +- } +- +- /** +- * Add source edits to the given [fileEdit] based on the given [blobDiff]. +- */ +- void _createSourceEdits(FileEdit fileEdit, BlobDiff blobDiff) { +- LineInfo info = fileEdit.lineInfo; +- for (DiffHunk hunk in blobDiff.hunks) { +- int srcStart = info.getOffsetOfLine(hunk.srcLine); +- int srcEnd = info.getOffsetOfLine( +- math.min(hunk.srcLine + hunk.removeLines.length, info.lineCount - 1)); +- String addedText = _join(hunk.addLines); +- // +- // Create the source edits. +- // +- List breakOffsets = _getBreakOffsets(addedText); +- int breakCount = breakOffsets.length; +- List sourceEdits = []; +- if (breakCount == 0) { +- sourceEdits +- .add(new SourceEdit(srcStart, srcEnd - srcStart + 1, addedText)); +- } else { +- int previousOffset = breakOffsets[0]; +- String string = addedText.substring(0, previousOffset); +- sourceEdits +- .add(new SourceEdit(srcStart, srcEnd - srcStart + 1, string)); +- String reconstruction = string; +- for (int i = 1; i < breakCount; i++) { +- int offset = breakOffsets[i]; +- string = addedText.substring(previousOffset, offset); +- reconstruction += string; +- sourceEdits.add(new SourceEdit(srcStart + previousOffset, 0, string)); +- previousOffset = offset; +- } +- string = addedText.substring(previousOffset); +- reconstruction += string; +- sourceEdits.add(new SourceEdit(srcStart + previousOffset, 0, string)); +- if (reconstruction != addedText) { +- throw new AssertionError(); +- } +- } +- fileEdit.addSourceEdits(sourceEdits); +- } +- } +- +- /** +- * Return the absolute paths of all of the pubspec files in all of the +- * analysis roots. +- */ +- Iterable _findPubspecsInAnalysisRoots() { +- List pubspecFiles = []; +- for (String directoryPath in analysisRoots) { +- Directory directory = new Directory(directoryPath); +- List children = +- directory.listSync(recursive: true, followLinks: false); +- for (FileSystemEntity child in children) { +- String filePath = child.path; +- if (path.basename(filePath) == PUBSPEC_FILE_NAME) { +- pubspecFiles.add(filePath); +- } +- } +- } +- return pubspecFiles; +- } +- +- /** +- * Return a list of offsets into the given [text] that represent good places +- * to break the text when building edits. +- */ +- List _getBreakOffsets(String text) { +- List breakOffsets = []; +- Scanner scanner = new Scanner(null, new CharSequenceReader(text), +- error.AnalysisErrorListener.NULL_LISTENER); +- Token token = scanner.tokenize(); +- // TODO(brianwilkerson) Randomize. Sometimes add zero (0) as a break point. +- while (token.type != TokenType.EOF) { +- // TODO(brianwilkerson) Break inside comments? +-// Token comment = token.precedingComments; +- int offset = token.offset; +- int length = token.length; +- breakOffsets.add(offset); +- if (token.type == TokenType.IDENTIFIER && length > 3) { +- breakOffsets.add(offset + (length ~/ 2)); +- } +- token = token.next; +- } +- return breakOffsets; +- } +- +- /** +- * Join the given [lines] into a single string. +- */ +- String _join(List lines) { +- StringBuffer buffer = new StringBuffer(); +- for (int i = 0; i < lines.length; i++) { +- buffer.writeln(lines[i]); +- } +- return buffer.toString(); +- } +- +- /** +- * Process the command-line [arguments]. Return `true` if the simulation +- * should be run. +- */ +- bool _processCommandLine(List args) { +- ArgParser parser = _createArgParser(); +- ArgResults results; +- try { +- results = parser.parse(args); +- } catch (exception) { +- _showUsage(parser); +- return false; +- } +- +- if (results[HELP_FLAG_NAME]) { +- _showUsage(parser); +- return false; +- } +- +- String overlayStyleValue = results[OVERLAY_STYLE_OPTION_NAME]; +- if (overlayStyleValue == CHANGE_OVERLAY_STYLE) { +- overlayStyle = OverlayStyle.change; +- } else if (overlayStyleValue == MULTIPLE_ADD_OVERLAY_STYLE) { +- overlayStyle = OverlayStyle.multipleAdd; +- } +- +- if (results[VERBOSE_FLAG_NAME]) { +- verbose = true; +- logger = new Logger(stdout); +- } +- +- List arguments = results.rest; +- if (arguments.length < 2) { +- _showUsage(parser); +- return false; +- } +- repositoryPath = path.normalize(arguments[0]); +- repository = new GitRepository(repositoryPath, logger: logger); +- +- analysisRoots = arguments +- .sublist(1) +- .map((String analysisRoot) => path.normalize(analysisRoot)) +- .toList(); +- for (String analysisRoot in analysisRoots) { +- if (repositoryPath != analysisRoot && +- !path.isWithin(repositoryPath, analysisRoot)) { +- _showUsage(parser, +- 'Analysis roots must be contained within the repository: $analysisRoot'); +- return false; +- } +- } +- return true; +- } +- +- /** +- * Replay the changes in each commit. +- */ +- Future _replayChanges() async { +- // +- // Get the revision history of the repo. +- // +- LinearCommitHistory history = repository.getCommitHistory(); +- statistics.commitCount = history.commitIds.length; +- LinearCommitHistoryIterator iterator = history.iterator(); +- try { +- // +- // Iterate over the history, applying changes. +- // +- bool firstCheckout = true; +- ErrorMap expectedErrors = null; +- Iterable changedPubspecs; +- while (iterator.moveNext()) { +- // +- // Checkout the commit on which the changes are based. +- // +- String commit = iterator.srcCommit; +- repository.checkout(commit); +- if (expectedErrors != null) { +-// ErrorMap actualErrors = +- await server.computeErrorMap(server.analyzedDartFiles); +-// String difference = expectedErrors.expectErrorMap(actualErrors); +-// if (difference != null) { +-// stdout.write('Mismatched errors after commit '); +-// stdout.writeln(commit); +-// stdout.writeln(); +-// stdout.writeln(difference); +-// return; +-// } +- } +- if (firstCheckout) { +- changedPubspecs = _findPubspecsInAnalysisRoots(); +- server.sendAnalysisSetAnalysisRoots(analysisRoots, []); +- firstCheckout = false; +- } else { +- server.removeAllOverlays(); +- } +- await readServerOutput(); +- expectedErrors = await server.computeErrorMap(server.analyzedDartFiles); +- for (String filePath in changedPubspecs) { +- _runPub(filePath); +- } +- // +- // Apply the changes. +- // +- CommitDelta commitDelta = iterator.next(); +- commitDelta.filterDiffs(analysisRoots, fileGlobs); +- if (commitDelta.hasDiffs) { +- statistics.commitsWithChangeInRootCount++; +- await _replayDiff(commitDelta); +- } +- changedPubspecs = commitDelta.filesMatching(PUBSPEC_FILE_NAME); +- } +- } finally { +- // Ensure that the repository is left at the most recent commit. +- if (history.commitIds.length > 0) { +- repository.checkout(history.commitIds[0]); +- } +- } +- server.removeAllOverlays(); +- await readServerOutput(); +- stdout.writeln(); +- } +- +- /** +- * Replay the changes between two commits, as represented by the given +- * [commitDelta]. +- */ +- Future _replayDiff(CommitDelta commitDelta) async { +- List editList = []; +- for (DiffRecord record in commitDelta.diffRecords) { +- FileEdit edit = new FileEdit(overlayStyle, record); +- _createSourceEdits(edit, record.getBlobDiff()); +- editList.add(edit); +- } +- // +- // TODO(brianwilkerson) Randomize. +- // Randomly select operations from different files to simulate a user +- // editing multiple files simultaneously. +- // +- for (FileEdit edit in editList) { +- List currentFile = [edit.filePath]; +- server.sendAnalysisSetPriorityFiles(currentFile); +- server.sendAnalysisSetSubscriptions({ +- AnalysisService.FOLDING: currentFile, +- AnalysisService.HIGHLIGHTS: currentFile, +- AnalysisService.IMPLEMENTED: currentFile, +- AnalysisService.NAVIGATION: currentFile, +- AnalysisService.OCCURRENCES: currentFile, +- AnalysisService.OUTLINE: currentFile, +- AnalysisService.OVERRIDES: currentFile +- }); +- for (ServerOperation operation in edit.getOperations()) { +- statistics.editCount++; +- operation.perform(server); +- await readServerOutput(); +- } +- } +- } +- +- /** +- * Run `pub` on the pubspec with the given [filePath]. +- */ +- void _runPub(String filePath) { +- String directoryPath = path.dirname(filePath); +- if (new Directory(directoryPath).existsSync()) { +- Process.runSync( +- '/Users/brianwilkerson/Dev/dart/dart-sdk/bin/pub', ['get'], +- workingDirectory: directoryPath); +- } +- } +- +- /** +- * Run the simulation by starting up a server and sending it requests. +- */ +- Future _runSimulation() async { +- server = new Server(logger: logger); +- Stopwatch stopwatch = new Stopwatch(); +- statistics.stopwatch = stopwatch; +- stopwatch.start(); +- await server.start(); +- server.sendServerSetSubscriptions([ServerService.STATUS]); +- server.sendAnalysisSetGeneralSubscriptions( +- [GeneralAnalysisService.ANALYZED_FILES]); +- // TODO(brianwilkerson) Get the list of glob patterns from the server after +- // an API for getting them has been implemented. +- fileGlobs = [ +- new Glob(path.context.separator, '**.dart'), +- new Glob(path.context.separator, '**.html'), +- new Glob(path.context.separator, '**.htm'), +- new Glob(path.context.separator, '**/.analysisOptions') +- ]; +- try { +- await _replayChanges(); +- } finally { +- // TODO(brianwilkerson) This needs to be moved into a Zone in order to +- // ensure that it is always run. +- server.sendServerShutdown(); +- repository.checkout('master'); +- } +- stopwatch.stop(); +- } +- +- /** +- * Display usage information, preceded by the [errorMessage] if one is given. +- */ +- void _showUsage(ArgParser parser, [String errorMessage = null]) { +- if (errorMessage != null) { +- stderr.writeln(errorMessage); +- stderr.writeln(); +- } +- stderr.writeln(''' +-Usage: replay [options...] repositoryPath analysisRoot... +- +-Uses the commit history of the git repository at the given repository path to +-simulate the development of a code base while using the analysis server to +-analyze the code base. +- +-The repository path must be the absolute path of a directory containing a git +-repository. +- +-There must be at least one analysis root, and all of the analysis roots must be +-the absolute path of a directory contained within the repository directory. The +-analysis roots represent the portions of the repository that will be analyzed by +-the analysis server. +- +-OPTIONS:'''); +- stderr.writeln(parser.usage); +- } +-} +- +-/** +- * A representation of the edits to be applied to a single file. +- */ +-class FileEdit { +- /** +- * The style of interaction to use for analysis.updateContent requests. +- */ +- OverlayStyle overlayStyle; +- +- /** +- * The absolute path of the file to be edited. +- */ +- String filePath; +- +- /** +- * The content of the file before any edits have been applied. +- */ +- String content; +- +- /** +- * The line info for the file before any edits have been applied. +- */ +- LineInfo lineInfo; +- +- /** +- * The lists of source edits, one list for each hunk being edited. +- */ +- List> editLists = >[]; +- +- /** +- * The current content of the file. This field is only used if the overlay +- * style is [OverlayStyle.multipleAdd]. +- */ +- String currentContent; +- +- /** +- * Initialize a collection of edits to be associated with the file at the +- * given [filePath]. +- */ +- FileEdit(this.overlayStyle, DiffRecord record) { +- filePath = record.srcPath; +- if (record.isAddition) { +- content = ''; +- lineInfo = new LineInfo([0]); +- } else if (record.isCopy || record.isRename || record.isTypeChange) { +- throw new ArgumentError('Unhandled change of type ${record.status}'); +- } else { +- content = new File(filePath).readAsStringSync(); +- lineInfo = new LineInfo(StringUtilities.computeLineStarts(content)); +- } +- currentContent = content; +- } +- +- /** +- * Add a list of source edits that, taken together, transform a single hunk in +- * the file. +- */ +- void addSourceEdits(List sourceEdits) { +- editLists.add(sourceEdits); +- } +- +- /** +- * Return a list of operations to be sent to the server. +- */ +- List getOperations() { +- List operations = []; +- void addUpdateContent(var overlay) { +- operations.add(new Analysis_UpdateContent(filePath, overlay)); +- } +- +- // TODO(brianwilkerson) Randomize. +- // Make the order of edits random. Doing so will require updating the +- // offsets of edits after the selected edit point. +- addUpdateContent(new AddContentOverlay(content)); +- for (List editList in editLists.reversed) { +- for (SourceEdit edit in editList.reversed) { +- var overlay = null; +- if (overlayStyle == OverlayStyle.change) { +- overlay = new ChangeContentOverlay([edit]); +- } else if (overlayStyle == OverlayStyle.multipleAdd) { +- currentContent = edit.apply(currentContent); +- overlay = new AddContentOverlay(currentContent); +- } else { +- throw new StateError( +- 'Failed to handle overlay style = $overlayStyle'); +- } +- if (overlay != null) { +- addUpdateContent(overlay); +- } +- } +- } +- addUpdateContent(new RemoveContentOverlay()); +- return operations; +- } +-} +- +-/** +- * The possible styles of interaction to use for analysis.updateContent requests. +- */ +-enum OverlayStyle { change, multipleAdd } +- +-/** +- * A set of statistics related to the execution of the simulation. +- */ +-class Statistics { +- /** +- * The driver driving the simulation. +- */ +- final Driver driver; +- +- /** +- * The stopwatch being used to time the simulation. +- */ +- Stopwatch stopwatch; +- +- /** +- * The total number of commits in the repository. +- */ +- int commitCount; +- +- /** +- * The number of commits in the repository that touched one of the files in +- * one of the analysis roots. +- */ +- int commitsWithChangeInRootCount = 0; +- +- /** +- * The total number of edits that were applied. +- */ +- int editCount = 0; +- +- /** +- * Initialize a newly created set of statistics. +- */ +- Statistics(this.driver); +- +- /** +- * Print the statistics to [stdout]. +- */ +- void print() { +- stdout.write('Replay commits in '); +- stdout.writeln(driver.repositoryPath); +- stdout.write(' replay took '); +- stdout.writeln(_printTime(stopwatch.elapsedMilliseconds)); +- stdout.write(' analysis roots = '); +- stdout.writeln(driver.analysisRoots); +- stdout.write(' number of commits = '); +- stdout.writeln(commitCount); +- stdout.write(' number of commits with a change in an analysis root = '); +- stdout.writeln(commitsWithChangeInRootCount); +- stdout.write(' number of edits = '); +- stdout.writeln(editCount); +- } +- +- /** +- * Return a textual representation of the given duration, represented in +- * [milliseconds]. +- */ +- String _printTime(int milliseconds) { +- int seconds = milliseconds ~/ 1000; +- milliseconds -= seconds * 1000; +- int minutes = seconds ~/ 60; +- seconds -= minutes * 60; +- int hours = minutes ~/ 60; +- minutes -= hours * 60; +- +- if (hours > 0) { +- return '$hours:$minutes:$seconds.$milliseconds'; +- } else if (minutes > 0) { +- return '$minutes:$seconds.$milliseconds'; +- } +- return '$seconds.$milliseconds'; +- } +-} +diff --git a/pkg/analysis_server/test/stress/utilities/git.dart b/pkg/analysis_server/test/stress/utilities/git.dart +deleted file mode 100644 +index cfcef4fb7aa..00000000000 +--- a/pkg/analysis_server/test/stress/utilities/git.dart ++++ /dev/null +@@ -1,551 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-/** +- * Support for interacting with a git repository. +- */ +-import 'dart:convert'; +-import 'dart:io'; +- +-import 'package:analyzer/src/util/glob.dart'; +-import 'package:path/path.dart' as path; +- +-import 'logger.dart'; +- +-/** +- * A representation of the differences between two blobs. +- */ +-class BlobDiff { +- /** +- * The regular expression used to identify the beginning of a hunk. +- */ +- static final RegExp hunkHeaderRegExp = +- new RegExp(r'@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)(?:,[0-9]+)? @@'); +- +- /** +- * A list of the hunks in the diff. +- */ +- List hunks = []; +- +- /** +- * Initialize a newly created blob diff by parsing the result of the git diff +- * command (the [input]). +- * +- * This is only intended to be invoked from [GitRepository.getBlobDiff]. +- */ +- BlobDiff._(List input) { +- _parseInput(input); +- } +- +- /** +- * Parse the result of the git diff command (the [input]). +- */ +- void _parseInput(List input) { +- for (String line in input) { +- _parseLine(line); +- } +- } +- +- /** +- * Parse a single [line] from the result of the git diff command. +- */ +- void _parseLine(String line) { +- DiffHunk currentHunk = hunks.isEmpty ? null : hunks.last; +- if (line.startsWith('@@')) { +- Match match = hunkHeaderRegExp.matchAsPrefix(line); +- int srcLine = int.parse(match.group(1)); +- int dstLine = int.parse(match.group(2)); +- hunks.add(new DiffHunk(srcLine, dstLine)); +- } else if (currentHunk != null && line.startsWith('+')) { +- currentHunk.addLines.add(line.substring(1)); +- } else if (currentHunk != null && line.startsWith('-')) { +- currentHunk.removeLines.add(line.substring(1)); +- } +- } +-} +- +-/** +- * A representation of the differences between two commits. +- */ +-class CommitDelta { +- /** +- * The length (in characters) of a SHA. +- */ +- static final int SHA_LENGTH = 40; +- +- /** +- * The code-point for a colon (':'). +- */ +- static final int COLON = ':'.codeUnitAt(0); +- +- /** +- * The code-point for a nul character. +- */ +- static final int NUL = 0; +- +- /** +- * The code-point for a tab. +- */ +- static final int TAB = '\t'.codeUnitAt(0); +- +- /** +- * The repository from which the commits were taken. +- */ +- final GitRepository repository; +- +- /** +- * The records of the files that were changed. +- */ +- final List diffRecords = []; +- +- /** +- * Initialize a newly created representation of the differences between two +- * commits. The differences are computed by parsing the result of a git diff +- * command (the [diffResults]). +- * +- * This is only intended to be invoked from [GitRepository.getBlobDiff]. +- */ +- CommitDelta._(this.repository, String diffResults) { +- _parseInput(diffResults); +- } +- +- /** +- * Return `true` if there are differences. +- */ +- bool get hasDiffs => diffRecords.isNotEmpty; +- +- /** +- * Return the absolute paths of all of the files in this commit whose name +- * matches the given [fileName]. +- */ +- Iterable filesMatching(String fileName) { +- return diffRecords +- .where((DiffRecord record) => record.isFor(fileName)) +- .map((DiffRecord record) => record.srcPath); +- } +- +- /** +- * Remove any diffs for files that are either (a) outside the given +- * [inclusionPaths], or (b) are files that do not match one of the given +- * [globPatterns]. +- */ +- void filterDiffs(List inclusionPaths, List globPatterns) { +- diffRecords.retainWhere((DiffRecord record) { +- String filePath = record.srcPath ?? record.dstPath; +- for (String inclusionPath in inclusionPaths) { +- if (path.isWithin(inclusionPath, filePath)) { +- for (Glob glob in globPatterns) { +- if (glob.matches(filePath)) { +- return true; +- } +- } +- } +- } +- return false; +- }); +- } +- +- /** +- * Return the index of the first nul character in the given [string] that is +- * at or after the given [start] index. +- */ +- int _findEnd(String string, int start) { +- int length = string.length; +- int end = start; +- while (end < length && string.codeUnitAt(end) != NUL) { +- end++; +- } +- return end; +- } +- +- /** +- * Return the result of converting the given [relativePath] to an absolute +- * path. The path is assumed to be relative to the root of the repository. +- */ +- String _makeAbsolute(String relativePath) { +- return path.join(repository.path, relativePath); +- } +- +- /** +- * Parse all of the diff records in the given [input]. +- */ +- void _parseInput(String input) { +- int length = input.length; +- int start = 0; +- while (start < length) { +- start = _parseRecord(input, start); +- } +- } +- +- /** +- * Parse a single record from the given [input], assuming that the record +- * starts at the given [startIndex]. +- * +- * Each record is formatted as a sequence of fields. The fields are, from the +- * left to the right: +- * +- * 1. a colon. +- * 2. mode for "src"; 000000 if creation or unmerged. +- * 3. a space. +- * 4. mode for "dst"; 000000 if deletion or unmerged. +- * 5. a space. +- * 6. sha1 for "src"; 0{40} if creation or unmerged. +- * 7. a space. +- * 8. sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree". +- * 9. a space. +- * 10. status, followed by optional "score" number. +- * 11. a tab or a NUL when -z option is used. +- * 12. path for "src" +- * 13. a tab or a NUL when -z option is used; only exists for C or R. +- * 14. path for "dst"; only exists for C or R. +- * 15. an LF or a NUL when -z option is used, to terminate the record. +- */ +- int _parseRecord(String input, int startIndex) { +- // Skip the first five fields. +- startIndex += 15; +- // Parse field 6 +- String srcSha = input.substring(startIndex, startIndex + SHA_LENGTH); +- startIndex += SHA_LENGTH + 1; +- // Parse field 8 +- String dstSha = input.substring(startIndex, startIndex + SHA_LENGTH); +- startIndex += SHA_LENGTH + 1; +- // Parse field 10 +- int endIndex = _findEnd(input, startIndex); +- String status = input.substring(startIndex, endIndex); +- startIndex = endIndex + 1; +- // Parse field 12 +- endIndex = _findEnd(input, startIndex); +- String srcPath = _makeAbsolute(input.substring(startIndex, endIndex)); +- startIndex = endIndex + 1; +- // Parse field 14 +- String dstPath = null; +- if (status.startsWith('C') || status.startsWith('R')) { +- endIndex = _findEnd(input, startIndex); +- dstPath = _makeAbsolute(input.substring(startIndex, endIndex)); +- } +- // Create the record. +- diffRecords.add( +- new DiffRecord(repository, srcSha, dstSha, status, srcPath, dstPath)); +- return endIndex + 1; +- } +-} +- +-/** +- * Representation of a single diff hunk. +- */ +-class DiffHunk { +- /** +- * The index of the first line that was changed in the src as returned by the +- * diff command. The diff command numbers lines starting at 1, but it +- * subtracts 1 from the line number if there are no lines on the source side +- * of the hunk. +- */ +- int diffSrcLine; +- +- /** +- * The index of the first line that was changed in the dst as returned by the +- * diff command. The diff command numbers lines starting at 1, but it +- * subtracts 1 from the line number if there are no lines on the destination +- * side of the hunk. +- */ +- int diffDstLine; +- +- /** +- * A list of the individual lines that were removed from the src. +- */ +- List removeLines = []; +- +- /** +- * A list of the individual lines that were added to the dst. +- */ +- List addLines = []; +- +- /** +- * Initialize a newly created hunk. The lines will be added after the object +- * has been created. +- */ +- DiffHunk(this.diffSrcLine, this.diffDstLine); +- +- /** +- * Return the index of the first line that was changed in the dst. Unlike the +- * [diffDstLine] field, this getter adjusts the line number to be consistent +- * whether or not there were any changed lines. +- */ +- int get dstLine { +- return addLines.isEmpty ? diffDstLine : diffDstLine - 1; +- } +- +- /** +- * Return the index of the first line that was changed in the src. Unlike the +- * [diffDstLine] field, this getter adjusts the line number to be consistent +- * whether or not there were any changed lines. +- */ +- int get srcLine { +- return removeLines.isEmpty ? diffSrcLine : diffSrcLine - 1; +- } +-} +- +-/** +- * A representation of a single line (record) from a raw diff. +- */ +-class DiffRecord { +- /** +- * The repository containing the file(s) that were modified. +- */ +- final GitRepository repository; +- +- /** +- * The SHA1 of the blob in the src. +- */ +- final String srcBlob; +- +- /** +- * The SHA1 of the blob in the dst. +- */ +- final String dstBlob; +- +- /** +- * The status of the change. Valid values are: +- * * A: addition of a file +- * * C: copy of a file into a new one +- * * D: deletion of a file +- * * M: modification of the contents or mode of a file +- * * R: renaming of a file +- * * T: change in the type of the file +- * * U: file is unmerged (you must complete the merge before it can be committed) +- * * X: "unknown" change type (most probably a bug, please report it) +- * +- * Status letters C and R are always followed by a score (denoting the +- * percentage of similarity between the source and target of the move or +- * copy), and are the only ones to be so. +- */ +- final String status; +- +- /** +- * The path of the src. +- */ +- final String srcPath; +- +- /** +- * The path of the dst if this was either a copy or a rename operation. +- */ +- final String dstPath; +- +- /** +- * Initialize a newly created diff record. +- */ +- DiffRecord(this.repository, this.srcBlob, this.dstBlob, this.status, +- this.srcPath, this.dstPath); +- +- /** +- * Return `true` if this record represents a file that was added. +- */ +- bool get isAddition => status == 'A'; +- +- /** +- * Return `true` if this record represents a file that was copied. +- */ +- bool get isCopy => status.startsWith('C'); +- +- /** +- * Return `true` if this record represents a file that was deleted. +- */ +- bool get isDeletion => status == 'D'; +- +- /** +- * Return `true` if this record represents a file that was modified. +- */ +- bool get isModification => status == 'M'; +- +- /** +- * Return `true` if this record represents a file that was renamed. +- */ +- bool get isRename => status.startsWith('R'); +- +- /** +- * Return `true` if this record represents an entity whose type was changed +- * (for example, from a file to a directory). +- */ +- bool get isTypeChange => status == 'T'; +- +- /** +- * Return a representation of the individual blobs within this diff. +- */ +- BlobDiff getBlobDiff() => repository.getBlobDiff(srcBlob, dstBlob); +- +- /** +- * Return `true` if this diff applies to a file with the given name. +- */ +- bool isFor(String fileName) => +- (srcPath != null && fileName == path.basename(srcPath)) || +- (dstPath != null && fileName == path.basename(dstPath)); +- +- @override +- String toString() => srcPath ?? dstPath; +-} +- +-/** +- * A representation of a git repository. +- */ +-class GitRepository { +- /** +- * The absolute path of the directory containing the repository. +- */ +- final String path; +- +- /** +- * The logger to which git commands should be written, or `null` if the +- * commands should not be written. +- */ +- final Logger logger; +- +- /** +- * Initialize a newly created repository to represent the git repository at +- * the given [path]. +- * +- * If a [commandSink] is provided, any calls to git will be written to it. +- */ +- GitRepository(this.path, {this.logger = null}); +- +- /** +- * Checkout the given [commit] from the repository. This is done by running +- * the command `git checkout `. +- */ +- void checkout(String commit) { +- _run(['checkout', commit]); +- } +- +- /** +- * Return details about the differences between the two blobs identified by +- * the SHA1 of the [srcBlob] and the SHA1 of the [dstBlob]. This is done by +- * running the command `git diff `. +- */ +- BlobDiff getBlobDiff(String srcBlob, String dstBlob) { +- ProcessResult result = _run(['diff', '-U0', srcBlob, dstBlob]); +- List diffResults = LineSplitter.split(result.stdout).toList(); +- return new BlobDiff._(diffResults); +- } +- +- /** +- * Return details about the differences between the two commits identified by +- * the [srcCommit] and [dstCommit]. This is done by running the command +- * `git diff --raw --no-abbrev --no-renames -z `. +- */ +- CommitDelta getCommitDiff(String srcCommit, String dstCommit) { +- // Consider --find-renames instead of --no-renames if rename information is +- // desired. +- ProcessResult result = _run([ +- 'diff', +- '--raw', +- '--no-abbrev', +- '--no-renames', +- '-z', +- srcCommit, +- dstCommit +- ]); +- return new CommitDelta._(this, result.stdout); +- } +- +- /** +- * Return a representation of the history of this repository. This is done by +- * running the command `git rev-list --first-parent HEAD`. +- */ +- LinearCommitHistory getCommitHistory() { +- ProcessResult result = _run(['rev-list', '--first-parent', 'HEAD']); +- List commitIds = LineSplitter.split(result.stdout).toList(); +- return new LinearCommitHistory(this, commitIds); +- } +- +- /** +- * Synchronously run the given [executable] with the given [arguments]. Return +- * the result of running the process. +- */ +- ProcessResult _run(List arguments) { +- logger?.log('git', 'git', arguments: arguments); +- return Process.runSync('git', arguments, +- stderrEncoding: UTF8, stdoutEncoding: UTF8, workingDirectory: path); +- } +-} +- +-/** +- * A representation of the history of a Git repository. This only represents a +- * single linear path in the history graph. +- */ +-class LinearCommitHistory { +- /** +- * The repository whose history is being represented. +- */ +- final GitRepository repository; +- +- /** +- * The id's (SHA's) of the commits in the repository, with the most recent +- * commit being first and the oldest commit being last. +- */ +- final List commitIds; +- +- /** +- * Initialize a commit history for the given [repository] to have the given +- * [commitIds]. +- */ +- LinearCommitHistory(this.repository, this.commitIds); +- +- /** +- * Return an iterator that can be used to iterate over this commit history. +- */ +- LinearCommitHistoryIterator iterator() { +- return new LinearCommitHistoryIterator(this); +- } +-} +- +-/** +- * An iterator over the history of a Git repository. +- */ +-class LinearCommitHistoryIterator { +- /** +- * The commit history being iterated over. +- */ +- final LinearCommitHistory history; +- +- /** +- * The index of the current commit in the list of [commitIds]. +- */ +- int currentCommit; +- +- /** +- * Initialize a newly created iterator to iterate over the commits with the +- * given [commitIds]; +- */ +- LinearCommitHistoryIterator(this.history) { +- currentCommit = history.commitIds.length; +- } +- +- /** +- * Return the SHA1 of the commit after the current commit (the 'dst' of the +- * [next] diff). +- */ +- String get dstCommit => history.commitIds[currentCommit - 1]; +- +- /** +- * Return the SHA1 of the current commit (the 'src' of the [next] diff). +- */ +- String get srcCommit => history.commitIds[currentCommit]; +- +- /** +- * Advance to the next commit in the history. Return `true` if it is safe to +- * ask for the [next] diff. +- */ +- bool moveNext() { +- if (currentCommit <= 1) { +- return false; +- } +- currentCommit--; +- return true; +- } +- +- /** +- * Return the difference between the current commit and the commit that +- * followed it. +- */ +- CommitDelta next() => history.repository.getCommitDiff(srcCommit, dstCommit); +-} +diff --git a/pkg/analysis_server/test/stress/utilities/logger.dart b/pkg/analysis_server/test/stress/utilities/logger.dart +deleted file mode 100644 +index acf7a742bae..00000000000 +--- a/pkg/analysis_server/test/stress/utilities/logger.dart ++++ /dev/null +@@ -1,49 +0,0 @@ +-// 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. +- +-/** +- * A utility class used to write logging information during a test. +- */ +-class Logger { +- /** +- * The width of the field in which labels are printed. +- */ +- static const int _labelWidth = 8; +- +- /** +- * The separator used to separate the label from the content. +- */ +- static const String _separator = ' : '; +- +- /** +- * The sink to which the logged information should be written. +- */ +- final StringSink sink; +- +- /** +- * Initialize a newly created logger to write to the given [sink]. +- */ +- Logger(this.sink); +- +- /** +- * Log the given information. +- * +- * The [label] is used to indicate the kind of information being logged, while +- * the [content] contains the actual information. If a list of [arguments] is +- * provided, then they will be written after the content. +- */ +- void log(String label, String content, {List arguments = null}) { +- for (int i = _labelWidth - label.length; i > 0; i--) { +- sink.write(' '); +- } +- sink.write(label); +- sink.write(_separator); +- sink.write(content); +- arguments?.forEach((String argument) { +- sink.write(' '); +- sink.write(argument); +- }); +- sink.writeln(); +- } +-} +diff --git a/pkg/analysis_server/test/stress/utilities/server.dart b/pkg/analysis_server/test/stress/utilities/server.dart +deleted file mode 100644 +index 533281badba..00000000000 +--- a/pkg/analysis_server/test/stress/utilities/server.dart ++++ /dev/null +@@ -1,1081 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-/** +- * Support for interacting with an analysis server that is running in a separate +- * process. +- */ +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:convert' hide JsonDecoder; +-import 'dart:io'; +-import 'dart:math' as math; +- +-import 'package:analysis_server/protocol/protocol.dart'; +-import 'package:analysis_server/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:path/path.dart' as path; +- +-import 'logger.dart'; +- +-/** +- * Return the current time expressed as milliseconds since the epoch. +- */ +-int get currentTime => new DateTime.now().millisecondsSinceEpoch; +- +-/** +- * ??? +- */ +-class ErrorMap { +- /** +- * A table mapping file paths to the errors associated with that file. +- */ +- final Map> pathMap = +- new HashMap>(); +- +- /** +- * Initialize a newly created error map. +- */ +- ErrorMap(); +- +- /** +- * Initialize a newly created error map to contain the same mapping as the +- * given [errorMap]. +- */ +- ErrorMap.from(ErrorMap errorMap) { +- pathMap.addAll(errorMap.pathMap); +- } +- +- void operator []=(String filePath, List errors) { +- pathMap[filePath] = errors; +- } +- +- /** +- * Compare the this error map with the state captured in the given [errorMap]. +- * Throw an exception if the two maps do not agree. +- */ +- String expectErrorMap(ErrorMap errorMap) { +- StringBuffer buffer = new StringBuffer(); +- _ErrorComparator comparator = new _ErrorComparator(buffer); +- comparator.compare(pathMap, errorMap.pathMap); +- if (buffer.length > 0) { +- return buffer.toString(); +- } +- return null; +- } +-} +- +-/** +- * Data that has been collected about a request sent to the server. +- */ +-class RequestData { +- /** +- * The unique id of the request. +- */ +- final String id; +- +- /** +- * The method that was requested. +- */ +- final String method; +- +- /** +- * The request parameters. +- */ +- final Map params; +- +- /** +- * The time at which the request was sent. +- */ +- final int requestTime; +- +- /** +- * The time at which the response was received, or `null` if no response has +- * been received. +- */ +- int responseTime = null; +- +- /** +- * The response that was received. +- */ +- Response _response; +- +- /** +- * The completer that will be completed when a response is received. +- */ +- Completer _responseCompleter; +- +- /** +- * Initialize a newly created set of request data. +- */ +- RequestData(this.id, this.method, this.params, this.requestTime); +- +- /** +- * Return the number of milliseconds that elapsed between the request and the +- * response. This getter assumes that the response was received. +- */ +- int get elapsedTime => responseTime - requestTime; +- +- /** +- * Return a future that will complete when a response is received. +- */ +- Future get respondedTo { +- if (_response != null) { +- return new Future.value(_response); +- } +- if (_responseCompleter == null) { +- _responseCompleter = new Completer(); +- } +- return _responseCompleter.future; +- } +- +- /** +- * Record that the given [response] was received. +- */ +- void recordResponse(Response response) { +- if (_response != null) { +- stdout.writeln( +- 'Received a second response to a $method request (id = $id)'); +- return; +- } +- responseTime = currentTime; +- _response = response; +- if (_responseCompleter != null) { +- _responseCompleter.complete(response); +- _responseCompleter = null; +- } +- } +-} +- +-/** +- * A utility for starting and communicating with an analysis server that is +- * running in a separate process. +- */ +-class Server { +- /** +- * The label used for communications from the client. +- */ +- static const String fromClient = 'client'; +- +- /** +- * The label used for normal communications from the server. +- */ +- static const String fromServer = 'server'; +- +- /** +- * The label used for output written by the server on [fromStderr]. +- */ +- static const String fromStderr = 'stderr'; +- +- /** +- * The logger to which the communications log should be written, or `null` if +- * the log should not be written. +- */ +- final Logger logger; +- +- /** +- * The process in which the server is running, or `null` if the server hasn't +- * been started yet. +- */ +- Process _process = null; +- +- /** +- * Number that should be used to compute the 'id' to send in the next command +- * sent to the server. +- */ +- int _nextId = 0; +- +- /** +- * The analysis roots that are included. +- */ +- List _analysisRootIncludes = []; +- +- /** +- * A list containing the paths of files for which an overlay has been created. +- */ +- List filesWithOverlays = []; +- +- /** +- * The files that the server reported as being analyzed. +- */ +- List _analyzedFiles = []; +- +- /** +- * A mapping from the absolute paths of files to the most recent set of errors +- * received for that file. +- */ +- ErrorMap _errorMap = new ErrorMap(); +- +- /** +- * The completer that will be completed the next time a 'server.status' +- * notification is received from the server with 'analyzing' set to false. +- */ +- Completer _analysisFinishedCompleter; +- +- /** +- * The completer that will be completed the next time a 'server.connected' +- * notification is received from the server. +- */ +- Completer _serverConnectedCompleter; +- +- /** +- * A table mapping the ids of requests that have been sent to the server to +- * data about those requests. +- */ +- final Map _requestDataMap = {}; +- +- /** +- * A table mapping the number of times a request whose 'event' is equal to the +- * key was sent to the server. +- */ +- final Map _notificationCountMap = {}; +- +- /** +- * Initialize a new analysis server. The analysis server is not running and +- * must be started using [start]. +- * +- * If a [logger] is provided, the communications between the client (this +- * test) and the server will be written to it. +- */ +- Server({this.logger = null}); +- +- /** +- * Return a future that will complete when a 'server.status' notification is +- * received from the server with 'analyzing' set to false. +- * +- * The future will only be completed by 'server.status' notifications that are +- * received after this function call, so it is safe to use this getter +- * multiple times in one test; each time it is used it will wait afresh for +- * analysis to finish. +- */ +- Future get analysisFinished { +- if (_analysisFinishedCompleter == null) { +- _analysisFinishedCompleter = new Completer(); +- } +- return _analysisFinishedCompleter.future; +- } +- +- /** +- * Return a list of the paths of files that are currently being analyzed. +- */ +- List get analyzedDartFiles { +- bool isAnalyzed(String filePath) { +- // TODO(brianwilkerson) This should use the path package to determine +- // inclusion, and needs to take exclusions into account. +- for (String includedRoot in _analysisRootIncludes) { +- if (filePath.startsWith(includedRoot)) { +- return true; +- } +- } +- return false; +- } +- +- List analyzedFiles = []; +- for (String filePath in _analyzedFiles) { +- if (filePath.endsWith('.dart') && isAnalyzed(filePath)) { +- analyzedFiles.add(filePath); +- } +- } +- return analyzedFiles; +- } +- +- /** +- * Return a table mapping the absolute paths of files to the most recent set +- * of errors received for that file. The content of the map will not change +- * when new sets of errors are received. +- */ +- ErrorMap get errorMap => new ErrorMap.from(_errorMap); +- +- /** +- * Compute a mapping from each of the file paths in the given list of +- * [filePaths] to the list of errors in the file at that path. +- */ +- Future computeErrorMap(List filePaths) async { +- ErrorMap errorMap = new ErrorMap(); +- List futures = []; +- for (String filePath in filePaths) { +- RequestData requestData = sendAnalysisGetErrors(filePath); +- futures.add(requestData.respondedTo.then((Response response) { +- if (response.result != null) { +- AnalysisGetErrorsResult result = +- new AnalysisGetErrorsResult.fromResponse(response); +- errorMap[filePath] = result.errors; +- } +- })); +- } +- await Future.wait(futures); +- return errorMap; +- } +- +- /** +- * Print information about the communications with the server. +- */ +- void printStatistics() { +- void writeSpaces(int count) { +- for (int i = 0; i < count; i++) { +- stdout.write(' '); +- } +- } +- +- // +- // Print information about the requests that were sent. +- // +- stdout.writeln('Request Counts'); +- if (_requestDataMap.isEmpty) { +- stdout.writeln(' none'); +- } else { +- Map> requestsByMethod = +- >{}; +- _requestDataMap.values.forEach((RequestData requestData) { +- requestsByMethod +- .putIfAbsent(requestData.method, () => []) +- .add(requestData); +- }); +- List keys = requestsByMethod.keys.toList(); +- keys.sort(); +- int maxCount = requestsByMethod.values +- .fold(0, (int count, List list) => count + list.length); +- int countWidth = maxCount.toString().length; +- for (String key in keys) { +- List requests = requestsByMethod[key]; +- int noResponseCount = 0; +- int responseCount = 0; +- int minTime = -1; +- int maxTime = -1; +- int totalTime = 0; +- requests.forEach((RequestData data) { +- if (data.responseTime == null) { +- noResponseCount++; +- } else { +- responseCount++; +- int time = data.elapsedTime; +- minTime = minTime < 0 ? time : math.min(minTime, time); +- maxTime = math.max(maxTime, time); +- totalTime += time; +- } +- }); +- String count = requests.length.toString(); +- writeSpaces(countWidth - count.length); +- stdout.write(' '); +- stdout.write(count); +- stdout.write(' - '); +- stdout.write(key); +- if (noResponseCount > 0) { +- stdout.write(', '); +- stdout.write(noResponseCount); +- stdout.write(' with no response'); +- } +- if (maxTime >= 0) { +- stdout.write(' ('); +- stdout.write(minTime); +- stdout.write(', '); +- stdout.write(totalTime / responseCount); +- stdout.write(', '); +- stdout.write(maxTime); +- stdout.write(')'); +- } +- stdout.writeln(); +- } +- } +- // +- // Print information about the notifications that were received. +- // +- stdout.writeln(); +- stdout.writeln('Notification Counts'); +- if (_notificationCountMap.isEmpty) { +- stdout.writeln(' none'); +- } else { +- List keys = _notificationCountMap.keys.toList(); +- keys.sort(); +- int maxCount = _notificationCountMap.values.fold(0, math.max); +- int countWidth = maxCount.toString().length; +- for (String key in keys) { +- String count = _notificationCountMap[key].toString(); +- writeSpaces(countWidth - count.length); +- stdout.write(' '); +- stdout.write(count); +- stdout.write(' - '); +- stdout.writeln(key); +- } +- } +- } +- +- /** +- * Remove any existing overlays. +- */ +- void removeAllOverlays() { +- Map files = new HashMap(); +- for (String path in filesWithOverlays) { +- files[path] = new RemoveContentOverlay(); +- } +- sendAnalysisUpdateContent(files); +- } +- +- RequestData sendAnalysisGetErrors(String file) { +- var params = new AnalysisGetErrorsParams(file).toJson(); +- return _send("analysis.getErrors", params); +- } +- +- RequestData sendAnalysisGetHover(String file, int offset) { +- var params = new AnalysisGetHoverParams(file, offset).toJson(); +- return _send("analysis.getHover", params); +- } +- +- RequestData sendAnalysisGetLibraryDependencies() { +- return _send("analysis.getLibraryDependencies", null); +- } +- +- RequestData sendAnalysisGetNavigation(String file, int offset, int length) { +- var params = new AnalysisGetNavigationParams(file, offset, length).toJson(); +- return _send("analysis.getNavigation", params); +- } +- +- RequestData sendAnalysisGetReachableSources(String file) { +- var params = new AnalysisGetReachableSourcesParams(file).toJson(); +- return _send("analysis.getReachableSources", params); +- } +- +- void sendAnalysisReanalyze({List roots}) { +- var params = new AnalysisReanalyzeParams(roots: roots).toJson(); +- _send("analysis.reanalyze", params); +- } +- +- void sendAnalysisSetAnalysisRoots( +- List included, List excluded, +- {Map packageRoots}) { +- _analysisRootIncludes = included; +- var params = new AnalysisSetAnalysisRootsParams(included, excluded, +- packageRoots: packageRoots) +- .toJson(); +- _send("analysis.setAnalysisRoots", params); +- } +- +- void sendAnalysisSetGeneralSubscriptions( +- List subscriptions) { +- var params = +- new AnalysisSetGeneralSubscriptionsParams(subscriptions).toJson(); +- _send("analysis.setGeneralSubscriptions", params); +- } +- +- void sendAnalysisSetPriorityFiles(List files) { +- var params = new AnalysisSetPriorityFilesParams(files).toJson(); +- _send("analysis.setPriorityFiles", params); +- } +- +- void sendAnalysisSetSubscriptions( +- Map> subscriptions) { +- var params = new AnalysisSetSubscriptionsParams(subscriptions).toJson(); +- _send("analysis.setSubscriptions", params); +- } +- +- void sendAnalysisUpdateContent(Map files) { +- files.forEach((String path, dynamic overlay) { +- if (overlay is AddContentOverlay) { +- filesWithOverlays.add(path); +- } else if (overlay is RemoveContentOverlay) { +- filesWithOverlays.remove(path); +- } +- }); +- var params = new AnalysisUpdateContentParams(files).toJson(); +- _send('analysis.updateContent', params); +- } +- +- void sendAnalysisUpdateOptions(AnalysisOptions options) { +- var params = new AnalysisUpdateOptionsParams(options).toJson(); +- _send("analysis.updateOptions", params); +- } +- +- void sendCompletionGetSuggestions(String file, int offset) { +- var params = new CompletionGetSuggestionsParams(file, offset).toJson(); +- _send("completion.getSuggestions", params); +- } +- +- RequestData sendDiagnosticGetDiagnostics() { +- return _send("diagnostic.getDiagnostics", null); +- } +- +- RequestData sendEditFormat( +- String file, int selectionOffset, int selectionLength, +- {int lineLength}) { +- var params = new EditFormatParams(file, selectionOffset, selectionLength, +- lineLength: lineLength) +- .toJson(); +- return _send("edit.format", params); +- } +- +- RequestData sendEditGetAssists(String file, int offset, int length) { +- var params = new EditGetAssistsParams(file, offset, length).toJson(); +- return _send("edit.getAssists", params); +- } +- +- RequestData sendEditGetAvailableRefactorings( +- String file, int offset, int length) { +- var params = +- new EditGetAvailableRefactoringsParams(file, offset, length).toJson(); +- return _send("edit.getAvailableRefactorings", params); +- } +- +- RequestData sendEditGetFixes(String file, int offset) { +- var params = new EditGetFixesParams(file, offset).toJson(); +- return _send("edit.getFixes", params); +- } +- +- RequestData sendEditGetRefactoring(RefactoringKind kind, String file, +- int offset, int length, bool validateOnly, +- {RefactoringOptions options}) { +- var params = new EditGetRefactoringParams( +- kind, file, offset, length, validateOnly, +- options: options) +- .toJson(); +- return _send("edit.getRefactoring", params); +- } +- +- RequestData sendEditOrganizeDirectives(String file) { +- var params = new EditOrganizeDirectivesParams(file).toJson(); +- return _send("edit.organizeDirectives", params); +- } +- +- RequestData sendEditSortMembers(String file) { +- var params = new EditSortMembersParams(file).toJson(); +- return _send("edit.sortMembers", params); +- } +- +- RequestData sendExecutionCreateContext(String contextRoot) { +- var params = new ExecutionCreateContextParams(contextRoot).toJson(); +- return _send("execution.createContext", params); +- } +- +- RequestData sendExecutionDeleteContext(String id) { +- var params = new ExecutionDeleteContextParams(id).toJson(); +- return _send("execution.deleteContext", params); +- } +- +- RequestData sendExecutionMapUri(String id, {String file, String uri}) { +- var params = new ExecutionMapUriParams(id, file: file, uri: uri).toJson(); +- return _send("execution.mapUri", params); +- } +- +- RequestData sendExecutionSetSubscriptions( +- List subscriptions) { +- var params = new ExecutionSetSubscriptionsParams(subscriptions).toJson(); +- return _send("execution.setSubscriptions", params); +- } +- +- void sendSearchFindElementReferences( +- String file, int offset, bool includePotential) { +- var params = +- new SearchFindElementReferencesParams(file, offset, includePotential) +- .toJson(); +- _send("search.findElementReferences", params); +- } +- +- void sendSearchFindMemberDeclarations(String name) { +- var params = new SearchFindMemberDeclarationsParams(name).toJson(); +- _send("search.findMemberDeclarations", params); +- } +- +- void sendSearchFindMemberReferences(String name) { +- var params = new SearchFindMemberReferencesParams(name).toJson(); +- _send("search.findMemberReferences", params); +- } +- +- void sendSearchFindTopLevelDeclarations(String pattern) { +- var params = new SearchFindTopLevelDeclarationsParams(pattern).toJson(); +- _send("search.findTopLevelDeclarations", params); +- } +- +- void sendSearchGetTypeHierarchy(String file, int offset, {bool superOnly}) { +- var params = +- new SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly) +- .toJson(); +- _send("search.getTypeHierarchy", params); +- } +- +- RequestData sendServerGetVersion() { +- return _send("server.getVersion", null); +- } +- +- void sendServerSetSubscriptions(List subscriptions) { +- var params = new ServerSetSubscriptionsParams(subscriptions).toJson(); +- _send("server.setSubscriptions", params); +- } +- +- void sendServerShutdown() { +- _send("server.shutdown", null); +- } +- +- /** +- * Start the server and listen for communications from it. +- * +- * If [checked] is `true`, the server's VM will be running in checked mode. +- * +- * If [diagnosticPort] is not `null`, the server will serve status pages to +- * the specified port. +- * +- * If [profileServer] is `true`, the server will be started with "--observe" +- * and "--pause-isolates-on-exit", allowing the observatory to be used. +- * +- * If [useAnalysisHighlight2] is `true`, the server will use the new highlight +- * APIs. +- */ +- Future start( +- {bool checked: true, +- int diagnosticPort, +- bool profileServer: false, +- String sdkPath, +- int servicesPort, +- bool useAnalysisHighlight2: false}) async { +- if (_process != null) { +- throw new Exception('Process already started'); +- } +- String dartBinary = Platform.executable; +- String rootDir = +- _findRoot(Platform.script.toFilePath(windows: Platform.isWindows)); +- String serverPath = +- path.normalize(path.join(rootDir, 'bin', 'server.dart')); +- List arguments = []; +- // +- // Add VM arguments. +- // +- if (profileServer) { +- if (servicesPort == null) { +- arguments.add('--observe'); +- } else { +- arguments.add('--observe=$servicesPort'); +- } +- arguments.add('--pause-isolates-on-exit'); +- } else if (servicesPort != null) { +- arguments.add('--enable-vm-service=$servicesPort'); +- } +- if (Platform.packageRoot != null) { +- arguments.add('--package-root=${Platform.packageRoot}'); +- } +- if (Platform.packageConfig != null) { +- arguments.add('--packages=${Platform.packageConfig}'); +- } +- if (checked) { +- arguments.add('--checked'); +- } +- // +- // Add the server executable. +- // +- arguments.add(serverPath); +- // +- // Add server arguments. +- // +- if (diagnosticPort != null) { +- arguments.add('--port'); +- arguments.add(diagnosticPort.toString()); +- } +- if (sdkPath != null) { +- arguments.add('--sdk=$sdkPath'); +- } +- if (useAnalysisHighlight2) { +- arguments.add('--useAnalysisHighlight2'); +- } +-// stdout.writeln('Launching $serverPath'); +-// stdout.writeln('$dartBinary ${arguments.join(' ')}'); +- _process = await Process.start(dartBinary, arguments); +- _process.exitCode.then((int code) { +- if (code != 0) { +- throw new StateError('Server terminated with exit code $code'); +- } +- }); +- _listenToOutput(); +- _serverConnectedCompleter = new Completer(); +- return _serverConnectedCompleter.future; +- } +- +- /** +- * Find the root directory of the analysis_server package by proceeding +- * upward to the 'test' dir, and then going up one more directory. +- */ +- String _findRoot(String pathname) { +- while (!['benchmark', 'test'].contains(path.basename(pathname))) { +- String parent = path.dirname(pathname); +- if (parent.length >= pathname.length) { +- throw new Exception("Can't find root directory"); +- } +- pathname = parent; +- } +- return path.dirname(pathname); +- } +- +- /** +- * Handle a [notification] received from the server. +- */ +- void _handleNotification(Notification notification) { +- switch (notification.event) { +- case "server.connected": +-// new ServerConnectedParams.fromNotification(notification); +- _serverConnectedCompleter.complete(null); +- break; +- case "server.error": +-// new ServerErrorParams.fromNotification(notification); +- throw new StateError('Server error: ${notification.toJson()}'); +- break; +- case "server.status": +- if (_analysisFinishedCompleter != null) { +- ServerStatusParams params = +- new ServerStatusParams.fromNotification(notification); +- var analysis = params.analysis; +- if (analysis != null && !analysis.isAnalyzing) { +- _analysisFinishedCompleter.complete(null); +- } +- } +- break; +- case "analysis.analyzedFiles": +- AnalysisAnalyzedFilesParams params = +- new AnalysisAnalyzedFilesParams.fromNotification(notification); +- _analyzedFiles = params.directories; +- break; +- case "analysis.errors": +- AnalysisErrorsParams params = +- new AnalysisErrorsParams.fromNotification(notification); +- _errorMap.pathMap[params.file] = params.errors; +- break; +- case "analysis.flushResults": +-// new AnalysisFlushResultsParams.fromNotification(notification); +- _errorMap.pathMap.clear(); +- break; +- case "analysis.folding": +-// new AnalysisFoldingParams.fromNotification(notification); +- break; +- case "analysis.highlights": +-// new AnalysisHighlightsParams.fromNotification(notification); +- break; +- case "analysis.implemented": +-// new AnalysisImplementedParams.fromNotification(notification); +- break; +- case "analysis.invalidate": +-// new AnalysisInvalidateParams.fromNotification(notification); +- break; +- case "analysis.navigation": +-// new AnalysisNavigationParams.fromNotification(notification); +- break; +- case "analysis.occurrences": +-// new AnalysisOccurrencesParams.fromNotification(notification); +- break; +- case "analysis.outline": +-// new AnalysisOutlineParams.fromNotification(notification); +- break; +- case "analysis.overrides": +-// new AnalysisOverridesParams.fromNotification(notification); +- break; +- case "completion.results": +-// new CompletionResultsParams.fromNotification(notification); +- break; +- case "search.results": +-// new SearchResultsParams.fromNotification(notification); +- break; +- case "execution.launchData": +-// new ExecutionLaunchDataParams.fromNotification(notification); +- break; +- default: +- throw new StateError( +- 'Unhandled notification: ${notification.toJson()}'); +- } +- } +- +- /** +- * Handle a [response] received from the server. +- */ +- void _handleResponse(Response response) { +- String id = response.id.toString(); +- RequestData requestData = _requestDataMap[id]; +- requestData.recordResponse(response); +-// switch (requestData.method) { +-// case "analysis.getErrors": +-// break; +-// case "analysis.getHover": +-// break; +-// case "analysis.getLibraryDependencies": +-// break; +-// case "analysis.getNavigation": +-// break; +-// case "analysis.getReachableSources": +-// break; +-// case "analysis.reanalyze": +-// break; +-// case "analysis.setAnalysisRoots": +-// break; +-// case "analysis.setGeneralSubscriptions": +-// break; +-// case "analysis.setPriorityFiles": +-// break; +-// case "analysis.setSubscriptions": +-// break; +-// case 'analysis.updateContent': +-// break; +-// case "analysis.updateOptions": +-// break; +-// case "completion.getSuggestions": +-// break; +-// case "diagnostic.getDiagnostics": +-// break; +-// case "edit.format": +-// break; +-// case "edit.getAssists": +-// break; +-// case "edit.getAvailableRefactorings": +-// break; +-// case "edit.getFixes": +-// break; +-// case "edit.getRefactoring": +-// break; +-// case "edit.organizeDirectives": +-// break; +-// case "edit.sortMembers": +-// break; +-// case "execution.createContext": +-// break; +-// case "execution.deleteContext": +-// break; +-// case "execution.mapUri": +-// break; +-// case "execution.setSubscriptions": +-// break; +-// case "search.findElementReferences": +-// break; +-// case "search.findMemberDeclarations": +-// break; +-// case "search.findMemberReferences": +-// break; +-// case "search.findTopLevelDeclarations": +-// break; +-// case "search.getTypeHierarchy": +-// break; +-// case "server.getVersion": +-// break; +-// case "server.setSubscriptions": +-// break; +-// case "server.shutdown": +-// break; +-// default: +-// throw new StateError('Unhandled response: ${response.toJson()}'); +-// } +- } +- +- /** +- * Handle a [line] of input read from stderr. +- */ +- void _handleStdErr(String line) { +- String trimmedLine = line.trim(); +- logger?.log(fromStderr, '$trimmedLine'); +- throw new StateError('Message received on stderr: "$trimmedLine"'); +- } +- +- /** +- * Handle a [line] of input read from stdout. +- */ +- void _handleStdOut(String line) { +- /** +- * Cast the given [value] to a Map, or throw an [ArgumentError] if the value +- * cannot be cast. +- */ +- Map asMap(Object value) { +- if (value is Map) { +- return value; +- } +- throw new ArgumentError('Expected a Map, found a ${value.runtimeType}'); +- } +- +- String trimmedLine = line.trim(); +- if (trimmedLine.isEmpty || +- trimmedLine.startsWith('Observatory listening on ')) { +- return; +- } +- logger?.log(fromServer, '$trimmedLine'); +- Map message = asMap(JSON.decoder.convert(trimmedLine)); +- if (message.containsKey('id')) { +- // The message is a response. +- Response response = new Response.fromJson(message); +- _handleResponse(response); +- } else { +- // The message is a notification. +- Notification notification = new Notification.fromJson(message); +- String event = notification.event; +- _notificationCountMap[event] = (_notificationCountMap[event] ?? 0) + 1; +- _handleNotification(notification); +- } +- } +- +- /** +- * Start listening to output from the server. +- */ +- void _listenToOutput() { +- /** +- * Install the given [handler] to listen to transformed output from the +- * given [stream]. +- */ +- void installHandler(Stream> stream, handler(String line)) { +- stream +- .transform((new Utf8Codec()).decoder) +- .transform(new LineSplitter()) +- .listen(handler); +- } +- +- installHandler(_process.stdout, _handleStdOut); +- installHandler(_process.stderr, _handleStdErr); +- } +- +- /** +- * Send a command to the server. An 'id' will be automatically assigned. +- */ +- RequestData _send(String method, Map params, +- {void onResponse(Response response)}) { +- String id = '${_nextId++}'; +- RequestData requestData = new RequestData(id, method, params, currentTime); +- _requestDataMap[id] = requestData; +- Map command = { +- 'id': id, +- 'method': method +- }; +- if (params != null) { +- command['params'] = params; +- } +- String line = JSON.encode(command); +- _process.stdin.add(UTF8.encoder.convert('$line\n')); +- logger?.log(fromClient, '$line'); +- return requestData; +- } +-} +- +-/** +- * A utility class used to compare two sets of errors. +- */ +-class _ErrorComparator { +- /** +- * An empty list of analysis errors. +- */ +- static final List NO_ERRORS = []; +- +- /** +- * The buffer to which an error description will be written if any of the +- * files have different errors than are expected. +- */ +- final StringBuffer buffer; +- +- /** +- * Initialize a newly created comparator to write to the given [buffer]. +- */ +- _ErrorComparator(this.buffer); +- +- /** +- * Compare the [actualErrorMap] and the [expectedErrorMap], writing a +- * description to the [buffer] if they are not the same. The error maps are +- * expected to be maps from absolute file paths to the list of actual or +- * expected errors. +- */ +- void compare(Map> actualErrorMap, +- Map> expectedErrorMap) { +- Set allFiles = new HashSet(); +- allFiles.addAll(actualErrorMap.keys); +- allFiles.addAll(expectedErrorMap.keys); +- List sortedFiles = allFiles.toList()..sort(); +- for (String filePath in sortedFiles) { +- List actualErrors = actualErrorMap[filePath]; +- List expectedErrors = expectedErrorMap[filePath]; +- _compareLists( +- filePath, actualErrors ?? NO_ERRORS, expectedErrors ?? NO_ERRORS); +- } +- } +- +- /** +- * Compare the [actualErrors] and [expectedErrors], writing a description to +- * the [buffer] if they are not the same. +- */ +- void _compareLists(String filePath, List actualErrors, +- List expectedErrors) { +- List remainingExpected = +- new List.from(expectedErrors); +- for (AnalysisError actualError in actualErrors) { +- AnalysisError expectedError = _findError(remainingExpected, actualError); +- if (expectedError == null) { +- _writeReport(filePath, actualErrors, expectedErrors); +- return; +- } +- remainingExpected.remove(expectedError); +- } +- if (remainingExpected.isNotEmpty) { +- _writeReport(filePath, actualErrors, expectedErrors); +- } +- } +- +- /** +- * Return `true` if the [firstError] and the [secondError] are equivalent. +- */ +- bool _equalErrors(AnalysisError firstError, AnalysisError secondError) => +- firstError.severity == secondError.severity && +- firstError.type == secondError.type && +- _equalLocations(firstError.location, secondError.location) && +- firstError.message == secondError.message; +- +- /** +- * Return `true` if the [firstLocation] and the [secondLocation] are +- * equivalent. +- */ +- bool _equalLocations(Location firstLocation, Location secondLocation) => +- firstLocation.file == secondLocation.file && +- firstLocation.offset == secondLocation.offset && +- firstLocation.length == secondLocation.length; +- +- /** +- * Search through the given list of [errors] for an error that is equal to the +- * [targetError]. If one is found, return it, otherwise return `null`. +- */ +- AnalysisError _findError( +- List errors, AnalysisError targetError) { +- for (AnalysisError error in errors) { +- if (_equalErrors(error, targetError)) { +- return error; +- } +- } +- return null; +- } +- +- /** +- * Write the given list of [errors], preceded by a header beginning with the +- * given [prefix]. +- */ +- void _writeErrors(String prefix, List errors) { +- buffer.write(prefix); +- buffer.write(errors.length); +- buffer.write(' errors:'); +- for (AnalysisError error in errors) { +- buffer.writeln(); +- Location location = error.location; +- int offset = location.offset; +- buffer.write(' '); +- buffer.write(location.file); +- buffer.write(' ('); +- buffer.write(offset); +- buffer.write('..'); +- buffer.write(offset + location.length); +- buffer.write(') '); +- buffer.write(error.severity); +- buffer.write(', '); +- buffer.write(error.type); +- buffer.write(' : '); +- buffer.write(error.message); +- } +- } +- +- /** +- * Write a report of the differences between the [actualErrors] and the +- * [expectedErrors]. The errors are reported as being from the file at the +- * given [filePath]. +- */ +- void _writeReport(String filePath, List actualErrors, +- List expectedErrors) { +- if (buffer.length > 0) { +- buffer.writeln(); +- buffer.writeln(); +- } +- buffer.writeln(filePath); +- _writeErrors(' Expected ', expectedErrors); +- buffer.writeln(); +- _writeErrors(' Found ', actualErrors); +- } +-} +diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart +deleted file mode 100644 +index a736732eab6..00000000000 +--- a/pkg/analysis_server/test/test_all.dart ++++ /dev/null +@@ -1,61 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:test_reflective_loader/test_reflective_loader.dart'; +- +-import '../tool/spec/check_all_test.dart' as check_spec; +-import 'analysis/test_all.dart' as analysis_all; +-import 'analysis_server_test.dart' as analysis_server_test; +-import 'channel/test_all.dart' as channel_test; +-import 'completion_test.dart' as completion_test; +-import 'context_manager_test.dart' as context_manager_test; +-import 'domain_analysis_test.dart' as domain_analysis_test; +-import 'domain_completion_test.dart' as domain_completion_test; +-import 'domain_diagnostic_test.dart' as domain_experimental_test; +-import 'domain_execution_test.dart' as domain_execution_test; +-import 'domain_server_test.dart' as domain_server_test; +-import 'edit/test_all.dart' as edit_all; +-import 'plugin/test_all.dart' as plugin_all; +-import 'protocol_server_test.dart' as protocol_server_test; +-import 'protocol_test.dart' as protocol_test; +-import 'search/test_all.dart' as search_all; +-import 'services/test_all.dart' as services_all; +-import 'socket_server_test.dart' as socket_server_test; +-import 'src/test_all.dart' as src_all; +- +-/** +- * Utility for manually running all tests. +- */ +-main() { +- defineReflectiveSuite(() { +- analysis_all.main(); +- analysis_server_test.main(); +- channel_test.main(); +- completion_test.main(); +- context_manager_test.main(); +- domain_analysis_test.main(); +- domain_completion_test.main(); +- domain_execution_test.main(); +- domain_experimental_test.main(); +- domain_server_test.main(); +- edit_all.main(); +- plugin_all.main(); +- protocol_server_test.main(); +- protocol_test.main(); +- search_all.main(); +- services_all.main(); +- socket_server_test.main(); +- src_all.main(); +- defineReflectiveSuite(() { +- defineReflectiveTests(SpecTest); +- }, name: 'spec'); +- }, name: 'analysis_server'); +-} +- +-@reflectiveTest +-class SpecTest { +- test_specHasBeenGenerated() { +- check_spec.main(); +- } +-} +diff --git a/pkg/analysis_server/test/timing/completion/completion_simple.dart b/pkg/analysis_server/test/timing/completion/completion_simple.dart +deleted file mode 100644 +index 50cbaa2ed08..00000000000 +--- a/pkg/analysis_server/test/timing/completion/completion_simple.dart ++++ /dev/null +@@ -1,111 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +- +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +-import 'package:path/path.dart'; +- +-import '../timing_framework.dart'; +- +-/** +- * Perform the timing test, printing the minimum, average and maximum times, as +- * well as the standard deviation to the output. +- */ +-void main(List args) { +- SimpleTest test = new SimpleTest(); +- test.run().then((TimingResult result) { +- print('minTime = ${result.minTime}'); +- print('averageTime = ${result.averageTime}'); +- print('maxTime = ${result.maxTime}'); +- print('standardDeviation = ${result.standardDeviation}'); +- print(''); +- print('Press return to exit'); +- return stdin.first; +- }); +-} +- +-/** +- * A test of how long it takes to get code completion results after making a +- * minor change inside a method body. +- */ +-class SimpleTest extends TimingTest { +- /** +- * The path to the file in which code completion is to be performed. +- */ +- String mainFilePath; +- +- /** +- * The original content of the file. +- */ +- String originalContent; +- +- /** +- * The offset of the cursor when requesting code completion. +- */ +- int cursorOffset; +- +- /** +- * A completer that will be completed when code completion results have been +- * received from the server. +- */ +- Completer completionReceived; +- +- /** +- * Initialize a newly created test. +- */ +- SimpleTest(); +- +- @override +- Future oneTimeSetUp() { +- return super.oneTimeSetUp().then((_) { +- mainFilePath = sourcePath('test.dart'); +- originalContent = r''' +-class C { +- m() { +- return 0; +- } +-} +- +-f(C c) { +- return c; +-} +-'''; +- cursorOffset = originalContent.indexOf('c;') + 1; +- writeFile(mainFilePath, originalContent); +- }); +- } +- +- @override +- Future perform() { +- sendAnalysisUpdateContent({ +- mainFilePath: +- new ChangeContentOverlay([new SourceEdit(cursorOffset, 0, '.')]) +- }); +- sendCompletionGetSuggestions(mainFilePath, cursorOffset + 1); +- return completionReceived.future; +- } +- +- @override +- Future setUp() { +- completionReceived = new Completer(); +- onCompletionResults.listen((_) { +- // We only care about the time to the first response. +- if (!completionReceived.isCompleted) { +- completionReceived.complete(); +- } +- }); +- sendAnalysisSetAnalysisRoots([dirname(mainFilePath)], []); +- sendAnalysisUpdateContent( +- {mainFilePath: new AddContentOverlay(originalContent)}); +- return new Future.value(); +- } +- +- @override +- Future tearDown() { +- sendAnalysisSetAnalysisRoots([], []); +- return new Future.value(); +- } +-} +diff --git a/pkg/analysis_server/test/timing/timing_framework.dart b/pkg/analysis_server/test/timing/timing_framework.dart +deleted file mode 100644 +index 9c4be1f7b40..00000000000 +--- a/pkg/analysis_server/test/timing/timing_framework.dart ++++ /dev/null +@@ -1,312 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +-import 'dart:math'; +- +-import 'package:path/path.dart'; +- +-import '../integration/support/integration_test_methods.dart'; +-import '../integration/support/integration_tests.dart'; +- +-/** +- * Instances of the class [TimingResult] represent the timing information +- * gathered while executing a given timing test. +- */ +-class TimingResult { +- /** +- * The number of nanoseconds in a millisecond. +- */ +- static int NANOSECONDS_PER_MILLISECOND = 1000000; +- +- /** +- * The amount of time spent executing each test, in nanoseconds. +- */ +- List times; +- +- /** +- * Initialize a newly created timing result. +- */ +- TimingResult(this.times); +- +- /** +- * The average amount of time spent executing a single iteration, in +- * milliseconds. +- */ +- int get averageTime { +- return totalTime ~/ times.length; +- } +- +- /** +- * The maximum amount of time spent executing a single iteration, in +- * milliseconds. +- */ +- int get maxTime { +- int maxTime = 0; +- int count = times.length; +- for (int i = 0; i < count; i++) { +- maxTime = max(maxTime, times[i]); +- } +- return maxTime ~/ NANOSECONDS_PER_MILLISECOND; +- } +- +- /** +- * The minimum amount of time spent executing a single iteration, in +- * milliseconds. +- */ +- int get minTime { +- int minTime = times[0]; +- int count = times.length; +- for (int i = 1; i < count; i++) { +- minTime = min(minTime, times[i]); +- } +- return minTime ~/ NANOSECONDS_PER_MILLISECOND; +- } +- +- /** +- * The standard deviation of the times. +- */ +- double get standardDeviation { +- return computeStandardDeviation(toMilliseconds(times)); +- } +- +- /** +- * The total amount of time spent executing the test, in milliseconds. +- */ +- int get totalTime { +- int totalTime = 0; +- int count = times.length; +- for (int i = 0; i < count; i++) { +- totalTime += times[i]; +- } +- return totalTime ~/ NANOSECONDS_PER_MILLISECOND; +- } +- +- /** +- * Compute the standard deviation of the given set of [values]. +- */ +- double computeStandardDeviation(List values) { +- int count = values.length; +- double sumOfValues = 0.0; +- for (int i = 0; i < count; i++) { +- sumOfValues += values[i]; +- } +- double average = sumOfValues / count; +- double sumOfDiffSquared = 0.0; +- for (int i = 0; i < count; i++) { +- double diff = values[i] - average; +- sumOfDiffSquared += diff * diff; +- } +- return sqrt((sumOfDiffSquared / (count - 1))); +- } +- +- /** +- * Convert the given [times], expressed in nanoseconds, to times expressed in +- * milliseconds. +- */ +- List toMilliseconds(List times) { +- int count = times.length; +- List convertedValues = new List(); +- for (int i = 0; i < count; i++) { +- convertedValues.add(times[i] ~/ NANOSECONDS_PER_MILLISECOND); +- } +- return convertedValues; +- } +-} +- +-/** +- * The abstract class [TimingTest] defines the behavior of objects that measure +- * the time required to perform some sequence of server operations. +- */ +-abstract class TimingTest extends IntegrationTestMixin { +- /** +- * The number of times the test will be performed in order to warm up the VM. +- */ +- static final int DEFAULT_WARMUP_COUNT = 10; +- +- /** +- * The number of times the test will be performed in order to compute a time. +- */ +- static final int DEFAULT_TIMING_COUNT = 10; +- +- /** +- * The file suffix used to identify Dart files. +- */ +- static final String DART_SUFFIX = '.dart'; +- +- /** +- * The file suffix used to identify HTML files. +- */ +- static final String HTML_SUFFIX = '.html'; +- +- /** +- * The amount of time to give the server to respond to a shutdown request +- * before forcibly terminating it. +- */ +- static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5); +- +- /** +- * The connection to the analysis server. +- */ +- Server server; +- +- /** +- * The temporary directory in which source files can be stored. +- */ +- Directory sourceDirectory; +- +- /** +- * A flag indicating whether the teardown process should skip sending a +- * "server.shutdown" request because the server is known to have already +- * shutdown. +- */ +- bool skipShutdown = false; +- +- /** +- * Initialize a newly created test. +- */ +- TimingTest(); +- +- /** +- * Return the number of iterations that should be performed in order to +- * compute a time. +- */ +- int get timingCount => DEFAULT_TIMING_COUNT; +- +- /** +- * Return the number of iterations that should be performed in order to warm +- * up the VM. +- */ +- int get warmupCount => DEFAULT_WARMUP_COUNT; +- +- /** +- * Perform any operations that need to be performed once before any iterations. +- */ +- Future oneTimeSetUp() { +- initializeInttestMixin(); +- server = new Server(); +- sourceDirectory = Directory.systemTemp.createTempSync('analysisServer'); +- Completer serverConnected = new Completer(); +- onServerConnected.listen((_) { +- serverConnected.complete(); +- }); +- skipShutdown = true; +- return server.start(/*profileServer: true*/).then((_) { +- server.listenToOutput(dispatchNotification); +- server.exitCode.then((_) { +- skipShutdown = true; +- }); +- return serverConnected.future; +- }); +- } +- +- /** +- * Perform any operations that need to be performed once after all iterations. +- */ +- Future oneTimeTearDown() { +- return _shutdownIfNeeded().then((_) { +- sourceDirectory.deleteSync(recursive: true); +- }); +- } +- +- /** +- * Perform any operations that part of a single iteration. It is the execution +- * of this method that will be measured. +- */ +- Future perform(); +- +- /** +- * Return a future that will complete with a timing result representing the +- * number of milliseconds required to perform the operation the specified +- * number of times. +- */ +- Future run() async { +- List times = new List(); +- await oneTimeSetUp(); +- await _repeat(warmupCount, null); +- await _repeat(timingCount, times); +- await oneTimeTearDown(); +- return new Future.value(new TimingResult(times)); +- } +- +- /** +- * Perform any operations that need to be performed before each iteration. +- */ +- Future setUp(); +- +- /** +- * Convert the given [relativePath] to an absolute path, by interpreting it +- * relative to [sourceDirectory]. On Windows any forward slashes in +- * [relativePath] are converted to backslashes. +- */ +- String sourcePath(String relativePath) { +- return join(sourceDirectory.path, relativePath.replaceAll('/', separator)); +- } +- +- /** +- * Perform any operations that need to be performed after each iteration. +- */ +- Future tearDown(); +- +- /** +- * Write a source file with the given absolute [pathname] and [contents]. +- * +- * If the file didn't previously exist, it is created. If it did, it is +- * overwritten. +- * +- * Parent directories are created as necessary. +- */ +- void writeFile(String pathname, String contents) { +- new Directory(dirname(pathname)).createSync(recursive: true); +- new File(pathname).writeAsStringSync(contents); +- } +- +- /** +- * Return the number of nanoseconds that have elapsed since the given +- * [stopwatch] was last stopped. +- */ +- int _elapsedNanoseconds(Stopwatch stopwatch) { +- return (stopwatch.elapsedTicks * 1000000000) ~/ stopwatch.frequency; +- } +- +- /** +- * Repeatedly execute this test [count] times, adding timing information to +- * the given list of [times] if it is non-`null`. +- */ +- Future _repeat(int count, List times) { +- Stopwatch stopwatch = new Stopwatch(); +- return setUp().then((_) { +- stopwatch.start(); +- return perform().then((_) { +- stopwatch.stop(); +- if (times != null) { +- times.add(_elapsedNanoseconds(stopwatch)); +- } +- return tearDown().then((_) { +- if (count > 0) { +- return _repeat(count - 1, times); +- } else { +- return new Future.value(); +- } +- }); +- }); +- }); +- } +- +- /** +- * Shut the server down unless [skipShutdown] is `true`. +- */ +- Future _shutdownIfNeeded() { +- if (skipShutdown) { +- return new Future.value(); +- } +- // Give the server a short time to comply with the shutdown request; if it +- // doesn't exit, then forcibly terminate it. +- sendServerShutdown(); +- return server.exitCode.timeout(SHUTDOWN_TIMEOUT, onTimeout: () { +- return server.kill('server failed to exit'); +- }); +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/log/log.dart b/pkg/analysis_server/tool/instrumentation/log/log.dart +deleted file mode 100644 +index 544013cd027..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/log/log.dart ++++ /dev/null +@@ -1,1195 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-/** +- * A representation of the contents of an instrumentation log. +- */ +-import 'dart:convert'; +-import 'dart:math' as math; +- +-import 'package:analyzer/instrumentation/instrumentation.dart'; +-import 'package:path/path.dart' as path; +- +-/** +- * A boolean-valued function of one argument. +- */ +-typedef bool Predicate(T value); +- +-/** +- * A description of a group of log entries. +- */ +-class EntryGroup { +- /** +- * A list of all of the instances of this class. +- */ +- static final List groups = [ +- new EntryGroup._( +- 'nonTask', 'Non-task', (LogEntry entry) => entry is! TaskEntry), +- new EntryGroup._( +- 'errors', +- 'Errors', +- (LogEntry entry) => +- entry is ErrorEntry || +- entry is ExceptionEntry || +- (entry is NotificationEntry && entry.isServerError)), +- new EntryGroup._('malformed', 'Malformed', +- (LogEntry entry) => entry is MalformedLogEntry), +- new EntryGroup._('all', 'All', (LogEntry entry) => true), +- ]; +- +- /** +- * The unique id of the group. +- */ +- final String id; +- +- /** +- * The human-readable name of the group. +- */ +- final String name; +- +- /** +- * The filter used to determine which entries belong to the group. The filter +- * should return `true` for members and `false` for non-members. +- */ +- final Predicate filter; +- +- /** +- * Initialize a newly created entry group with the given state. +- */ +- EntryGroup._(this.id, this.name, this.filter); +- +- /** +- * Given a list of [entries], return all of the entries in the list that are +- * members of this group. +- */ +- List computeMembers(List entries) { +- return entries.where(filter).toList(); +- } +- +- /** +- * Return the entry group with the given [id], or `null` if there is no group +- * with the given id. +- */ +- static EntryGroup withId(String id) { +- for (EntryGroup group in groups) { +- if (group.id == id) { +- return group; +- } +- } +- return null; +- } +-} +- +-/** +- * A range of log entries, represented by the index of the first and last +- * entries in the range. +- */ +-class EntryRange { +- /** +- * The index of the first entry in the range. +- */ +- int firstIndex; +- +- /** +- * The index of the first entry in the range. +- */ +- int lastIndex; +- +- /** +- * Initialize a newly created range to represent the entries between the +- * [firstIndex] and the [lastIndex], inclusive. +- */ +- EntryRange(this.firstIndex, this.lastIndex); +-} +- +-/** +- * A log entry representing an Err entry. +- */ +-class ErrorEntry extends GenericEntry { +- /** +- * Initialize a newly created log entry. +- */ +- ErrorEntry( +- int index, int timeStamp, String entryKind, List components) +- : super(index, timeStamp, entryKind, components); +-} +- +-/** +- * A log entry representing an Ex entry. +- */ +-class ExceptionEntry extends GenericEntry { +- /** +- * Initialize a newly created log entry. +- */ +- ExceptionEntry( +- int index, int timeStamp, String entryKind, List components) +- : super(index, timeStamp, entryKind, components); +-} +- +-/** +- * A representation of a generic log entry. +- */ +-class GenericEntry extends LogEntry { +- /** +- * The kind of the log entry. +- */ +- String entryKind; +- +- /** +- * The components in the entry that follow the time stamp and entry kind. +- */ +- List components; +- +- /** +- * Initialize a newly created generic log entry to have the given [timeStamp], +- * [entryKind] and list of [components] +- */ +- GenericEntry(int index, int timeStamp, this.entryKind, this.components) +- : super(index, timeStamp); +- +- @override +- String get kind => entryKind; +- +- @override +- void _appendDetails(StringBuffer buffer) { +- super._appendDetails(buffer); +- for (String component in components) { +- buffer.write(component); +- buffer.write('
    '); +- } +- } +-} +- +-/** +- * A log entry representing an PluginErr entry. +- */ +-class GenericPluginEntry extends GenericEntry with PluginEntryMixin { +- /** +- * The components describing the plugin associated with this entry. +- */ +- final List pluginData; +- +- /** +- * Initialize a newly created log entry. +- */ +- GenericPluginEntry(int index, int timeStamp, String entryKind, +- List components, this.pluginData) +- : super(index, timeStamp, entryKind, components); +-} +- +-/** +- * A representation of an instrumentation log. +- */ +-class InstrumentationLog { +- /** +- * The paths of the log files containing the entries. +- */ +- List logFilePaths; +- +- /** +- * The entries in the instrumentation log. +- */ +- List logEntries; +- +- /** +- * A table mapping the entry groups that have been computed to the list of +- * entries in that group. +- */ +- Map> entryGroups = >{}; +- +- /** +- * A table mapping entries that are paired with another entry to the entry +- * with which they are paired. +- */ +- Map _pairedEntries = {}; +- +- /** +- * A table mapping the id's of requests to the entry representing the request. +- */ +- Map _requestMap = {}; +- +- /** +- * A table mapping the id's of plugin requests to the entry representing the +- * request. +- */ +- Map _pluginRequestMap = +- {}; +- +- /** +- * A table mapping the id's of responses to the entry representing the +- * response. +- */ +- Map _responseMap = {}; +- +- /** +- * A table mapping the id's of plugin responses to the entry representing the +- * response. +- */ +- Map _pluginResponseMap = +- {}; +- +- /** +- * A table mapping the ids of completion events to the events with those ids. +- */ +- Map> _completionMap = +- >{}; +- +- /** +- * The ranges of entries that are between analysis start and analysis end +- * notifications. +- */ +- List analysisRanges; +- +- /** +- * Initialize a newly created instrumentation log by parsing each of the lines +- * in the [logContent] into a separate entry. The log contents should be the +- * contents of the files whose paths are in the given list of [logFilePaths]. +- */ +- InstrumentationLog(this.logFilePaths, List logContent) { +- _parseLogContent(logContent); +- } +- +- /** +- * Return a list of the completion events associated with the given [id]. +- */ +- List completionEventsWithId(String id) => +- _completionMap[id]; +- +- /** +- * Return the log entries that are contained in the given [group]. +- */ +- List entriesInGroup(EntryGroup group) => +- entryGroups.putIfAbsent(group, () => group.computeMembers(logEntries)); +- +- /** +- * Return the entry that is paired with the given [entry], or `null` if there +- * is no entry paired with it. +- */ +- LogEntry pairedEntry(LogEntry entry) => _pairedEntries[entry]; +- +- /** +- * Return the response that corresponds to the given plugin request. +- */ +- PluginRequestEntry pluginRequestFor(PluginResponseEntry entry) => +- _pluginRequestMap[entry.id]; +- +- /** +- * Return the response that corresponds to the given request. +- */ +- PluginResponseEntry pluginResponseFor(PluginRequestEntry entry) => +- _pluginResponseMap[entry.id]; +- +- /** +- * Return the response that corresponds to the given request. +- */ +- RequestEntry requestFor(ResponseEntry entry) => _requestMap[entry.id]; +- +- /** +- * Return the response that corresponds to the given request. +- */ +- ResponseEntry responseFor(RequestEntry entry) => _responseMap[entry.id]; +- +- /** +- * Return a list containing all of the task entries between the start of +- * analysis notification at the given [startIndex] and the matching end of +- * analysis notification (or the end of the log if the log does not contain a +- * corresponding end notification. +- */ +- List taskEntriesFor(int startIndex) { +- List taskEntries = []; +- NotificationEntry startEntry = logEntries[startIndex]; +- LogEntry endEntry = pairedEntry(startEntry); +- int lastIndex = endEntry == null ? logEntries.length : endEntry.index; +- for (int i = startEntry.index + 1; i < lastIndex; i++) { +- LogEntry entry = logEntries[i]; +- if (entry is TaskEntry) { +- taskEntries.add(entry); +- } +- } +- return taskEntries; +- } +- +- /** +- * Return `true` if the given [logContent] appears to be from session data. +- */ +- bool _isSessionData(List logContent) { +- if (logContent.length < 2) { +- return false; +- } +- String firstLine = logContent[0]; +- return firstLine.startsWith('-----') && logContent[1].startsWith('~') || +- firstLine.startsWith('~'); +- } +- +- /** +- * Merge any multi-line entries into a single line so that every element in +- * the given [logContent] is a single entry. +- */ +- void _mergeEntries(List logContent) { +- bool isStartOfEntry(String line) { +- return line.startsWith(LogEntry.entryRegExp); +- } +- +- String merge(String line, List extraLines) { +- StringBuffer buffer = new StringBuffer(); +- buffer.writeln(line); +- for (String extraLine in extraLines) { +- buffer.writeln(extraLine); +- } +- return buffer.toString(); +- } +- +- List extraLines = []; +- for (int i = logContent.length - 1; i >= 0; i--) { +- String line = logContent[i]; +- if (isStartOfEntry(line)) { +- if (extraLines.isNotEmpty) { +- logContent[i] = merge(line, extraLines); +- } +- extraLines.clear(); +- } else { +- logContent.removeAt(i); +- extraLines.insert(0, line); +- } +- } +- if (extraLines.isNotEmpty) { +- int count = math.min(extraLines.length, 10); +- StringBuffer buffer = new StringBuffer(); +- buffer.writeln('${extraLines.length} non-entry lines before any entry'); +- buffer.writeln('First $count lines:'); +- for (int i = 0; i < count; i++) { +- buffer.writeln(extraLines[i]); +- } +- throw new StateError(buffer.toString()); +- } +- } +- +- /** +- * Parse the given [logContent] into a list of log entries. +- */ +- void _parseLogContent(List logContent) { +- if (_isSessionData(logContent)) { +- if (logContent[0].startsWith('-----')) { +- logContent.removeAt(0); +- } +- int lastIndex = logContent.length - 1; +- if (logContent[lastIndex].startsWith('extraction complete')) { +- logContent.removeAt(lastIndex); +- } +- } else { +- _mergeEntries(logContent); +- } +- logEntries = []; +- analysisRanges = []; +- NotificationEntry analysisStartEntry = null; +- int analysisStartIndex = -1; +- NotificationEntry pubStartEntry = null; +- for (String line in logContent) { +- LogEntry entry = new LogEntry.from(logEntries.length, line); +- if (entry != null) { +- logEntries.add(entry); +- if (entry is RequestEntry) { +- _requestMap[entry.id] = entry; +- } else if (entry is ResponseEntry) { +- _responseMap[entry.id] = entry; +- RequestEntry request = _requestMap[entry.id]; +- _pairedEntries[entry] = request; +- _pairedEntries[request] = entry; +- } else if (entry is NotificationEntry) { +- if (entry.isServerStatus) { +- var analysisStatus = entry.param('analysis'); +- if (analysisStatus is Map) { +- if (analysisStatus['isAnalyzing']) { +- if (analysisStartEntry != null) { +- analysisStartEntry.recordProblem( +- 'Analysis started without being terminated.'); +- } +- analysisStartEntry = entry; +- analysisStartIndex = logEntries.length - 1; +- } else { +- if (analysisStartEntry == null) { +- entry.recordProblem( +- 'Analysis terminated without being started.'); +- } else { +- int analysisEnd = logEntries.length - 1; +- analysisRanges +- .add(new EntryRange(analysisStartIndex, analysisEnd)); +- _pairedEntries[entry] = analysisStartEntry; +- _pairedEntries[analysisStartEntry] = entry; +- analysisStartEntry = null; +- analysisStartIndex = -1; +- } +- } +- } +- var pubStatus = entry.param('pub'); +- if (pubStatus is Map) { +- if (pubStatus['isListingPackageDirs']) { +- if (pubStartEntry != null) { +- pubStartEntry.recordProblem( +- 'Pub started without previous being terminated.'); +- } +- pubStartEntry = entry; +- } else { +- if (pubStartEntry == null) { +- entry.recordProblem('Pub terminated without being started.'); +- } else { +- _pairedEntries[entry] = pubStartEntry; +- _pairedEntries[pubStartEntry] = entry; +- pubStartEntry = null; +- } +- } +- } +- } else if (entry.event == 'completion.results') { +- String id = entry.param('id'); +- if (id != null) { +- _completionMap +- .putIfAbsent(id, () => new List()) +- .add(entry); +- } +- } +- } else if (entry is PluginRequestEntry) { +- _pluginRequestMap[entry.id] = entry; +- } else if (entry is PluginResponseEntry) { +- _pluginResponseMap[entry.id] = entry; +- PluginRequestEntry request = _pluginRequestMap[entry.id]; +- _pairedEntries[entry] = request; +- _pairedEntries[request] = entry; +- } +- } +- } +- if (analysisStartEntry != null) { +- analysisStartEntry +- .recordProblem('Analysis started without being terminated.'); +- } +- if (pubStartEntry != null) { +- pubStartEntry +- .recordProblem('Pub started without previous being terminated.'); +- } +- } +-} +- +-/** +- * A log entry that has a single JSON encoded component following the time stamp +- * and entry kind. +- */ +-abstract class JsonBasedEntry extends LogEntry { +- /** +- * The HTML string used to indent text when formatting the JSON [data]. +- */ +- static const String singleIndent = '   '; +- +- /** +- * The decoded form of the JSON encoded component. +- */ +- final Map data; +- +- /** +- * Initialize a newly created log entry to have the given [timeStamp] and +- * [data]. +- */ +- JsonBasedEntry(int index, int timeStamp, this.data) : super(index, timeStamp); +- +- @override +- void _appendDetails(StringBuffer buffer) { +- super._appendDetails(buffer); +- _format(buffer, '', data); +- } +- +- /** +- * Encode any character in the given [string] that would prevent source code +- * from being displayed correctly: end of line markers and spaces. +- */ +- String _encodeSourceCode(String string) { +- // TODO(brianwilkerson) This method isn't working completely. Some source +- // code produces an error of +- // "log?start=3175:261 Uncaught SyntaxError: missing ) after argument list" +- // in the sample log I was using. +- StringBuffer buffer = new StringBuffer(); +- int length = string.length; +- int index = 0; +- while (index < length) { +- int char = string.codeUnitAt(index); +- index++; +- // TODO(brianwilkerson) Handle tabs and other special characters. +- if (char == '\r'.codeUnitAt(0)) { +- if (index < length && string.codeUnitAt(index) == '\n'.codeUnitAt(0)) { +- index++; +- } +- buffer.write('
    '); +- } else if (char == '\n'.codeUnitAt(0)) { +- buffer.write('
    '); +- } else if (char == ' '.codeUnitAt(0)) { +- // Encode all spaces in order to accurately reproduce the original +- // source code when displaying it. +- buffer.write(' '); +- } else { +- buffer.writeCharCode(char); +- } +- } +- return buffer.toString(); +- } +- +- /** +- * Write an HTML representation the given JSON [object] to the given [buffer], +- * using the given [indent] to make the output more readable. +- */ +- void _format(StringBuffer buffer, String indent, Object object) { +- if (object is String) { +- buffer.write('"'); +- buffer.write(_encodeSourceCode(object)); +- buffer.write('"'); +- } else if (object is int || object is bool) { +- buffer.write(object); +- } else if (object is Map) { +- buffer.write('{
    '); +- object.forEach((Object key, Object value) { +- String newIndent = indent + singleIndent; +- buffer.write(newIndent); +- _format(buffer, newIndent, key); +- buffer.write(' : '); +- _format(buffer, newIndent, value); +- buffer.write('
    '); +- }); +- buffer.write(indent); +- buffer.write('}'); +- } else if (object is List) { +- buffer.write('[
    '); +- object.forEach((Object element) { +- String newIndent = indent + singleIndent; +- buffer.write(newIndent); +- _format(buffer, newIndent, element); +- buffer.write('
    '); +- }); +- buffer.write(indent); +- buffer.write(']'); +- } +- } +-} +- +-/** +- * A log entry representing a communication between the server and a plugin. +- */ +-abstract class JsonBasedPluginEntry extends JsonBasedEntry +- with PluginEntryMixin { +- /** +- * The components describing the plugin associated with this entry. +- */ +- final List pluginData; +- +- /** +- * Initialize a newly created entry to have the given [timeStamp] and +- * [notificationData] and to be associated with the plugin with the given +- * [pluginData]. +- */ +- JsonBasedPluginEntry( +- int index, int timeStamp, Map notificationData, this.pluginData) +- : super(index, timeStamp, notificationData); +-} +- +-/** +- * A single entry in an instrumentation log. +- */ +-abstract class LogEntry { +- /** +- * The character used to separate fields within an entry. +- */ +- static final int fieldSeparator = ':'.codeUnitAt(0); +- +- /** +- * A regular expression that will match the beginning of a valid log entry. +- */ +- static final RegExp entryRegExp = new RegExp('[0-9]+\\:'); +- +- /** +- * A table mapping kinds to the names of those kinds. +- */ +- static final Map kindMap = { +- 'Err': 'Error', +- 'Ex': 'Exception', +- 'Log': 'Log message', +- 'Mal': 'Malformed entry', +- 'Noti': 'Notification', +- 'Read': 'Read file', +- 'Req': 'Request', +- 'Res': 'Response', +- 'Perf': 'Performance data', +- 'SPResult': 'Subprocess result', +- 'SPStart': 'Subprocess start', +- 'Task': 'Task', +- 'Ver': 'Version information', +- 'Watch': 'Watch event', +- }; +- +- /** +- * The index of this entry in the log file. +- */ +- final int index; +- +- /** +- * The time at which the entry occurred. +- */ +- final int timeStamp; +- +- /** +- * A list containing the descriptions of problems that were found while +- * processing the log file, or `null` if no problems were found. +- */ +- List _problems = null; +- +- /** +- * Initialize a newly created log entry with the given [timeStamp]. +- */ +- LogEntry(this.index, this.timeStamp); +- +- /** +- * Create a log entry from the given encoded form of the [entry]. +- */ +- factory LogEntry.from(int index, String entry) { +- if (entry.isEmpty) { +- return null; +- } +- try { +- List components = _parseComponents(entry); +- int timeStamp; +- String component = components[0]; +- if (component.startsWith('~')) { +- component = component.substring(1); +- } +- timeStamp = int.parse(component); +- String entryKind = components[1]; +- if (entryKind == InstrumentationService.TAG_ANALYSIS_TASK) { +- return new TaskEntry(index, timeStamp, components[2], components[3]); +- } else if (entryKind == InstrumentationService.TAG_ERROR) { +- return new ErrorEntry( +- index, timeStamp, entryKind, components.sublist(2)); +- } else if (entryKind == InstrumentationService.TAG_EXCEPTION) { +- return new ExceptionEntry( +- index, timeStamp, entryKind, components.sublist(2)); +- } else if (entryKind == InstrumentationService.TAG_FILE_READ) { +- // Fall through +- } else if (entryKind == InstrumentationService.TAG_LOG_ENTRY) { +- // Fall through +- } else if (entryKind == InstrumentationService.TAG_NOTIFICATION) { +- Map requestData = JSON.decode(components[2]); +- return new NotificationEntry(index, timeStamp, requestData); +- } else if (entryKind == InstrumentationService.TAG_PERFORMANCE) { +- // Fall through +- } else if (entryKind == InstrumentationService.TAG_PLUGIN_ERROR) { +- return new PluginErrorEntry(index, timeStamp, entryKind, +- components.sublist(2, 4), components.sublist(4)); +- } else if (entryKind == InstrumentationService.TAG_PLUGIN_EXCEPTION) { +- return new PluginExceptionEntry(index, timeStamp, entryKind, +- components.sublist(2, 5), components.sublist(5)); +- } else if (entryKind == InstrumentationService.TAG_PLUGIN_NOTIFICATION) { +- Map requestData = JSON.decode(components[2]); +- return new PluginNotificationEntry( +- index, timeStamp, requestData, components.sublist(3)); +- } else if (entryKind == InstrumentationService.TAG_PLUGIN_REQUEST) { +- Map requestData = JSON.decode(components[2]); +- return new PluginRequestEntry( +- index, timeStamp, requestData, components.sublist(3)); +- } else if (entryKind == InstrumentationService.TAG_PLUGIN_RESPONSE) { +- Map responseData = JSON.decode(components[2]); +- return new PluginResponseEntry( +- index, timeStamp, responseData, components.sublist(3)); +- } else if (entryKind == InstrumentationService.TAG_PLUGIN_TIMEOUT) { +- return new PluginErrorEntry(index, timeStamp, entryKind, +- components.sublist(2, 3), components.sublist(3)); +- } else if (entryKind == InstrumentationService.TAG_REQUEST) { +- Map requestData = JSON.decode(components[2]); +- return new RequestEntry(index, timeStamp, requestData); +- } else if (entryKind == InstrumentationService.TAG_RESPONSE) { +- Map responseData = JSON.decode(components[2]); +- return new ResponseEntry(index, timeStamp, responseData); +- } else if (entryKind == InstrumentationService.TAG_SUBPROCESS_START) { +- // Fall through +- } else if (entryKind == InstrumentationService.TAG_SUBPROCESS_RESULT) { +- // Fall through +- } else if (entryKind == InstrumentationService.TAG_VERSION) { +- // Fall through +- } else if (entryKind == InstrumentationService.TAG_WATCH_EVENT) { +- // Fall through +- } +- return new GenericEntry( +- index, timeStamp, entryKind, components.sublist(2)); +- } catch (exception) { +- LogEntry logEntry = new MalformedLogEntry(index, entry); +- logEntry.recordProblem(exception.toString()); +- return logEntry; +- } +- } +- +- /** +- * Return `true` if any problems were found while processing the log file. +- */ +- bool get hasProblems => _problems != null; +- +- /** +- * Return the value of the component used to indicate the kind of the entry. +- * This is the abbreviation recorded in the entry. +- */ +- String get kind; +- +- /** +- * Return a human-readable representation of the kind of this entry. +- */ +- String get kindName => kindMap[kind] ?? kind; +- +- /** +- * Return a list containing the descriptions of problems that were found while +- * processing the log file, or `null` if no problems were found. +- */ +- List get problems => _problems; +- +- /** +- * Return a date that is equivalent to the [timeStamp]. +- */ +- DateTime get toTime => new DateTime.fromMillisecondsSinceEpoch(timeStamp); +- +- /** +- * Return an HTML representation of the details of the entry. +- */ +- String details() { +- StringBuffer buffer = new StringBuffer(); +- _appendDetails(buffer); +- return buffer.toString(); +- } +- +- /** +- * Record that the given [problem] was found while processing the log file. +- */ +- void recordProblem(String problem) { +- _problems ??= []; +- _problems.add(problem); +- } +- +- /** +- * Append details related to this entry to the given [buffer]. +- */ +- void _appendDetails(StringBuffer buffer) { +- if (_problems != null) { +- for (String problem in _problems) { +- buffer.write('

    $problem

    '); +- } +- } +- } +- +- /** +- * Parse the given encoded form of the [entry] into a list of components. The +- * first component is always the time stamp for when the entry was generated. +- * The second component is always the kind of the entry. The remaining +- * components depend on the kind of the entry. Return the components that were +- * parsed. +- */ +- static List _parseComponents(String entry) { +- List components = []; +- StringBuffer component = new StringBuffer(); +- int length = entry.length; +- for (int i = 0; i < length; i++) { +- int char = entry.codeUnitAt(i); +- if (char == fieldSeparator) { +- if (entry.codeUnitAt(i + 1) == fieldSeparator) { +- component.write(':'); +- i++; +- } else { +- components.add(component.toString()); +- component.clear(); +- } +- } else { +- component.writeCharCode(char); +- } +- } +- components.add(component.toString()); +- return components; +- } +-} +- +-/** +- * A representation of a malformed log entry. +- */ +-class MalformedLogEntry extends LogEntry { +- final String entry; +- +- MalformedLogEntry(int index, this.entry) : super(index, -1); +- +- @override +- String get kind => 'Mal'; +- +- @override +- void _appendDetails(StringBuffer buffer) { +- super._appendDetails(buffer); +- buffer.write(entry); +- buffer.write('
    '); +- } +-} +- +-/** +- * A log entry representing a notification that was sent from the server to the +- * client. +- */ +-class NotificationEntry extends JsonBasedEntry { +- /** +- * Initialize a newly created response to have the given [timeStamp] and +- * [notificationData]. +- */ +- NotificationEntry(int index, int timeStamp, Map notificationData) +- : super(index, timeStamp, notificationData); +- +- /** +- * Return the event field of the request. +- */ +- String get event => data['event']; +- +- /** +- * Return `true` if this is a server error notification. +- */ +- bool get isServerError => event == 'server.error'; +- +- /** +- * Return `true` if this is a server status notification. +- */ +- bool get isServerStatus => event == 'server.status'; +- +- @override +- String get kind => 'Noti'; +- +- /** +- * Return the value of the parameter with the given [parameterName], or `null` +- * if there is no such parameter. +- */ +- dynamic param(String parameterName) { +- var parameters = data['params']; +- if (parameters is Map) { +- return parameters[parameterName]; +- } +- return null; +- } +-} +- +-/** +- * A log entry representing a communication between the server and a plugin. +- */ +-abstract class PluginEntryMixin { +- /** +- * The components describing the plugin associated with this entry. +- */ +- List get pluginData; +- +- /** +- * The id of the plugin associated with this entry. +- */ +- String get pluginId => pluginData[0]; +- +- /** +- * The name of the plugin associated with this entry. +- */ +- String get pluginName => pluginData[1]; +- +- /** +- * The version of the plugin associated with this entry. +- */ +- String get pluginVersion => pluginData[2]; +- +- /** +- * Return a shortened version of the plugin id. +- */ +- String get shortPluginId { +- int index = pluginId.lastIndexOf(path.separator); +- if (index > 0) { +- return pluginId.substring(index + 1); +- } +- return pluginId; +- } +-} +- +-/** +- * A log entry representing an PluginErr entry. +- */ +-class PluginErrorEntry extends GenericPluginEntry { +- /** +- * Initialize a newly created log entry. +- */ +- PluginErrorEntry(int index, int timeStamp, String entryKind, +- List components, List pluginData) +- : super(index, timeStamp, entryKind, components, pluginData); +-} +- +-/** +- * A log entry representing an PluginEx entry. +- */ +-class PluginExceptionEntry extends GenericPluginEntry { +- /** +- * Initialize a newly created log entry. +- */ +- PluginExceptionEntry(int index, int timeStamp, String entryKind, +- List components, List pluginData) +- : super(index, timeStamp, entryKind, components, pluginData); +-} +- +-/** +- * A log entry representing a notification that was sent from a plugin to the +- * server. +- */ +-class PluginNotificationEntry extends JsonBasedPluginEntry { +- /** +- * Initialize a newly created notification to have the given [timeStamp] and +- * [notificationData]. +- */ +- PluginNotificationEntry( +- int index, int timeStamp, Map notificationData, List pluginData) +- : super(index, timeStamp, notificationData, pluginData); +- +- /** +- * Return the event field of the notification. +- */ +- String get event => data['event']; +- +- @override +- String get kind => 'PluginNoti'; +- +- /** +- * Return the value of the parameter with the given [parameterName], or `null` +- * if there is no such parameter. +- */ +- dynamic param(String parameterName) { +- var parameters = data['params']; +- if (parameters is Map) { +- return parameters[parameterName]; +- } +- return null; +- } +-} +- +-/** +- * A log entry representing a request that was sent from the server to a plugin. +- */ +-class PluginRequestEntry extends JsonBasedPluginEntry { +- /** +- * Initialize a newly created response to have the given [timeStamp] and +- * [requestData]. +- */ +- PluginRequestEntry( +- int index, int timeStamp, Map requestData, List pluginData) +- : super(index, timeStamp, requestData, pluginData); +- +- /** +- * Return the id field of the request. +- */ +- String get id => data['id']; +- +- @override +- String get kind => 'PluginReq'; +- +- /** +- * Return the method field of the request. +- */ +- String get method => data['method']; +- +- /** +- * Return the value of the parameter with the given [parameterName], or `null` +- * if there is no such parameter. +- */ +- dynamic param(String parameterName) { +- var parameters = data['params']; +- if (parameters is Map) { +- return parameters[parameterName]; +- } +- return null; +- } +-} +- +-/** +- * A log entry representing a response that was sent from a plugin to the +- * server. +- */ +-class PluginResponseEntry extends JsonBasedPluginEntry { +- /** +- * Initialize a newly created response to have the given [timeStamp] and +- * [responseData]. +- */ +- PluginResponseEntry( +- int index, int timeStamp, Map responseData, List pluginData) +- : super(index, timeStamp, responseData, pluginData); +- +- /** +- * Return the id field of the response. +- */ +- String get id => data['id']; +- +- @override +- String get kind => 'PluginRes'; +- +- /** +- * Return the value of the result with the given [resultName], or `null` if +- * there is no such result. +- */ +- dynamic result(String resultName) { +- var results = data['result']; +- if (results is Map) { +- return results[resultName]; +- } +- return null; +- } +-} +- +-/** +- * A log entry representing a request that was sent from the client to the +- * server. +- */ +-class RequestEntry extends JsonBasedEntry { +- /** +- * Initialize a newly created response to have the given [timeStamp] and +- * [requestData]. +- */ +- RequestEntry(int index, int timeStamp, Map requestData) +- : super(index, timeStamp, requestData); +- +- /** +- * Return the clientRequestTime field of the request. +- */ +- int get clientRequestTime => data['clientRequestTime']; +- +- /** +- * Return the id field of the request. +- */ +- String get id => data['id']; +- +- @override +- String get kind => 'Req'; +- +- /** +- * Return the method field of the request. +- */ +- String get method => data['method']; +- +- /** +- * Return the value of the parameter with the given [parameterName], or `null` +- * if there is no such parameter. +- */ +- dynamic param(String parameterName) { +- var parameters = data['params']; +- if (parameters is Map) { +- return parameters[parameterName]; +- } +- return null; +- } +-} +- +-/** +- * A log entry representing a response that was sent from the server to the +- * client. +- */ +-class ResponseEntry extends JsonBasedEntry { +- /** +- * Initialize a newly created response to have the given [timeStamp] and +- * [responseData]. +- */ +- ResponseEntry(int index, int timeStamp, Map responseData) +- : super(index, timeStamp, responseData); +- +- /** +- * Return the id field of the response. +- */ +- String get id => data['id']; +- +- @override +- String get kind => 'Res'; +- +- /** +- * Return the value of the result with the given [resultName], or `null` if +- * there is no such result. +- */ +- dynamic result(String resultName) { +- var results = data['result']; +- if (results is Map) { +- return results[resultName]; +- } +- return null; +- } +-} +- +-class TaskEntry extends LogEntry { +- /** +- * The path to the directory at the root of the context in which analysis was +- * being performed. +- */ +- final String context; +- +- /** +- * A description of the task that was performed. +- */ +- final String description; +- +- /** +- * The name of the class implementing the task. +- */ +- String _taskName = null; +- +- /** +- * The description of the target of the task. +- */ +- String _target = null; +- +- /** +- * Initialize a newly created entry with the given [index] and [timeStamp] to +- * represent the execution of an analysis task in the given [context] that is +- * described by the given [description]. +- */ +- TaskEntry(int index, int timeStamp, this.context, this.description) +- : super(index, timeStamp); +- +- @override +- String get kind => 'Task'; +- +- /** +- * Return the description of the target of the task. +- */ +- String get target { +- if (_target == null) { +- _splitDescription(); +- } +- return _target; +- } +- +- /** +- * Return the name of the class implementing the task. +- */ +- String get taskName { +- if (_taskName == null) { +- _splitDescription(); +- } +- return _taskName; +- } +- +- @override +- void _appendDetails(StringBuffer buffer) { +- super._appendDetails(buffer); +- buffer.write('Context: '); +- buffer.write(context); +- buffer.write('
    Description: '); +- buffer.write(description); +- } +- +- /** +- * Split the description to get the task name and target description. +- */ +- void _splitDescription() { +- int index = description.indexOf(' '); +- if (index < 0) { +- _taskName = ''; +- } else { +- _taskName = description.substring(0, index); +- } +- index = description.lastIndexOf(' '); +- _target = description.substring(index + 1); +- int slash = context.lastIndexOf('/'); +- if (slash < 0) { +- slash = context.lastIndexOf('\\'); +- } +- if (slash >= 0) { +- String prefix = context.substring(0, slash); +- _target = _target.replaceAll(prefix, '...'); +- } +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/log_viewer.dart b/pkg/analysis_server/tool/instrumentation/log_viewer.dart +deleted file mode 100644 +index 62d572236e7..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/log_viewer.dart ++++ /dev/null +@@ -1,129 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:io' as io; +- +-import 'package:args/args.dart'; +- +-import 'log/log.dart'; +-import 'server.dart'; +- +-/** +- * Start a web server that will allow an instrumentation log to be viewed. +- */ +-void main(List args) { +- Driver driver = new Driver(); +- driver.start(args); +-} +- +-/** +- * The main driver that configures and starts the web server. +- */ +-class Driver { +- /** +- * The flag used to specify that the user wants to have help text printed but +- * that no other work should be done. +- */ +- static String helpFlag = 'help'; +- +- /** +- * The option used to specify the port on which the server should listen for +- * requests. +- */ +- static String portOption = 'port'; +- +- /** +- * The port that will be used if no port number is provided on the command +- * line. +- */ +- static int defaultPortNumber = 11000; +- +- /** +- * Initialize a newly created driver. +- */ +- Driver(); +- +- /** +- * Create and return the parser used to parse the command-line arguments. +- */ +- ArgParser createParser() { +- ArgParser parser = new ArgParser(); +- parser.addFlag(helpFlag, help: 'Print this help text', negatable: false); +- parser.addOption(portOption, +- help: 'The port number on which the server should listen for requests', +- defaultsTo: defaultPortNumber.toString()); +- return parser; +- } +- +- /** +- * Print usage information. +- */ +- void printUsage(ArgParser parser, +- {String error, Object exception, StackTrace stackTrace}) { +- if (error != null) { +- print(error); +- print(''); +- } +- print('log_viewer [options] logFile'); +- print(''); +- print('Usage:'); +- print(''); +- print( +- 'The "logFile" is the file containing the content of the log that is being viewed'); +- print(''); +- print('Options:'); +- print(parser.usage); +- if (exception != null) { +- print(exception); +- } +- if (stackTrace != null) { +- print(stackTrace); +- } +- } +- +- /** +- * Use the given command-line [args] to configure and start the web server. +- */ +- void start(List args) { +- ArgParser parser = createParser(); +- ArgResults options = parser.parse(args); +- if (options[helpFlag]) { +- printUsage(parser); +- return; +- } +- +- int port = defaultPortNumber; +- try { +- port = int.parse(options[portOption]); +- } catch (exception) { +- printUsage(parser, error: 'Invalid port number'); +- return; +- } +- +- List arguments = options.rest; +- if (arguments == null || arguments.length != 1) { +- printUsage(parser, error: 'Missing log file'); +- return; +- } +- String fileName = arguments[0]; +- io.File logFile = new io.File(fileName); +- List lines; +- try { +- lines = logFile.readAsLinesSync(); +- } catch (exception, stackTrace) { +- printUsage(parser, +- error: 'Could not read file "$fileName":', +- exception: exception, +- stackTrace: stackTrace); +- return; +- } +- print('Log file contains ${lines.length} lines'); +- +- InstrumentationLog log = +- new InstrumentationLog([logFile.path], lines); +- WebServer server = new WebServer(log); +- server.serveHttp(port); +- print('logViewer is listening on http://localhost:$port/log'); +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/page/log_page.dart b/pkg/analysis_server/tool/instrumentation/page/log_page.dart +deleted file mode 100644 +index b53758015f5..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/page/log_page.dart ++++ /dev/null +@@ -1,331 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:math' as math; +- +-import '../log/log.dart'; +-import '../server.dart'; +-import 'page_writer.dart'; +- +-/** +- * A page writer that will produce the page containing access to the full +- * content of the log. +- */ +-class LogPage extends PageWriter { +- /** +- * The instrumentation log to be written. +- */ +- InstrumentationLog log; +- +- /** +- * The id of the entry groups to be displayed. +- */ +- EntryGroup selectedGroup; +- +- /** +- * The entries in the selected group. +- */ +- List entries; +- +- /** +- * The index of the first entry to be written. +- */ +- int pageStart = 0; +- +- /** +- * The number of entries to be written, or `null` if all of the entries should +- * be written. +- */ +- int pageLength = null; +- +- /** +- * The number of digits in the event stamps that are the same for every entry. +- */ +- int prefixLength; +- +- /** +- * A table mapping the ids of plugins to an index for the plugin. +- */ +- Map pluginIdMap = {}; +- +- /** +- * Initialize a newly created writer to write the content of the given +- * [instrumentationLog]. +- */ +- LogPage(this.log); +- +- /** +- * Return the encoding for the given [pluginId] that is used to build anchors. +- */ +- int getPluginId(String pluginId) { +- return pluginIdMap.putIfAbsent(pluginId, () => pluginIdMap.length); +- } +- +- @override +- void writeBody(StringSink sink) { +- entries = log.entriesInGroup(selectedGroup); +- prefixLength = computePrefixLength(entries); +- +- writeMenu(sink); +- writeTwoColumns( +- sink, 'leftColumn', _writeLeftColumn, 'rightColumn', _writeRightColumn); +- } +- +- @override +- void writeScripts(StringSink sink) { +- super.writeScripts(sink); +- sink.writeln(r''' +-var highlightedRows = []; +-function clearHighlight() { +- for (i = 0; i < highlightedRows.length; i++) { +- setFontWeight(highlightedRows[i], "normal"); +- } +-} +-function highlight(requestId, responseId) { +- clearHighlight(); +- setFontWeight(requestId, "bold"); +- setFontWeight(responseId, "bold"); +- highlightedRows = [requestId, responseId]; +-} +-function setFontWeight(id, weight) { +- var element = document.getElementById(id); +- if (element != null) { +- element.style.fontWeight = weight; +- } +-} +-function setDetails(detailsContent) { +- var element = document.getElementById("details"); +- if (element != null) { +- element.innerHTML = detailsContent; +- } +-} +-function selectEntryGroup(pageStart) { +- var element = document.getElementById("entryGroup"); +- var url = "/log?group=" + element.value; +- window.location.assign(url); +-} +-'''); +- } +- +- /** +- * Write the content of the style sheet (without the 'script' tag) for the +- * page to the given [sink]. +- */ +- void writeStyleSheet(StringSink sink) { +- super.writeStyleSheet(sink); +- writeTwoColumnStyles(sink, 'leftColumn', 'rightColumn'); +- } +- +- /** +- * Return the number of milliseconds elapsed between the [startEntry] and the +- * [endEntry], or a question . +- */ +- String _getDuration(LogEntry startEntry, LogEntry endEntry) { +- if (startEntry != null && endEntry != null) { +- return (endEntry.timeStamp - startEntry.timeStamp).toString(); +- } +- return '?'; +- } +- +- /** +- * Write the given log [entry] to the given [sink]. +- */ +- void _writeEntry(StringSink sink, LogEntry entry) { +- String id = null; +- String clickHandler = 'clearHighlight()'; +- String icon = ''; +- String description = entry.kindName; +- if (entry is RequestEntry) { +- String entryId = entry.id; +- id = 'req$entryId'; +- clickHandler = 'highlight(\'req$entryId\', \'res$entryId\')'; +- icon = '→'; +- description = entry.method; +- } else if (entry is ResponseEntry) { +- String entryId = entry.id; +- RequestEntry request = log.requestFor(entry); +- id = 'res$entryId'; +- clickHandler = 'highlight(\'req$entryId\', \'res$entryId\')'; +- icon = '←'; +- if (request != null) { +- int latency = entry.timeStamp - request.timeStamp; +- description = +- '${request.method} ($latency ms)'; +- } +- } else if (entry is NotificationEntry) { +- id = 'e${entry.index}'; +- LogEntry pairedEntry = log.pairedEntry(entry); +- if (pairedEntry != null) { +- String pairedId = 'e${pairedEntry.index}'; +- clickHandler = 'highlight(\'$id\', \'$pairedId\')'; +- } +- icon = '←'; +- description = entry.event; +- if (entry.isServerStatus) { +- var analysisStatus = entry.param('analysis'); +- if (analysisStatus is Map) { +- if (analysisStatus['isAnalyzing']) { +- description = +- '$description (analysis) (
    tasks)'; +- } else { +- String duration = _getDuration(pairedEntry, entry); +- description = +- '$description (analysis - $duration ms)'; +- } +- } +- var pubStatus = entry.param('pub'); +- if (pubStatus is Map) { +- if (pubStatus['isListingPackageDirs']) { +- description = '$description (pub)'; +- } else { +- String duration = _getDuration(pairedEntry, entry); +- description = +- '$description (pub - $duration ms)'; +- } +- } +- } +- } else if (entry is PluginRequestEntry) { +- String entryId = entry.id; +- int pluginId = getPluginId(entry.pluginId); +- id = 'req$pluginId.$entryId'; +- clickHandler = +- 'highlight(\'req$pluginId.$entryId\', \'res$pluginId.$entryId\')'; +- icon = '→'; +- description = '${entry.method} (${entry.shortPluginId})'; +- } else if (entry is PluginResponseEntry) { +- String entryId = entry.id; +- int pluginId = getPluginId(entry.pluginId); +- PluginRequestEntry request = log.pluginRequestFor(entry); +- id = 'res$pluginId.$entryId'; +- clickHandler = +- 'highlight(\'req$pluginId.$entryId\', \'res$pluginId.$entryId\')'; +- icon = '←'; +- if (request != null) { +- int latency = entry.timeStamp - request.timeStamp; +- description = +- '${request.method} ($latency ms) (${entry.shortPluginId})'; +- } +- } else if (entry is PluginNotificationEntry) { +- id = 'e${entry.index}'; +- LogEntry pairedEntry = log.pairedEntry(entry); +- if (pairedEntry != null) { +- String pairedId = 'e${pairedEntry.index}'; +- clickHandler = 'highlight(\'$id\', \'$pairedId\')'; +- } +- icon = '←'; +- description = '${entry.event} (${entry.shortPluginId})'; +- } else if (entry is TaskEntry) { +- description = entry.description; +- } else if (entry is ErrorEntry) { +- description = '$description'; +- } else if (entry is PluginErrorEntry) { +- description = +- '$description (${entry.shortPluginId})'; +- } else if (entry is ExceptionEntry) { +- description = '$description'; +- } else if (entry is MalformedLogEntry) { +- description = '$description'; +- } +- id = id == null ? '' : 'id="$id" '; +- clickHandler = '$clickHandler; setDetails(\'${escape(entry.details())}\')'; +- String timeStamp = entry.timeStamp.toString(); +- if (prefixLength > 0) { +- timeStamp = timeStamp.substring(prefixLength); +- } +- +- sink.writeln(''); +- sink.writeln('$icon'); +- sink.writeln(''); +- sink.writeln(timeStamp); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(description); +- sink.writeln(''); +- sink.writeln(''); +- } +- +- /** +- * Write the entries in the instrumentation log to the given [sink]. +- */ +- void _writeLeftColumn(StringSink sink) { +- int length = entries.length; +- int pageEnd = +- pageLength == null ? length : math.min(pageStart + pageLength, length); +- // +- // Write the header of the column. +- // +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln(''); +- if (length == 0) { +- sink.writeln('No matching events'); +- } else { +- sink.writeln('Events $pageStart - ${pageEnd - 1} of $length'); +- } +- sink.writeln('
    '); +- +- sink.writeln('
    '); +- if (pageStart == 0) { +- sink.writeln(''); +- } else { +- sink.write(''); +- } +- // TODO(brianwilkerson) Add a text field for selecting the start index. +- if (pageEnd == length) { +- sink.writeln(''); +- } else { +- sink.write(''); +- } +- sink.writeln('
    '); +- sink.writeln('
    '); +- // +- // Write the main body of the column. +- // +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- for (int i = pageStart; i < pageEnd; i++) { +- LogEntry entry = entries[i]; +- _writeEntry(sink, entry); +- } +- sink.writeln('
    TimeKind
    '); +- } +- +- /** +- * Write a placeholder to the given [sink] where the details of a selected +- * entry can be displayed. +- */ +- void _writeRightColumn(StringSink sink) { +- // +- // Write the header of the column. +- // +- sink.writeln('
    '); +- sink.writeln('

    Entry Details

    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/page/page_writer.dart b/pkg/analysis_server/tool/instrumentation/page/page_writer.dart +deleted file mode 100644 +index dca5673452b..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/page/page_writer.dart ++++ /dev/null +@@ -1,317 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:convert'; +- +-import '../log/log.dart'; +-import '../server.dart'; +- +-typedef void Writer(StringSink sink); +- +-/** +- * A class used to write an HTML page. +- */ +-abstract class PageWriter { +- /** +- * The object used to escape special HTML characters. +- */ +- static final HtmlEscape htmlEscape = new HtmlEscape(); +- +- /** +- * Initialize a newly create page writer. +- */ +- PageWriter(); +- +- /** +- * Return the length of the common prefix for time stamps associated with the +- * given log [entries]. +- */ +- int computePrefixLength(List entries) { +- int length = entries.length; +- if (length < 2) { +- return 0; +- } +- String firstTime = entries[0].timeStamp.toString(); +- String lastTime = entries[length - 1].timeStamp.toString(); +- int prefixLength = 0; +- int timeLength = firstTime.length; +- while (prefixLength < timeLength && +- firstTime.codeUnitAt(prefixLength) == +- lastTime.codeUnitAt(prefixLength)) { +- prefixLength++; +- } +- return prefixLength; +- } +- +- /** +- * Return an escaped version of the given [unsafe] text. +- */ +- String escape(String unsafe) { +- // We double escape single quotes because the escaped characters are +- // processed as part of reading the HTML, which means that single quotes +- // end up terminating string literals too early when they appear in event +- // handlers (which in turn leads to JavaScript syntax errors). +- return htmlEscape.convert(unsafe).replaceAll(''', '&#39;'); +- } +- +- /** +- * Write the body of the page (without the 'body' tag) to the given [sink]. +- */ +- void writeBody(StringSink sink); +- +- /** +- * Write the given [date] to the given [sink]. +- */ +- void writeDate(StringSink sink, DateTime date) { +- String isoString = date.toIso8601String(); +- int index = isoString.indexOf('T'); +- String dateString = isoString.substring(0, index); +- String timeString = isoString.substring(index + 1); +- sink.write(dateString); +- sink.write(' at '); +- sink.write(timeString); +- } +- +- /** +- * Write the body of the page (without the 'body' tag) to the given [sink]. +- */ +- void writeMenu(StringSink sink) { +- sink.writeln(''); +- } +- +- /** +- * Write the contents of the instrumentation log to the given [sink]. +- */ +- void writePage(StringSink sink) { +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln( +- ''); +- sink.writeln('Instrumentation Log'); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- writeBody(sink); +- sink.writeln(''); +- sink.writeln(''); +- } +- +- /** +- * Write the scripts for the page (without the 'script' tag) to the given +- * [sink]. +- */ +- void writeScripts(StringSink sink) { +- // No common scripts. +- } +- +- /** +- * Write the content of the style sheet (without the 'script' tag) for the +- * page to the given [sink]. +- */ +- void writeStyleSheet(StringSink sink) { +- sink.writeln(r''' +-a { +- color: #000000; +- text-decoration: none; +-} +-a.menuItem { +- font-weight: bold; +-} +-body { +- font-family: sans-serif; +- height: 100%; +- margin: 0px; +- overflow: hidden; +- padding: 0px; +- width: 100%; +-} +-div.columnHeader { +-} +-div.button { +- display: inline-block; +- border-radius: 4px; +- border: 1px solid; +- height: 16px; +- text-align: center; +- vertical-align: middle; +- width: 16px; +-} +-div.inset { +- padding: 10px; +-} +-div.menu { +- background-color: #cce6ff; +- padding: 5px; +-} +-html { +- height: 100%; +- width: 100%; +-} +-span.button { +- border-radius: 5px; +- border: 1px solid; +- height: 16px; +- width: 16px; +-} +-span.error { +- color: #ff0000; +-} +-span.gray { +- color: #777777; +-} +-span.label { +- font-weight: bold; +-} +-table.fullWidth { +- border: 0px; +- width: 100%; +-} +-td.halfWidth { +- width: 50%; +- vertical-align: top; +-} +-td.int { +- text-align: right; +-} +-th { +- text-align: left; +-} +-th.narrow { +- width: 16px; +-} +- +-#container { +- height: 100%; +- min-height: 100%; +- position: relative; +- width: 100%; +-} +-#content { +- height: 90%; +- width: 100%; +-} +-'''); +- } +- +- /** +- * Write to the given [sink] the HTML required to display content in two +- * columns. The content of the columns will be written by the functions +- * [writeLeftColumn], [writeCenterColumn] and [writeRightColumn] and will be +- * contained in 'div' elements with the id's [leftColumnId], [centerColumnId] +- * and [rightColumnId]. +- */ +- void writeThreeColumns( +- StringSink sink, +- String leftColumnId, +- Writer writeLeftColumn, +- String centerColumnId, +- Writer writeCenterColumn, +- String rightColumnId, +- Writer writeRightColumn) { +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- writeLeftColumn(sink); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- writeRightColumn(sink); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- writeCenterColumn(sink); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- } +- +- /** +- * Writeto the given [sink] the styles needed by a three column section where +- * the columns have the ids [leftColumnId], [centerColumnId] and +- * [rightColumnId]. +- */ +- void writeThreeColumnStyles(StringSink sink, String leftColumnId, +- String centerColumnId, String rightColumnId) { +- sink.writeln(''' +-#$leftColumnId { +- float: left; +- height: 100%; +- overflow: auto; +- width: 33%; +-} +-#$centerColumnId { +- height: 100%; +- overflow: auto; +- width: 33%; +-} +-#$rightColumnId { +- float: right; +- height: 100%; +- overflow: auto; +- width: 33%; +-} +-'''); +- } +- +- /** +- * Write to the given [sink] the HTML required to display content in two +- * columns. The content of the columns will be written by the functions +- * [writeLeftColumn] and [writeRightColumn] and will be contained in 'div' +- * elements with the id's [leftColumnId] and [rightColumnId]. +- */ +- void writeTwoColumns(StringSink sink, String leftColumnId, +- Writer writeLeftColumn, String rightColumnId, Writer writeRightColumn) { +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- writeLeftColumn(sink); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- writeRightColumn(sink); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- } +- +- /** +- * Writeto the given [sink] the styles needed by a two column section where +- * the columns have the ids [leftColumnId] and [rightColumnId]. +- */ +- void writeTwoColumnStyles( +- StringSink sink, String leftColumnId, String rightColumnId) { +- sink.writeln(''' +-#$leftColumnId { +- float: left; +- height: 100%; +- overflow: auto; +- width: 50%; +-} +-#$rightColumnId { +- float: right; +- height: 100%; +- overflow: auto; +- width: 50%; +-} +-'''); +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/page/stats_page.dart b/pkg/analysis_server/tool/instrumentation/page/stats_page.dart +deleted file mode 100644 +index a8932a16920..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/page/stats_page.dart ++++ /dev/null +@@ -1,265 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import '../log/log.dart'; +-import 'page_writer.dart'; +- +-/** +- * A page writer that will produce the page containing statistics about an +- * instrumentation log. +- */ +-class StatsPage extends PageWriter { +- /** +- * The instrumentation log to be written. +- */ +- final InstrumentationLog log; +- +- /** +- * A table mapping the kinds of entries in the log to the number of each kind. +- */ +- final Map entryCounts = {}; +- +- /** +- * The number of responses that returned an error. +- */ +- int errorCount = 0; +- +- /** +- * The number of responses from each plugin that returned an error. +- */ +- Map pluginErrorCount = {}; +- +- /** +- * A table mapping request method names to a list of the latencies associated +- * with those requests, where the latency is defined to be the time between +- * when the request was sent by the client and when the server started +- * processing the request. +- */ +- final Map> latencyData = >{}; +- +- /** +- * A table mapping request method names to a list of the latencies associated +- * with those requests, where the latency is defined to be the time between +- * when the request was sent by the server and when the plugin sent a response. +- */ +- final Map>> pluginResponseData = +- >>{}; +- +- /** +- * A list of the number of milliseconds between a completion request and the +- * first event for that request. +- */ +- final List completionResponseTimes = []; +- +- /** +- * Initialize a newly created page writer to write information about the given +- * instrumentation [log]. +- */ +- StatsPage(this.log) { +- _processEntries(log.logEntries); +- } +- +- @override +- void writeBody(StringSink sink) { +- writeMenu(sink); +- writeTwoColumns( +- sink, 'leftColumn', _writeLeftColumn, 'rightColumn', _writeRightColumn); +- } +- +- /** +- * Write the content of the style sheet (without the 'script' tag) for the +- * page to the given [sink]. +- */ +- void writeStyleSheet(StringSink sink) { +- super.writeStyleSheet(sink); +- writeTwoColumnStyles(sink, 'leftColumn', 'rightColumn'); +- } +- +- /** +- * Return the mean of the values in the given list of [values]. +- */ +- int _mean(List values) { +- int sum = values.fold(0, (int sum, int latency) => sum + latency); +- return sum ~/ values.length; +- } +- +- /** +- * Return a table mapping the kinds of the given [entries] to the number of +- * each kind. +- */ +- void _processEntries(List entries) { +- void increment(Map map, K key) { +- map[key] = (map[key] ?? 0) + 1; +- } +- +- for (LogEntry entry in entries) { +- String kind = entry.kind; +- increment(entryCounts, kind); +- if (entry is ResponseEntry) { +- if (entry.result('error') != null) { +- errorCount++; +- } +- } else if (entry is RequestEntry) { +- String method = entry.method; +- int latency = entry.timeStamp - entry.clientRequestTime; +- latencyData.putIfAbsent(method, () => new List()).add(latency); +- if (method == 'completion.getSuggestions') { +- ResponseEntry response = log.responseFor(entry); +- if (response != null) { +- String id = response.result('id'); +- if (id != null) { +- List events = log.completionEventsWithId(id); +- if (events != null && events.length > 0) { +- completionResponseTimes +- .add(events[0].timeStamp - entry.timeStamp); +- } +- } +- } +- } +- } else if (entry is PluginResponseEntry) { +- if (entry.result('error') != null) { +- int count = pluginErrorCount[entry.pluginId] ?? 0; +- pluginErrorCount[entry.pluginId] = count + 1; +- } +- } else if (entry is PluginRequestEntry) { +- PluginResponseEntry response = log.pluginResponseFor(entry); +- int responseTime = response.timeStamp - entry.timeStamp; +- var pluginData = pluginResponseData.putIfAbsent( +- entry.pluginId, () => >{}); +- pluginData +- .putIfAbsent(entry.method, () => new List()) +- .add(responseTime); +- } +- } +- } +- +- void _writeLeftColumn(StringSink sink) { +- List filePaths = log.logFilePaths; +- List entries = log.logEntries; +- DateTime startDate = entries[0].toTime; +- DateTime endDate = entries[entries.length - 1].toTime; +- Duration duration = endDate.difference(startDate); +- List entryKinds = entryCounts.keys.toList()..sort(); +- +- sink.writeln('

    General

    '); +- sink.writeln('

    '); +- if (filePaths.length == 1) { +- sink.write('Log file: '); +- sink.write(filePaths[0]); +- } else { +- sink.write('Log files: '); +- bool needsSeparator = false; +- for (String path in filePaths) { +- if (needsSeparator) { +- sink.write(', '); +- } else { +- needsSeparator = true; +- } +- sink.write(path); +- } +- } +- sink.writeln('
    '); +- sink.write('Start time: '); +- writeDate(sink, startDate); +- sink.writeln('
    '); +- sink.write('End time: '); +- writeDate(sink, endDate); +- sink.writeln('
    '); +- sink.write('Duration: '); +- sink.write(duration.toString()); +- sink.writeln('

    '); +- +- sink.writeln('

    Entries

    '); +- sink.write('

    '); +- sink.write('Number of entries: '); +- sink.write(entries.length); +- sink.writeln('

    '); +- sink.write('

    '); +- sink.write('Error count: '); +- sink.write(errorCount); +- sink.writeln('

    '); +- pluginErrorCount.forEach((String pluginId, int count) { +- sink.write('

    '); +- sink.write('Errors from $pluginId: '); +- sink.write(count); +- sink.writeln('

    '); +- }); +- sink.writeln(''); +- sink.writeln(''); +- for (String kind in entryKinds) { +- sink.write(''); +- } +- sink.write(''); +- sink.writeln('
    countkind
    '); +- sink.write(entryCounts[kind]); +- sink.write(''); +- sink.write(kind); +- sink.writeln('
    '); +- sink.write(entries.length); +- sink.writeln('Total
    '); +- } +- +- void _writeRightColumn(StringSink sink) { +- completionResponseTimes.sort(); +- +- sink.writeln('

    Latency

    '); +- sink.write('

    '); +- sink.write('Latency by method'); +- sink.writeln('

    '); +- sink.writeln(''); +- sink.writeln( +- ''); +- List methodNames = latencyData.keys.toList()..sort(); +- for (String method in methodNames) { +- List latencies = latencyData[method]..sort(); +- // TODO(brianwilkerson) Add a spark-line distribution graph. +- sink.write(''); +- } +- sink.writeln('
    minmeanmaxmethod
    '); +- sink.write(latencies[0]); +- sink.write(''); +- sink.write(_mean(latencies)); +- sink.write(''); +- sink.write(latencies[latencies.length - 1]); +- sink.write(''); +- sink.write(method); +- sink.writeln('
    '); +- +- sink.writeln('

    Completion

    '); +- sink.write('

    '); +- sink.write('Time to first notification: '); +- sink.write(completionResponseTimes[0]); +- sink.write(', '); +- sink.write(_mean(completionResponseTimes)); +- sink.write(', '); +- sink.write(completionResponseTimes[completionResponseTimes.length - 1]); +- sink.writeln('

    '); +- +- if (pluginResponseData.isNotEmpty) { +- sink.writeln('

    Plugin response times

    '); +- pluginResponseData +- .forEach((String pluginId, Map> responseData) { +- sink.write('

    '); +- sink.write(pluginId); +- sink.writeln('

    '); +- sink.writeln(''); +- List methodNames = responseData.keys.toList()..sort(); +- for (String method in methodNames) { +- List responseTimes = responseData[method]..sort(); +- // TODO(brianwilkerson) Add a spark-line distribution graph. +- sink.write(''); +- } +- sink.writeln('
    '); +- sink.write(responseTimes[0]); +- sink.write(''); +- sink.write(_mean(responseTimes)); +- sink.write(''); +- sink.write(responseTimes[responseTimes.length - 1]); +- sink.write(''); +- sink.write(method); +- sink.writeln('
    '); +- }); +- } +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/page/task_page.dart b/pkg/analysis_server/tool/instrumentation/page/task_page.dart +deleted file mode 100644 +index f5cd3124a72..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/page/task_page.dart ++++ /dev/null +@@ -1,168 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:math' as math; +- +-import '../log/log.dart'; +-import '../server.dart'; +-import 'page_writer.dart'; +- +-/** +- * A class used to write a human-readable version of the tasks executed within a +- * single analysis step. +- */ +-class TaskPage extends PageWriter { +- /** +- * The instrumentation log to be written. +- */ +- final InstrumentationLog log; +- +- /** +- * The index of the entry representing the start of an analysis session. +- */ +- int analysisStart = 0; +- +- /** +- * The index of the first task to be written. +- */ +- int pageStart = 0; +- +- /** +- * The number of tasks to be written, or `null` if all of the tasks should +- * be written. +- */ +- int pageLength = null; +- +- /** +- * The number of digits in the event stamps that are the same for every task. +- */ +- int prefixLength; +- +- /** +- * Initialize a newly created page writer to write a single page worth of +- * tasks. +- */ +- TaskPage(this.log); +- +- @override +- void writeBody(StringSink sink) { +- writeMenu(sink); +- writeTwoColumns( +- sink, 'leftColumn', _writeLeftColumn, 'rightColumn', _writeRightColumn); +- } +- +- @override +- void writeScripts(StringSink sink) { +- super.writeScripts(sink); +- sink.writeln(r''' +-function setDetails(detailsContent) { +- var element = document.getElementById("details"); +- if (element != null) { +- element.innerHTML = detailsContent; +- } +-} +-'''); +- } +- +- /** +- * Write the content of the style sheet (without the 'script' tag) for the +- * page to the given [sink]. +- */ +- void writeStyleSheet(StringSink sink) { +- super.writeStyleSheet(sink); +- writeTwoColumnStyles(sink, 'leftColumn', 'rightColumn'); +- } +- +- /** +- * Write the given log [entry] to the given [sink]. +- */ +- void _writeEntry(StringSink sink, TaskEntry entry) { +- String clickHandler = 'setDetails(\'${escape(entry.details())}\')'; +- String timeStamp = entry.timeStamp.toString(); +- if (prefixLength > 0) { +- timeStamp = timeStamp.substring(prefixLength); +- } +- +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(timeStamp); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(entry.taskName); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(entry.target); +- sink.writeln(''); +- sink.writeln(''); +- } +- +- /** +- * Write the entries in the instrumentation log to the given [sink]. +- */ +- void _writeLeftColumn(StringSink sink) { +- List entries = log.taskEntriesFor(analysisStart); +- prefixLength = computePrefixLength(entries); +- int length = entries.length; +- int pageEnd = +- pageLength == null ? length : math.min(pageStart + pageLength, length); +- // +- // Write the header of the column. +- // +- sink.writeln('
    '); +- sink.writeln('
    '); +- sink.writeln('Tasks $pageStart - ${pageEnd - 1} of ${length - 1}'); +- sink.writeln('
    '); +- +- sink.writeln('
    '); +- if (pageStart == 0) { +- sink.writeln(''); +- } else { +- sink.write(''); +- } +- // TODO(brianwilkerson) Add a text field for selecting the start index. +- if (pageEnd == length) { +- sink.writeln(''); +- } else { +- sink.write(''); +- } +- sink.writeln('
    '); +- sink.writeln('
    '); +- // +- // Write the main body of the column. +- // +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- sink.writeln(''); +- for (int i = pageStart; i < pageEnd; i++) { +- LogEntry entry = entries[i]; +- _writeEntry(sink, entry); +- } +- sink.writeln('
    TimeTaskTarget
    '); +- } +- +- /** +- * Write a placeholder to the given [sink] where the details of a selected +- * entry can be displayed. +- */ +- void _writeRightColumn(StringSink sink) { +- // +- // Write the header of the column. +- // +- sink.writeln('
    '); +- sink.writeln('

    Task Details

    '); +- sink.writeln('
    '); +- sink.writeln('
    '); +- } +-} +diff --git a/pkg/analysis_server/tool/instrumentation/server.dart b/pkg/analysis_server/tool/instrumentation/server.dart +deleted file mode 100644 +index 768c8b8fc6b..00000000000 +--- a/pkg/analysis_server/tool/instrumentation/server.dart ++++ /dev/null +@@ -1,238 +0,0 @@ +-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'dart:async'; +-import 'dart:collection'; +-import 'dart:io'; +- +-import 'log/log.dart'; +-import 'page/log_page.dart'; +-import 'page/stats_page.dart'; +-import 'page/task_page.dart'; +- +-/** +- * An exception that is thrown when a request is received that cannot be +- * handled. +- */ +-class UnknownRequest implements Exception {} +- +-/** +- * A simple web server. +- */ +-class WebServer { +- /** +- * The path to the page containing a single page from the instrumentation log. +- */ +- static final String logPath = '/log'; +- +- /** +- * The path to the page containing statistics about the instrumentation log. +- */ +- static final String statsPath = '/stats'; +- +- /** +- * The path to the page containing statistics about the instrumentation log. +- */ +- static final String taskPath = '/task'; +- +- /** +- * The content type for HTML responses. +- */ +- static final ContentType _htmlContent = +- new ContentType("text", "html", charset: "utf-8"); +- +- /** +- * The instrumentation log being served up. +- */ +- final InstrumentationLog log; +- +- /** +- * Future that is completed with the HTTP server once it is running. +- */ +- Future _server; +- +- /** +- * Initialize a newly created server. +- */ +- WebServer(this.log); +- +- Map getParameterMap(HttpRequest request) { +- Map parameterMap = new HashMap(); +- String query = request.uri.query; +- if (query != null && query.isNotEmpty) { +- List pairs = query.split('&'); +- for (String pair in pairs) { +- List parts = pair.split('='); +- String value = parts[1].trim(); +- value = value.replaceAll('+', ' '); +- parameterMap[parts[0].trim()] = value; +- } +- } +- return parameterMap; +- } +- +- /** +- * Return a table mapping the names of properties to the values of those +- * properties that is extracted from the given HTTP [request]. +- */ +- Future> getValueMap(HttpRequest request) async { +- StringBuffer buffer = new StringBuffer(); +- await request.forEach((List element) { +- for (int code in element) { +- buffer.writeCharCode(code); +- } +- }); +- Map valueMap = new HashMap(); +- String parameters = buffer.toString(); +- if (parameters.isNotEmpty) { +- List pairs = parameters.split('&'); +- for (String pair in pairs) { +- List parts = pair.split('='); +- String value = parts[1].trim(); +- value = value.replaceAll('+', ' '); +- valueMap[parts[0].trim()] = value; +- } +- } +- return valueMap; +- } +- +- /** +- * Begin serving HTTP requests over the given [port]. +- */ +- void serveHttp(int port) { +- _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port); +- _server.then(_handleServer).catchError((_) {/* Ignore errors. */}); +- } +- +- /** +- * Handle a GET [request] received by the HTTP server. +- */ +- void _handleGetRequest(HttpRequest request) { +- StringBuffer buffer = new StringBuffer(); +- try { +- String path = request.uri.path; +- if (path == logPath) { +- _writeLogPage(request, buffer); +- } else if (path == statsPath) { +- _writeStatsPage(request, buffer); +- } else if (path == taskPath) { +- _writeTaskPage(request, buffer); +- } else { +- _returnUnknownRequest(request); +- return; +- } +- } on UnknownRequest { +- _returnUnknownRequest(request); +- return; +- } catch (exception, stackTrace) { +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.OK; +- response.headers.contentType = _htmlContent; +- StringBuffer buffer = new StringBuffer(); +- buffer.write('

    Exception while composing page:

    '); +- buffer.write('

    $exception

    '); +- buffer.write('

    '); +- _writeStackTrace(buffer, stackTrace); +- buffer.write('

    '); +- response.write(buffer.toString()); +- response.close(); +- return; +- } +- +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.OK; +- response.headers.contentType = _htmlContent; +- response.write(buffer.toString()); +- response.close(); +- } +- +- /** +- * Handle a POST [request] received by the HTTP server. +- */ +- Future _handlePostRequest(HttpRequest request) async { +- _returnUnknownRequest(request); +- } +- +- /** +- * Attach a listener to a newly created HTTP server. +- */ +- void _handleServer(HttpServer httpServer) { +- httpServer.listen((HttpRequest request) { +- String method = request.method; +- if (method == 'GET') { +- _handleGetRequest(request); +- } else if (method == 'POST') { +- _handlePostRequest(request); +- } else { +- _returnUnknownRequest(request); +- } +- }); +- } +- +- /** +- * Return an error in response to an unrecognized request received by the HTTP +- * server. +- */ +- void _returnUnknownRequest(HttpRequest request) { +- HttpResponse response = request.response; +- response.statusCode = HttpStatus.NOT_FOUND; +- response.headers.contentType = +- new ContentType("text", "html", charset: "utf-8"); +- response.write( +- '

    Page not found: "${request.uri.path}".

    '); +- response.close(); +- } +- +- void _writeLogPage(HttpRequest request, StringBuffer buffer) { +- Map parameterMap = getParameterMap(request); +- String groupId = parameterMap['group']; +- String startIndex = parameterMap['start']; +- LogPage page = new LogPage(log); +- page.selectedGroup = EntryGroup.withId(groupId ?? 'nonTask'); +- if (startIndex != null) { +- page.pageStart = int.parse(startIndex); +- } else { +- page.pageStart = 0; +- } +- page.pageLength = 25; +- page.writePage(buffer); +- } +- +- /** +- * Write a representation of the given [stackTrace] to the given [sink]. +- */ +- void _writeStackTrace(StringSink sink, StackTrace stackTrace) { +- if (stackTrace != null) { +- String trace = stackTrace.toString().replaceAll('#', '
    #'); +- if (trace.startsWith('
    #')) { +- trace = trace.substring(4); +- } +- sink.write('

    '); +- sink.write(trace); +- sink.write('

    '); +- } +- } +- +- void _writeStatsPage(HttpRequest request, StringBuffer buffer) { +- new StatsPage(log).writePage(buffer); +- } +- +- void _writeTaskPage(HttpRequest request, StringBuffer buffer) { +- Map parameterMap = getParameterMap(request); +- String analysisStart = parameterMap['analysisStart']; +- String start = parameterMap['start']; +- TaskPage page = new TaskPage(log); +- if (analysisStart == null) { +- throw new UnknownRequest(); +- } +- page.analysisStart = int.parse(analysisStart); +- if (start != null) { +- page.pageStart = int.parse(start); +- } else { +- page.pageStart = 0; +- } +- page.pageLength = 25; +- page.writePage(buffer); +- } +-} +diff --git a/pkg/analysis_server/tool/spec/api.dart b/pkg/analysis_server/tool/spec/api.dart +deleted file mode 100644 +index 1fd0c67e649..00000000000 +--- a/pkg/analysis_server/tool/spec/api.dart ++++ /dev/null +@@ -1,528 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Data structures representing an API definition, and visitor base classes +- * for visiting those data structures. +- */ +-import 'dart:collection'; +- +-import 'package:html/dom.dart' as dom; +- +-/** +- * Toplevel container for the API. +- */ +-class Api extends ApiNode { +- final String version; +- final List domains; +- final Types types; +- final Refactorings refactorings; +- +- Api(this.version, this.domains, this.types, this.refactorings, +- dom.Element html, +- {bool experimental}) +- : super(html, experimental, false); +-} +- +-/** +- * Base class for objects in the API model. +- */ +-class ApiNode { +- /** +- * A flag to indicate if this API is experimental. +- */ +- final bool experimental; +- +- /** +- * A flag to indicate if this API is deprecated. +- */ +- final bool deprecated; +- +- /** +- * Html element representing this part of the API. +- */ +- final dom.Element html; +- +- ApiNode(this.html, bool experimental, bool deprecated) +- : this.experimental = experimental ?? false, +- this.deprecated = deprecated ?? false; +-} +- +-/** +- * Base class for visiting the API definition. +- */ +-abstract class ApiVisitor { +- /** +- * Dispatch the given [type] to the visitor. +- */ +- T visitTypeDecl(TypeDecl type) => type.accept(this) as T; +- T visitTypeEnum(TypeEnum typeEnum); +- T visitTypeList(TypeList typeList); +- T visitTypeMap(TypeMap typeMap); +- T visitTypeObject(TypeObject typeObject); +- T visitTypeReference(TypeReference typeReference); +- +- T visitTypeUnion(TypeUnion typeUnion); +-} +- +-/** +- * Definition of a single domain. +- */ +-class Domain extends ApiNode { +- final String name; +- final List requests; +- final List notifications; +- +- Domain(this.name, this.requests, this.notifications, dom.Element html, +- {bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +-} +- +-/** +- * API visitor that visits the entire API hierarchically by default. +- */ +-class HierarchicalApiVisitor extends ApiVisitor { +- /** +- * The API to visit. +- */ +- final Api api; +- +- HierarchicalApiVisitor(this.api); +- +- /** +- * If [type] is a [TypeReference] that is defined in the API, follow the +- * chain until a non-[TypeReference] is found, if possible. +- * +- * If it is not possible (because the chain ends with a [TypeReference] that +- * is not defined in the API), then that final [TypeReference] is returned. +- */ +- TypeDecl resolveTypeReferenceChain(TypeDecl type) { +- while (type is TypeReference && api.types.containsKey(type.typeName)) { +- type = api.types[(type as TypeReference).typeName].type; +- } +- return type; +- } +- +- void visitApi() { +- api.domains.forEach(visitDomain); +- visitTypes(api.types); +- visitRefactorings(api.refactorings); +- } +- +- void visitDomain(Domain domain) { +- domain.requests.forEach(visitRequest); +- domain.notifications.forEach(visitNotification); +- } +- +- void visitNotification(Notification notification) { +- if (notification.params != null) { +- visitTypeDecl(notification.params); +- } +- } +- +- void visitRefactoring(Refactoring refactoring) { +- if (refactoring.feedback != null) { +- visitTypeDecl(refactoring.feedback); +- } +- if (refactoring.options != null) { +- visitTypeDecl(refactoring.options); +- } +- } +- +- void visitRefactorings(Refactorings refactorings) { +- refactorings?.forEach(visitRefactoring); +- } +- +- void visitRequest(Request request) { +- if (request.params != null) { +- visitTypeDecl(request.params); +- } +- if (request.result != null) { +- visitTypeDecl(request.result); +- } +- } +- +- void visitTypeDefinition(TypeDefinition typeDefinition) { +- visitTypeDecl(typeDefinition.type); +- } +- +- @override +- void visitTypeEnum(TypeEnum typeEnum) { +- typeEnum.values.forEach(visitTypeEnumValue); +- } +- +- void visitTypeEnumValue(TypeEnumValue typeEnumValue) {} +- +- @override +- void visitTypeList(TypeList typeList) { +- visitTypeDecl(typeList.itemType); +- } +- +- @override +- void visitTypeMap(TypeMap typeMap) { +- visitTypeDecl(typeMap.keyType); +- visitTypeDecl(typeMap.valueType); +- } +- +- @override +- void visitTypeObject(TypeObject typeObject) { +- typeObject.fields.forEach(visitTypeObjectField); +- } +- +- void visitTypeObjectField(TypeObjectField typeObjectField) { +- visitTypeDecl(typeObjectField.type); +- } +- +- @override +- void visitTypeReference(TypeReference typeReference) {} +- +- void visitTypes(Types types) { +- types.forEach(visitTypeDefinition); +- } +- +- @override +- void visitTypeUnion(TypeUnion typeUnion) { +- typeUnion.choices.forEach(visitTypeDecl); +- } +-} +- +-/** +- * Description of a notification method. +- */ +-class Notification extends ApiNode { +- /** +- * Name of the domain enclosing this request. +- */ +- final String domainName; +- +- /** +- * Name of the notification, without the domain prefix. +- */ +- final String event; +- +- /** +- * Type of the object associated with the "params" key in the notification +- * object, or null if the notification has no parameters. +- */ +- final TypeObject params; +- +- Notification(this.domainName, this.event, this.params, dom.Element html, +- {bool experimental}) +- : super(html, experimental, false); +- +- /** +- * Get the name of the notification, including the domain prefix. +- */ +- String get longEvent => '$domainName.$event'; +- +- /** +- * Get the full type of the notification object, including the common "id" +- * and "error" fields. +- */ +- TypeDecl get notificationType { +- List fields = [ +- new TypeObjectField('event', new TypeReference('String', null), null, +- value: '$domainName.$event') +- ]; +- if (params != null) { +- fields.add(new TypeObjectField('params', params, null)); +- } +- return new TypeObject(fields, null); +- } +-} +- +-/** +- * Description of a single refactoring. +- */ +-class Refactoring extends ApiNode { +- /** +- * Name of the refactoring. This should match one of the values allowed for +- * RefactoringKind. +- */ +- final String kind; +- +- /** +- * Type of the refactoring feedback, or null if the refactoring has no +- * feedback. +- */ +- final TypeObject feedback; +- +- /** +- * Type of the refactoring options, or null if the refactoring has no options. +- */ +- final TypeObject options; +- +- Refactoring(this.kind, this.feedback, this.options, dom.Element html, +- {bool experimental}) +- : super(html, experimental, false); +-} +- +-/** +- * A collection of refactoring definitions. +- */ +-class Refactorings extends ApiNode with IterableMixin { +- final List refactorings; +- +- Refactorings(this.refactorings, dom.Element html, {bool experimental}) +- : super(html, experimental, false); +- +- @override +- Iterator get iterator => refactorings.iterator; +-} +- +-/** +- * Description of a request method. +- */ +-class Request extends ApiNode { +- /** +- * Name of the domain enclosing this request. +- */ +- final String domainName; +- +- /** +- * Name of the request, without the domain prefix. +- */ +- final String method; +- +- /** +- * Type of the object associated with the "params" key in the request object, +- * or null if the request has no parameters. +- */ +- final TypeObject params; +- +- /** +- * Type of the object associated with the "result" key in the response object, +- * or null if the response has no results. +- */ +- final TypeObject result; +- +- Request( +- this.domainName, this.method, this.params, this.result, dom.Element html, +- {bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +- +- /** +- * Get the name of the request, including the domain prefix. +- */ +- String get longMethod => '$domainName.$method'; +- +- /** +- * Get the full type of the request object, including the common "id" and +- * "method" fields. +- */ +- TypeDecl get requestType { +- List fields = [ +- new TypeObjectField('id', new TypeReference('String', null), null), +- new TypeObjectField('method', new TypeReference('String', null), null, +- value: '$domainName.$method') +- ]; +- if (params != null) { +- fields.add(new TypeObjectField('params', params, null)); +- } +- return new TypeObject(fields, null); +- } +- +- /** +- * Get the full type of the response object, including the common "id" and +- * "error" fields. +- */ +- TypeDecl get responseType { +- List fields = [ +- new TypeObjectField('id', new TypeReference('String', null), null), +- new TypeObjectField( +- 'error', new TypeReference('RequestError', null), null, +- optional: true) +- ]; +- if (result != null) { +- fields.add(new TypeObjectField('result', result, null)); +- } +- return new TypeObject(fields, null); +- } +-} +- +-/** +- * Base class for all possible types. +- */ +-abstract class TypeDecl extends ApiNode { +- TypeDecl(dom.Element html, bool experimental, bool deprecated) +- : super(html, experimental, deprecated); +- +- accept(ApiVisitor visitor); +-} +- +-/** +- * Description of a named type definition. +- */ +-class TypeDefinition extends ApiNode { +- final String name; +- final TypeDecl type; +- +- bool isExternal = false; +- +- TypeDefinition(this.name, this.type, dom.Element html, +- {bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +-} +- +-/** +- * Type of an enum. We represent enums in JSON as strings, so this type +- * declaration simply lists the allowed values. +- */ +-class TypeEnum extends TypeDecl { +- final List values; +- +- TypeEnum(this.values, dom.Element html, {bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +- +- @override +- accept(ApiVisitor visitor) => visitor.visitTypeEnum(this); +-} +- +-/** +- * Description of a single allowed value for an enum. +- */ +-class TypeEnumValue extends ApiNode { +- final String value; +- +- TypeEnumValue(this.value, dom.Element html, +- {bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +-} +- +-/** +- * Type of a JSON list. +- */ +-class TypeList extends TypeDecl { +- final TypeDecl itemType; +- +- TypeList(this.itemType, dom.Element html, {bool experimental}) +- : super(html, experimental, false); +- +- @override +- accept(ApiVisitor visitor) => visitor.visitTypeList(this); +-} +- +-/** +- * Type of a JSON map. +- */ +-class TypeMap extends TypeDecl { +- /** +- * Type of map keys. Note that since JSON map keys must always be strings, +- * this must either be a [TypeReference] for [String], or a [TypeReference] +- * to a type which is defined in the API as an enum or a synonym for [String]. +- */ +- final TypeReference keyType; +- +- /** +- * Type of map values. +- */ +- final TypeDecl valueType; +- +- TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental}) +- : super(html, experimental, false); +- +- @override +- accept(ApiVisitor visitor) => visitor.visitTypeMap(this); +-} +- +-/** +- * Type of a JSON object with specified fields, some of which may be optional. +- */ +-class TypeObject extends TypeDecl { +- final List fields; +- +- TypeObject(this.fields, dom.Element html, +- {bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +- +- @override +- accept(ApiVisitor visitor) => visitor.visitTypeObject(this); +- +- /** +- * Return the field with the given [name], or null if there is no such field. +- */ +- TypeObjectField getField(String name) { +- for (TypeObjectField field in fields) { +- if (field.name == name) { +- return field; +- } +- } +- return null; +- } +-} +- +-/** +- * Description of a single field in a [TypeObject]. +- */ +-class TypeObjectField extends ApiNode { +- final String name; +- final TypeDecl type; +- final bool optional; +- +- /** +- * Value that the field is required to contain, or null if it may vary. +- */ +- final Object value; +- +- TypeObjectField(this.name, this.type, dom.Element html, +- {this.optional: false, this.value, bool experimental, bool deprecated}) +- : super(html, experimental, deprecated); +-} +- +-/** +- * A reference to a type which is either defined elsewhere in the API or which +- * is built-in ([String], [bool], or [int]). +- */ +-class TypeReference extends TypeDecl { +- final String typeName; +- +- TypeReference(this.typeName, dom.Element html, {bool experimental}) +- : super(html, experimental, false) { +- if (typeName.isEmpty) { +- throw new Exception('Empty type name'); +- } +- } +- +- @override +- accept(ApiVisitor visitor) => visitor.visitTypeReference(this); +-} +- +-/** +- * A collection of type definitions. +- */ +-class Types extends ApiNode with IterableMixin { +- final Map types; +- +- List importUris = []; +- +- Types(this.types, dom.Element html, {bool experimental}) +- : super(html, experimental, false); +- +- @override +- Iterator get iterator => types.values.iterator; +- +- Iterable get keys => types.keys; +- +- TypeDefinition operator [](String typeName) => types[typeName]; +- +- bool containsKey(String typeName) => types.containsKey(typeName); +-} +- +-/** +- * Type which represents a union among multiple choices. +- */ +-class TypeUnion extends TypeDecl { +- final List choices; +- +- /** +- * The field that is used to disambiguate this union +- */ +- final String field; +- +- TypeUnion(this.choices, this.field, dom.Element html, {bool experimental}) +- : super(html, experimental, false); +- +- @override +- accept(ApiVisitor visitor) => visitor.visitTypeUnion(this); +-} +diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart +deleted file mode 100644 +index a19596d7ad0..00000000000 +--- a/pkg/analysis_server/tool/spec/check_all_test.dart ++++ /dev/null +@@ -1,23 +0,0 @@ +-// 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:io'; +- +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:path/path.dart'; +- +-import 'generate_all.dart'; +- +-/** +- * Check that all targets have been code generated. If they haven't tell the +- * user to run generate_all.dart. +- */ +-main() async { +- String script = Platform.script.toFilePath(windows: Platform.isWindows); +- List components = split(script); +- int index = components.indexOf('analysis_server'); +- String pkgPath = joinAll(components.sublist(0, index + 1)); +- await GeneratedContent.checkAll( +- pkgPath, join('tool', 'spec', 'generate_all.dart'), allTargets); +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart +deleted file mode 100644 +index 307cf0727e4..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart ++++ /dev/null +@@ -1,137 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code generation for the file "AnalysisServer.java". +- */ +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +- +-import 'api.dart'; +-import 'codegen_java.dart'; +- +-final GeneratedFile target = javaGeneratedFile( +- 'tool/spec/generated/java/AnalysisServer.java', +- (Api api) => new CodegenAnalysisServer(api)); +- +-class CodegenAnalysisServer extends CodegenJavaVisitor { +- CodegenAnalysisServer(Api api) : super(api); +- +- /** +- * Get the name of the consumer class for responses to this request. +- */ +- String consumerName(Request request) { +- return camelJoin([request.method, 'consumer'], doCapitalize: true); +- } +- +- @override +- void visitApi() { +- outputHeader(javaStyle: true); +- writeln('package com.google.dart.server.generated;'); +- writeln(); +- writeln('import com.google.dart.server.*;'); +- writeln('import org.dartlang.analysis.server.protocol.*;'); +- writeln(); +- writeln('import java.util.List;'); +- writeln('import java.util.Map;'); +- writeln(); +- writeln('''/** +- * The interface {@code AnalysisServer} defines the behavior of objects that interface to an +- * analysis server. +- * +- * @coverage dart.server +- */'''); +- makeClass('public interface AnalysisServer', () { +- // +- // addAnalysisServerListener(..) +- // +- publicMethod('addAnalysisServerListener', () { +- writeln('''/** +- * Add the given listener to the list of listeners that will receive notification when new +- * analysis results become available. +- * +- * @param listener the listener to be added +- */'''); +- writeln( +- 'public void addAnalysisServerListener(AnalysisServerListener listener);'); +- }); +- +- // +- // removeAnalysisServerListener(..) +- // +- publicMethod('removeAnalysisServerListener', () { +- writeln('''/** +- * Remove the given listener from the list of listeners that will receive notification when new +- * analysis results become available. +- * +- * @param listener the listener to be removed +- */'''); +- writeln( +- 'public void removeAnalysisServerListener(AnalysisServerListener listener);'); +- }); +- +- // +- // addStatusListener(..) +- // +- publicMethod('addStatusListener', () { +- writeln('''/** +- * Add the given listener to the list of listeners that will receive notification when the server +- * is not active +- * +- * @param listener the listener to be added +- */'''); +- writeln( +- 'public void addStatusListener(AnalysisServerStatusListener listener);'); +- }); +- +- // +- // isSocketOpen() +- // +- publicMethod('isSocketOpen', () { +- writeln('''/** +- * Return {@code true} if the socket is open. +- */'''); +- writeln('public boolean isSocketOpen();'); +- }); +- +- // +- // start(..) +- // +- publicMethod('start', () { +- writeln('''/** +- * Start the analysis server. +- */'''); +- writeln('public void start() throws Exception;'); +- }); +- super.visitApi(); +- }); +- } +- +- @override +- void visitRequest(Request request) { +- String methodName = '${request.domainName}_${request.method}'; +- publicMethod(methodName, () { +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.write('{@code ${request.longMethod }}'); +- toHtmlVisitor.translateHtml(request.html); +- toHtmlVisitor.javadocParams(request.params); +- if (request.deprecated) { +- toHtmlVisitor.p(() => toHtmlVisitor.write('@deprecated')); +- } +- })); +- write('public void $methodName('); +- List arguments = []; +- if (request.params != null) { +- for (TypeObjectField field in request.params.fields) { +- arguments.add('${javaType(field.type)} ${javaName(field.name)}'); +- } +- } +- if (request.result != null) { +- arguments.add('${consumerName(request)} consumer'); +- } +- write(arguments.join(', ')); +- writeln(');'); +- }); +- } +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_dart.dart b/pkg/analysis_server/tool/spec/codegen_dart.dart +deleted file mode 100644 +index 8b736bbd257..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_dart.dart ++++ /dev/null +@@ -1,49 +0,0 @@ +-// Copyright (c) 2014, 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 'api.dart'; +- +-/** +- * Visitor specialized for generating Dart code. +- */ +-class DartCodegenVisitor extends HierarchicalApiVisitor { +- /** +- * Type references in the spec that are named something else in Dart. +- */ +- static const Map _typeRenames = const { +- 'long': 'int', +- 'object': 'Map', +- }; +- +- DartCodegenVisitor(Api api) : super(api); +- +- /** +- * Convert the given [TypeDecl] to a Dart type. +- */ +- String dartType(TypeDecl type) { +- if (type is TypeReference) { +- String typeName = type.typeName; +- TypeDefinition referencedDefinition = api.types[typeName]; +- if (_typeRenames.containsKey(typeName)) { +- return _typeRenames[typeName]; +- } +- if (referencedDefinition == null) { +- return typeName; +- } +- TypeDecl referencedType = referencedDefinition.type; +- if (referencedType is TypeObject || referencedType is TypeEnum) { +- return typeName; +- } +- return dartType(referencedType); +- } else if (type is TypeList) { +- return 'List<${dartType(type.itemType)}>'; +- } else if (type is TypeMap) { +- return 'Map<${dartType(type.keyType)}, ${dartType(type.valueType)}>'; +- } else if (type is TypeUnion) { +- return 'dynamic'; +- } else { +- throw new Exception("Can't convert to a dart type"); +- } +- } +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart +deleted file mode 100644 +index 621da412ee2..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart ++++ /dev/null +@@ -1,1326 +0,0 @@ +-// Copyright (c) 2014, 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:convert'; +- +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:html/dom.dart' as dom; +-import 'package:path/path.dart' as path; +- +-import 'api.dart'; +-import 'codegen_dart.dart'; +-import 'from_html.dart'; +-import 'implied_types.dart'; +-import 'to_html.dart'; +- +-/** +- * Special flags that need to be inserted into the declaration of the Element +- * class. +- */ +-const Map specialElementFlags = const { +- 'abstract': '0x01', +- 'const': '0x02', +- 'final': '0x04', +- 'static': '0x08', +- 'private': '0x10', +- 'deprecated': '0x20' +-}; +- +-GeneratedFile target(bool responseRequiresRequestTime) { +- return new GeneratedFile('lib/protocol/protocol_generated.dart', +- (String pkgPath) async { +- CodegenProtocolVisitor visitor = new CodegenProtocolVisitor( +- path.basename(pkgPath), responseRequiresRequestTime, readApi(pkgPath)); +- return visitor.collectCode(visitor.visitApi); +- }); +-} +- +-/** +- * Callback type used to represent arbitrary code generation. +- */ +-typedef void CodegenCallback(); +- +-typedef String FromJsonSnippetCallback(String jsonPath, String json); +- +-typedef String ToJsonSnippetCallback(String value); +- +-/** +- * Visitor which produces Dart code representing the API. +- */ +-class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { +- /** +- * Class members for which the constructor argument should be optional, even +- * if the member is not an optional part of the protocol. For list types, +- * the constructor will default the member to the empty list. +- */ +- static const Map> _optionalConstructorArguments = const { +- 'AnalysisErrorFixes': const ['fixes'], +- 'SourceChange': const ['edits', 'linkedEditGroups'], +- 'SourceFileEdit': const ['edits'], +- 'TypeHierarchyItem': const ['interfaces', 'mixins', 'subclasses'], +- }; +- +- /** +- * The disclaimer added to the documentation comment for each of the classes +- * that are generated. +- */ +- static const String disclaimer = +- 'Clients may not extend, implement or mix-in this class.'; +- +- /** +- * The name of the package into which code is being generated. +- */ +- final String packageName; +- +- /** +- * A flag indicating whether the class [Response] requires a `requestTime` +- * parameter. +- */ +- final bool responseRequiresRequestTime; +- +- /** +- * Visitor used to produce doc comments. +- */ +- final ToHtmlVisitor toHtmlVisitor; +- +- /** +- * Types implied by the API. This includes types explicitly named in the +- * API as well as those implied by the definitions of requests, responses, +- * notifications, etc. +- */ +- final Map impliedTypes; +- +- CodegenProtocolVisitor( +- this.packageName, this.responseRequiresRequestTime, Api api) +- : toHtmlVisitor = new ToHtmlVisitor(api), +- impliedTypes = computeImpliedTypes(api), +- super(api) { +- codeGeneratorSettings.commentLineLength = 79; +- codeGeneratorSettings.languageName = 'dart'; +- } +- +- /** +- * Compute the code necessary to compare two objects for equality. +- */ +- String compareEqualsCode(TypeDecl type, String thisVar, String otherVar) { +- TypeDecl resolvedType = resolveTypeReferenceChain(type); +- if (resolvedType is TypeReference || +- resolvedType is TypeEnum || +- resolvedType is TypeObject || +- resolvedType is TypeUnion) { +- return '$thisVar == $otherVar'; +- } else if (resolvedType is TypeList) { +- String itemTypeName = dartType(resolvedType.itemType); +- String subComparison = compareEqualsCode(resolvedType.itemType, 'a', 'b'); +- String closure = '($itemTypeName a, $itemTypeName b) => $subComparison'; +- return 'listEqual($thisVar, $otherVar, $closure)'; +- } else if (resolvedType is TypeMap) { +- String valueTypeName = dartType(resolvedType.valueType); +- String subComparison = +- compareEqualsCode(resolvedType.valueType, 'a', 'b'); +- String closure = '($valueTypeName a, $valueTypeName b) => $subComparison'; +- return 'mapEqual($thisVar, $otherVar, $closure)'; +- } +- throw new Exception( +- "Don't know how to compare for equality: $resolvedType"); +- } +- +- /** +- * Translate each of the given [types] implied by the API to a class. +- */ +- void emitClasses(List types) { +- for (ImpliedType impliedType in types) { +- TypeDecl type = impliedType.type; +- String dartTypeName = capitalize(impliedType.camelName); +- if (type == null) { +- writeln(); +- emitEmptyObjectClass(dartTypeName, impliedType); +- } else if (type is TypeObject) { +- writeln(); +- emitObjectClass(dartTypeName, type, impliedType); +- } else if (type is TypeEnum) { +- writeln(); +- emitEnumClass(dartTypeName, type, impliedType); +- } +- } +- } +- +- /** +- * Emit a convenience constructor for decoding a piece of protocol, if +- * appropriate. Return true if a constructor was emitted. +- */ +- bool emitConvenienceConstructor(String className, ImpliedType impliedType) { +- // The type of object from which this piece of protocol should be decoded. +- String inputType; +- // The name of the input object. +- String inputName; +- // The field within the input object to decode. +- String fieldName; +- // Constructor call to create the JsonDecoder object. +- String makeDecoder; +- // Name of the constructor to create. +- String constructorName; +- // Extra arguments for the constructor. +- List extraArgs = []; +- switch (impliedType.kind) { +- case 'requestParams': +- inputType = 'Request'; +- inputName = 'request'; +- fieldName = 'params'; +- makeDecoder = 'new RequestDecoder(request)'; +- constructorName = 'fromRequest'; +- break; +- case 'requestResult': +- inputType = 'Response'; +- inputName = 'response'; +- fieldName = 'result'; +- makeDecoder = +- 'new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id))'; +- constructorName = 'fromResponse'; +- break; +- case 'notificationParams': +- inputType = 'Notification'; +- inputName = 'notification'; +- fieldName = 'params'; +- makeDecoder = 'new ResponseDecoder(null)'; +- constructorName = 'fromNotification'; +- break; +- case 'refactoringOptions': +- inputType = 'EditGetRefactoringParams'; +- inputName = 'refactoringParams'; +- fieldName = 'options'; +- makeDecoder = 'new RequestDecoder(request)'; +- constructorName = 'fromRefactoringParams'; +- extraArgs.add('Request request'); +- break; +- default: +- return false; +- } +- List args = ['$inputType $inputName']; +- args.addAll(extraArgs); +- writeln('factory $className.$constructorName(${args.join(', ')}) {'); +- indent(() { +- String fieldNameString = +- literalString(fieldName.replaceFirst(new RegExp('^_'), '')); +- if (className == 'EditGetRefactoringParams') { +- writeln('var params = new $className.fromJson('); +- writeln(' $makeDecoder, $fieldNameString, $inputName.$fieldName);'); +- writeln('REQUEST_ID_REFACTORING_KINDS[request.id] = params.kind;'); +- writeln('return params;'); +- } else { +- writeln('return new $className.fromJson('); +- writeln(' $makeDecoder, $fieldNameString, $inputName.$fieldName);'); +- } +- }); +- writeln('}'); +- return true; +- } +- +- /** +- * Emit a class representing an data structure that doesn't exist in the +- * protocol because it is empty (e.g. the "params" object for a request that +- * doesn't have any parameters). +- */ +- void emitEmptyObjectClass(String className, ImpliedType impliedType) { +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(impliedType.humanReadableName); +- }); +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(disclaimer); +- }); +- })); +- write('class $className'); +- if (impliedType.kind == 'refactoringFeedback') { +- writeln(' extends RefactoringFeedback implements HasToJson {'); +- } else if (impliedType.kind == 'refactoringOptions') { +- writeln(' extends RefactoringOptions implements HasToJson {'); +- } else if (impliedType.kind == 'requestParams') { +- writeln(' implements RequestParams {'); +- } else if (impliedType.kind == 'requestResult') { +- writeln(' implements ResponseResult {'); +- } else { +- writeln(' {'); +- } +- indent(() { +- if (impliedType.kind == 'requestResult' || +- impliedType.kind == 'requestParams') { +- emitEmptyToJsonMember(); +- writeln(); +- } +- if (emitToRequestMember(impliedType)) { +- writeln(); +- } +- if (emitToResponseMember(impliedType)) { +- writeln(); +- } +- if (emitToNotificationMember(impliedType)) { +- writeln(); +- } +- emitObjectEqualsMember(null, className); +- writeln(); +- emitObjectHashCode(null, className); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the toJson() code for an empty class. +- */ +- void emitEmptyToJsonMember() { +- writeln('@override'); +- writeln('Map toJson() => {};'); +- } +- +- /** +- * Emit a class to encapsulate an enum. +- */ +- void emitEnumClass(String className, TypeEnum type, ImpliedType impliedType) { +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(impliedType.humanReadableName); +- }); +- if (impliedType.type != null) { +- toHtmlVisitor.showType(null, impliedType.type); +- } +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(disclaimer); +- }); +- })); +- writeln('class $className implements Enum {'); +- indent(() { +- if (emitSpecialStaticMembers(className)) { +- writeln(); +- } +- for (TypeEnumValue value in type.values) { +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(value.html); +- })); +- String valueString = literalString(value.value); +- writeln( +- 'static const $className ${value.value} = const $className._($valueString);'); +- writeln(); +- } +- +- writeln('/**'); +- writeln(' * A list containing all of the enum values that are defined.'); +- writeln(' */'); +- write('static const List<'); +- write(className); +- write('> VALUES = const <'); +- write(className); +- write('>['); +- bool first = true; +- for (TypeEnumValue value in type.values) { +- if (first) { +- first = false; +- } else { +- write(', '); +- } +- write(value.value); +- } +- writeln('];'); +- writeln(); +- +- writeln('@override'); +- writeln('final String name;'); +- writeln(); +- writeln('const $className._(this.name);'); +- writeln(); +- emitEnumClassConstructor(className, type); +- writeln(); +- emitEnumFromJsonConstructor(className, type, impliedType); +- writeln(); +- if (emitSpecialConstructors(className)) { +- writeln(); +- } +- if (emitSpecialGetters(className)) { +- writeln(); +- } +- if (emitSpecialMethods(className)) { +- writeln(); +- } +- writeln('@override'); +- writeln('String toString() => "$className.\$name";'); +- writeln(); +- writeln('String toJson() => name;'); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the constructor for an enum class. +- */ +- void emitEnumClassConstructor(String className, TypeEnum type) { +- writeln('factory $className(String name) {'); +- indent(() { +- writeln('switch (name) {'); +- indent(() { +- for (TypeEnumValue value in type.values) { +- String valueString = literalString(value.value); +- writeln('case $valueString:'); +- indent(() { +- writeln('return ${value.value};'); +- }); +- } +- }); +- writeln('}'); +- writeln(r"throw new Exception('Illegal enum value: $name');"); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the method for decoding an enum from JSON. +- */ +- void emitEnumFromJsonConstructor( +- String className, TypeEnum type, ImpliedType impliedType) { +- writeln( +- 'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {'); +- indent(() { +- writeln('if (json is String) {'); +- indent(() { +- writeln('try {'); +- indent(() { +- writeln('return new $className(json);'); +- }); +- writeln('} catch(_) {'); +- indent(() { +- writeln('// Fall through'); +- }); +- writeln('}'); +- }); +- writeln('}'); +- String humanReadableNameString = +- literalString(impliedType.humanReadableName); +- writeln( +- 'throw jsonDecoder.mismatch(jsonPath, $humanReadableNameString, json);'); +- }); +- writeln('}'); +- } +- +- void emitImports() { +- writeln("import 'dart:convert' hide JsonDecoder;"); +- writeln(); +- writeln("import 'package:analyzer/src/generated/utilities_general.dart';"); +- writeln("import 'package:$packageName/protocol/protocol.dart';"); +- writeln( +- "import 'package:$packageName/src/protocol/protocol_internal.dart';"); +- for (String uri in api.types.importUris) { +- write("import '"); +- write(uri); +- writeln("';"); +- } +- } +- +- /** +- * Emit the class to encapsulate an object type. +- */ +- void emitObjectClass( +- String className, TypeObject type, ImpliedType impliedType) { +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(impliedType.humanReadableName); +- }); +- if (impliedType.type != null) { +- toHtmlVisitor.showType(null, impliedType.type); +- } +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(disclaimer); +- }); +- })); +- write('class $className'); +- if (impliedType.kind == 'refactoringFeedback') { +- writeln(' extends RefactoringFeedback {'); +- } else if (impliedType.kind == 'refactoringOptions') { +- writeln(' extends RefactoringOptions {'); +- } else if (impliedType.kind == 'requestParams') { +- writeln(' implements RequestParams {'); +- } else if (impliedType.kind == 'requestResult') { +- writeln(' implements ResponseResult {'); +- } else { +- writeln(' implements HasToJson {'); +- } +- indent(() { +- if (emitSpecialStaticMembers(className)) { +- writeln(); +- } +- for (TypeObjectField field in type.fields) { +- if (field.value != null) { +- continue; +- } +- writeln('${dartType(field.type)} _${field.name};'); +- writeln(); +- } +- for (TypeObjectField field in type.fields) { +- if (field.value != null) { +- continue; +- } +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(field.html); +- })); +- writeln('${dartType(field.type)} get ${field.name} => _${field.name};'); +- writeln(); +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(field.html); +- })); +- writeln('void set ${field.name}(${dartType(field.type)} value) {'); +- indent(() { +- if (!field.optional) { +- writeln('assert(value != null);'); +- } +- writeln('this._${field.name} = value;'); +- }); +- writeln('}'); +- writeln(); +- } +- emitObjectConstructor(type, className); +- writeln(); +- emitObjectFromJsonConstructor(className, type, impliedType); +- writeln(); +- if (emitConvenienceConstructor(className, impliedType)) { +- writeln(); +- } +- if (emitSpecialConstructors(className)) { +- writeln(); +- } +- if (emitSpecialGetters(className)) { +- writeln(); +- } +- emitToJsonMember(type); +- writeln(); +- if (emitToRequestMember(impliedType)) { +- writeln(); +- } +- if (emitToResponseMember(impliedType)) { +- writeln(); +- } +- if (emitToNotificationMember(impliedType)) { +- writeln(); +- } +- if (emitSpecialMethods(className)) { +- writeln(); +- } +- writeln('@override'); +- writeln('String toString() => JSON.encode(toJson());'); +- writeln(); +- emitObjectEqualsMember(type, className); +- writeln(); +- emitObjectHashCode(type, className); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the constructor for an object class. +- */ +- void emitObjectConstructor(TypeObject type, String className) { +- List args = []; +- List optionalArgs = []; +- List extraInitCode = []; +- for (TypeObjectField field in type.fields) { +- if (field.value != null) { +- continue; +- } +- String arg = '${dartType(field.type)} ${field.name}'; +- String setValueFromArg = 'this.${field.name} = ${field.name};'; +- if (isOptionalConstructorArg(className, field)) { +- optionalArgs.add(arg); +- if (!field.optional) { +- // Optional constructor arg, but non-optional field. If no arg is +- // given, the constructor should populate with the empty list. +- TypeDecl fieldType = field.type; +- if (fieldType is TypeList) { +- extraInitCode.add(() { +- writeln('if (${field.name} == null) {'); +- indent(() { +- writeln( +- 'this.${field.name} = <${dartType(fieldType.itemType)}>[];'); +- }); +- writeln('} else {'); +- indent(() { +- writeln(setValueFromArg); +- }); +- writeln('}'); +- }); +- } else { +- throw new Exception( +- "Don't know how to create default field value."); +- } +- } else { +- extraInitCode.add(() { +- writeln(setValueFromArg); +- }); +- } +- } else { +- args.add(arg); +- extraInitCode.add(() { +- writeln(setValueFromArg); +- }); +- } +- } +- if (optionalArgs.isNotEmpty) { +- args.add('{${optionalArgs.join(', ')}}'); +- } +- write('$className(${args.join(', ')})'); +- if (extraInitCode.isEmpty) { +- writeln(';'); +- } else { +- writeln(' {'); +- indent(() { +- for (CodegenCallback callback in extraInitCode) { +- callback(); +- } +- }); +- writeln('}'); +- } +- } +- +- /** +- * Emit the operator== code for an object class. +- */ +- void emitObjectEqualsMember(TypeObject type, String className) { +- writeln('@override'); +- writeln('bool operator ==(other) {'); +- indent(() { +- writeln('if (other is $className) {'); +- indent(() { +- var comparisons = []; +- if (type != null) { +- for (TypeObjectField field in type.fields) { +- if (field.value != null) { +- continue; +- } +- comparisons.add(compareEqualsCode( +- field.type, field.name, 'other.${field.name}')); +- } +- } +- if (comparisons.isEmpty) { +- writeln('return true;'); +- } else { +- String concatenated = comparisons.join(' &&\n '); +- writeln('return $concatenated;'); +- } +- }); +- writeln('}'); +- writeln('return false;'); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the method for decoding an object from JSON. +- */ +- void emitObjectFromJsonConstructor( +- String className, TypeObject type, ImpliedType impliedType) { +- String humanReadableNameString = +- literalString(impliedType.humanReadableName); +- if (className == 'RefactoringFeedback') { +- writeln('factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, ' +- 'String jsonPath, Object json, Map responseJson) {'); +- indent(() { +- writeln('return refactoringFeedbackFromJson(jsonDecoder, jsonPath, ' +- 'json, responseJson);'); +- }); +- writeln('}'); +- return; +- } +- if (className == 'RefactoringOptions') { +- writeln('factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, ' +- 'String jsonPath, Object json, RefactoringKind kind) {'); +- indent(() { +- writeln('return refactoringOptionsFromJson(jsonDecoder, jsonPath, ' +- 'json, kind);'); +- }); +- writeln('}'); +- return; +- } +- writeln( +- 'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {'); +- indent(() { +- writeln('if (json == null) {'); +- indent(() { +- writeln('json = {};'); +- }); +- writeln('}'); +- writeln('if (json is Map) {'); +- indent(() { +- List args = []; +- List optionalArgs = []; +- for (TypeObjectField field in type.fields) { +- String fieldNameString = literalString(field.name); +- String fieldAccessor = 'json[$fieldNameString]'; +- String jsonPath = 'jsonPath + ${literalString('.${field.name}')}'; +- if (field.value != null) { +- String valueString = literalString(field.value); +- writeln('if ($fieldAccessor != $valueString) {'); +- indent(() { +- writeln( +- 'throw jsonDecoder.mismatch(jsonPath, "equal " + $valueString, json);'); +- }); +- writeln('}'); +- continue; +- } +- if (isOptionalConstructorArg(className, field)) { +- optionalArgs.add('${field.name}: ${field.name}'); +- } else { +- args.add(field.name); +- } +- TypeDecl fieldType = field.type; +- String fieldDartType = dartType(fieldType); +- writeln('$fieldDartType ${field.name};'); +- writeln('if (json.containsKey($fieldNameString)) {'); +- indent(() { +- String fromJson = +- fromJsonCode(fieldType).asSnippet(jsonPath, fieldAccessor); +- writeln('${field.name} = $fromJson;'); +- }); +- write('}'); +- if (!field.optional) { +- writeln(' else {'); +- indent(() { +- writeln( +- "throw jsonDecoder.mismatch(jsonPath, $fieldNameString);"); +- }); +- writeln('}'); +- } else { +- writeln(); +- } +- } +- args.addAll(optionalArgs); +- writeln('return new $className(${args.join(', ')});'); +- }); +- writeln('} else {'); +- indent(() { +- writeln( +- 'throw jsonDecoder.mismatch(jsonPath, $humanReadableNameString, json);'); +- }); +- writeln('}'); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the hashCode getter for an object class. +- */ +- void emitObjectHashCode(TypeObject type, String className) { +- writeln('@override'); +- writeln('int get hashCode {'); +- indent(() { +- if (type == null) { +- writeln('return ${className.hashCode};'); +- } else { +- writeln('int hash = 0;'); +- for (TypeObjectField field in type.fields) { +- String valueToCombine; +- if (field.value != null) { +- valueToCombine = field.value.hashCode.toString(); +- } else { +- valueToCombine = '${field.name}.hashCode'; +- } +- writeln('hash = JenkinsSmiHash.combine(hash, $valueToCombine);'); +- } +- writeln('return JenkinsSmiHash.finish(hash);'); +- } +- }); +- writeln('}'); +- } +- +- /** +- * If the class named [className] requires special constructors, emit them +- * and return true. +- */ +- bool emitSpecialConstructors(String className) { +- switch (className) { +- case 'LinkedEditGroup': +- docComment([new dom.Text('Construct an empty LinkedEditGroup.')]); +- writeln( +- 'LinkedEditGroup.empty() : this([], 0, []);'); +- return true; +- case 'RefactoringProblemSeverity': +- docComment([ +- new dom.Text( +- 'Returns the [RefactoringProblemSeverity] with the maximal severity.') +- ]); +- writeln( +- 'static RefactoringProblemSeverity max(RefactoringProblemSeverity a, RefactoringProblemSeverity b) =>'); +- writeln(' maxRefactoringProblemSeverity(a, b);'); +- return true; +- default: +- return false; +- } +- } +- +- /** +- * If the class named [className] requires special getters, emit them and +- * return true. +- */ +- bool emitSpecialGetters(String className) { +- switch (className) { +- case 'Element': +- for (String name in specialElementFlags.keys) { +- String flag = 'FLAG_${name.toUpperCase()}'; +- writeln( +- 'bool get ${camelJoin(['is', name])} => (flags & $flag) != 0;'); +- } +- return true; +- case 'SourceEdit': +- docComment([new dom.Text('The end of the region to be modified.')]); +- writeln('int get end => offset + length;'); +- return true; +- default: +- return false; +- } +- } +- +- /** +- * If the class named [className] requires special methods, emit them and +- * return true. +- */ +- bool emitSpecialMethods(String className) { +- switch (className) { +- case 'LinkedEditGroup': +- docComment([new dom.Text('Add a new position and change the length.')]); +- writeln('void addPosition(Position position, int length) {'); +- indent(() { +- writeln('positions.add(position);'); +- writeln('this.length = length;'); +- }); +- writeln('}'); +- writeln(); +- docComment([new dom.Text('Add a new suggestion.')]); +- writeln('void addSuggestion(LinkedEditSuggestion suggestion) {'); +- indent(() { +- writeln('suggestions.add(suggestion);'); +- }); +- writeln('}'); +- return true; +- case 'SourceChange': +- docComment([ +- new dom.Text('Adds [edit] to the [FileEdit] for the given [file].') +- ]); +- writeln('void addEdit(String file, int fileStamp, SourceEdit edit) =>'); +- writeln(' addEditToSourceChange(this, file, fileStamp, edit);'); +- writeln(); +- docComment([new dom.Text('Adds the given [FileEdit].')]); +- writeln('void addFileEdit(SourceFileEdit edit) {'); +- indent(() { +- writeln('edits.add(edit);'); +- }); +- writeln('}'); +- writeln(); +- docComment([new dom.Text('Adds the given [LinkedEditGroup].')]); +- writeln('void addLinkedEditGroup(LinkedEditGroup linkedEditGroup) {'); +- indent(() { +- writeln('linkedEditGroups.add(linkedEditGroup);'); +- }); +- writeln('}'); +- writeln(); +- docComment([ +- new dom.Text( +- 'Returns the [FileEdit] for the given [file], maybe `null`.') +- ]); +- writeln('SourceFileEdit getFileEdit(String file) =>'); +- writeln(' getChangeFileEdit(this, file);'); +- return true; +- case 'SourceEdit': +- docComment([ +- new dom.Text( +- 'Get the result of applying the edit to the given [code].') +- ]); +- writeln('String apply(String code) => applyEdit(code, this);'); +- return true; +- case 'SourceFileEdit': +- docComment([new dom.Text('Adds the given [Edit] to the list.')]); +- writeln('void add(SourceEdit edit) => addEditForSource(this, edit);'); +- writeln(); +- docComment([new dom.Text('Adds the given [Edit]s.')]); +- writeln('void addAll(Iterable edits) =>'); +- writeln(' addAllEditsForSource(this, edits);'); +- return true; +- default: +- return false; +- } +- } +- +- /** +- * If the class named [className] requires special static members, emit them +- * and return true. +- */ +- bool emitSpecialStaticMembers(String className) { +- switch (className) { +- case 'Element': +- List makeFlagsArgs = []; +- List makeFlagsStatements = []; +- specialElementFlags.forEach((String name, String value) { +- String flag = 'FLAG_${name.toUpperCase()}'; +- String camelName = camelJoin(['is', name]); +- writeln('static const int $flag = $value;'); +- makeFlagsArgs.add('$camelName: false'); +- makeFlagsStatements.add('if ($camelName) flags |= $flag;'); +- }); +- writeln(); +- writeln('static int makeFlags({${makeFlagsArgs.join(', ')}}) {'); +- indent(() { +- writeln('int flags = 0;'); +- for (String statement in makeFlagsStatements) { +- writeln(statement); +- } +- writeln('return flags;'); +- }); +- writeln('}'); +- return true; +- case 'SourceEdit': +- docComment([ +- new dom.Text('Get the result of applying a set of ' + +- '[edits] to the given [code]. Edits are applied in the order ' + +- 'they appear in [edits].') +- ]); +- writeln( +- 'static String applySequence(String code, Iterable edits) =>'); +- writeln(' applySequenceOfEdits(code, edits);'); +- return true; +- default: +- return false; +- } +- } +- +- /** +- * Emit the toJson() code for an object class. +- */ +- void emitToJsonMember(TypeObject type) { +- writeln('@override'); +- writeln('Map toJson() {'); +- indent(() { +- writeln('Map result = {};'); +- for (TypeObjectField field in type.fields) { +- String fieldNameString = literalString(field.name); +- if (field.value != null) { +- writeln('result[$fieldNameString] = ${literalString(field.value)};'); +- continue; +- } +- String fieldToJson = toJsonCode(field.type).asSnippet(field.name); +- String populateField = 'result[$fieldNameString] = $fieldToJson;'; +- if (field.optional) { +- writeln('if (${field.name} != null) {'); +- indent(() { +- writeln(populateField); +- }); +- writeln('}'); +- } else { +- writeln(populateField); +- } +- } +- writeln('return result;'); +- }); +- writeln('}'); +- } +- +- /** +- * Emit the toNotification() code for a class, if appropriate. Returns true +- * if code was emitted. +- */ +- bool emitToNotificationMember(ImpliedType impliedType) { +- if (impliedType.kind == 'notificationParams') { +- writeln('Notification toNotification() {'); +- indent(() { +- String eventString = +- literalString((impliedType.apiNode as Notification).longEvent); +- String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; +- writeln('return new Notification($eventString, $jsonPart);'); +- }); +- writeln('}'); +- return true; +- } +- return false; +- } +- +- /** +- * Emit the toRequest() code for a class, if appropriate. Returns true if +- * code was emitted. +- */ +- bool emitToRequestMember(ImpliedType impliedType) { +- if (impliedType.kind == 'requestParams') { +- writeln('@override'); +- writeln('Request toRequest(String id) {'); +- indent(() { +- String methodString = +- literalString((impliedType.apiNode as Request).longMethod); +- String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; +- writeln('return new Request(id, $methodString, $jsonPart);'); +- }); +- writeln('}'); +- return true; +- } +- return false; +- } +- +- /** +- * Emit the toResponse() code for a class, if appropriate. Returns true if +- * code was emitted. +- */ +- bool emitToResponseMember(ImpliedType impliedType) { +- if (impliedType.kind == 'requestResult') { +- writeln('@override'); +- if (responseRequiresRequestTime) { +- writeln('Response toResponse(String id, int requestTime) {'); +- } else { +- writeln('Response toResponse(String id) {'); +- } +- indent(() { +- String jsonPart = impliedType.type != null ? 'toJson()' : 'null'; +- if (responseRequiresRequestTime) { +- writeln('return new Response(id, requestTime, result: $jsonPart);'); +- } else { +- writeln('return new Response(id, result: $jsonPart);'); +- } +- }); +- writeln('}'); +- return true; +- } +- return false; +- } +- +- /** +- * Compute the code necessary to translate [type] from JSON. +- */ +- FromJsonCode fromJsonCode(TypeDecl type) { +- if (type is TypeReference) { +- TypeDefinition referencedDefinition = api.types[type.typeName]; +- if (referencedDefinition != null) { +- TypeDecl referencedType = referencedDefinition.type; +- if (referencedType is TypeObject || referencedType is TypeEnum) { +- return new FromJsonSnippet((String jsonPath, String json) { +- String typeName = dartType(type); +- if (typeName == 'RefactoringFeedback') { +- return 'new $typeName.fromJson(jsonDecoder, $jsonPath, $json, json)'; +- } else if (typeName == 'RefactoringOptions') { +- return 'new $typeName.fromJson(jsonDecoder, $jsonPath, $json, kind)'; +- } else { +- return 'new $typeName.fromJson(jsonDecoder, $jsonPath, $json)'; +- } +- }); +- } else { +- return fromJsonCode(referencedType); +- } +- } else { +- switch (type.typeName) { +- case 'String': +- return new FromJsonFunction('jsonDecoder.decodeString'); +- case 'bool': +- return new FromJsonFunction('jsonDecoder.decodeBool'); +- case 'int': +- case 'long': +- return new FromJsonFunction('jsonDecoder.decodeInt'); +- case 'object': +- return new FromJsonIdentity(); +- default: +- throw new Exception('Unexpected type name ${type.typeName}'); +- } +- } +- } else if (type is TypeMap) { +- FromJsonCode keyCode; +- if (dartType(type.keyType) != 'String') { +- keyCode = fromJsonCode(type.keyType); +- } else { +- keyCode = new FromJsonIdentity(); +- } +- FromJsonCode valueCode = fromJsonCode(type.valueType); +- if (keyCode.isIdentity && valueCode.isIdentity) { +- return new FromJsonFunction('jsonDecoder.decodeMap'); +- } else { +- return new FromJsonSnippet((String jsonPath, String json) { +- StringBuffer result = new StringBuffer(); +- result.write('jsonDecoder.decodeMap($jsonPath, $json'); +- if (!keyCode.isIdentity) { +- result.write(', keyDecoder: ${keyCode.asClosure}'); +- } +- if (!valueCode.isIdentity) { +- result.write(', valueDecoder: ${valueCode.asClosure}'); +- } +- result.write(')'); +- return result.toString(); +- }); +- } +- } else if (type is TypeList) { +- FromJsonCode itemCode = fromJsonCode(type.itemType); +- if (itemCode.isIdentity) { +- return new FromJsonFunction('jsonDecoder.decodeList'); +- } else { +- return new FromJsonSnippet((String jsonPath, String json) => +- 'jsonDecoder.decodeList($jsonPath, $json, ${itemCode.asClosure})'); +- } +- } else if (type is TypeUnion) { +- List decoders = []; +- for (TypeDecl choice in type.choices) { +- TypeDecl resolvedChoice = resolveTypeReferenceChain(choice); +- if (resolvedChoice is TypeObject) { +- TypeObjectField field = resolvedChoice.getField(type.field); +- if (field == null) { +- throw new Exception( +- 'Each choice in the union needs a field named ${type.field}'); +- } +- if (field.value == null) { +- throw new Exception( +- 'Each choice in the union needs a constant value for the field ${type.field}'); +- } +- String closure = fromJsonCode(choice).asClosure; +- decoders.add('${literalString(field.value)}: $closure'); +- } else { +- throw new Exception('Union types must be unions of objects.'); +- } +- } +- return new FromJsonSnippet((String jsonPath, String json) => +- 'jsonDecoder.decodeUnion($jsonPath, $json, ${literalString(type.field)}, {${decoders.join(', ')}})'); +- } else { +- throw new Exception("Can't convert $type from JSON"); +- } +- } +- +- /** +- * Return a list of the classes to be emitted. +- */ +- List getClassesToEmit() { +- List types = impliedTypes.values.where((ImpliedType type) { +- ApiNode node = type.apiNode; +- return !(node is TypeDefinition && node.isExternal); +- }).toList(); +- types.sort((first, second) => +- capitalize(first.camelName).compareTo(capitalize(second.camelName))); +- return types; +- } +- +- /** +- * True if the constructor argument for the given field should be optional. +- */ +- bool isOptionalConstructorArg(String className, TypeObjectField field) { +- if (field.optional) { +- return true; +- } +- List forceOptional = _optionalConstructorArguments[className]; +- if (forceOptional != null && forceOptional.contains(field.name)) { +- return true; +- } +- return false; +- } +- +- /** +- * Create a string literal that evaluates to [s]. +- */ +- String literalString(String s) { +- return JSON.encode(s); +- } +- +- /** +- * Compute the code necessary to convert [type] to JSON. +- */ +- ToJsonCode toJsonCode(TypeDecl type) { +- TypeDecl resolvedType = resolveTypeReferenceChain(type); +- if (resolvedType is TypeReference) { +- return new ToJsonIdentity(dartType(type)); +- } else if (resolvedType is TypeList) { +- ToJsonCode itemCode = toJsonCode(resolvedType.itemType); +- if (itemCode.isIdentity) { +- return new ToJsonIdentity(dartType(type)); +- } else { +- return new ToJsonSnippet(dartType(type), +- (String value) => '$value.map(${itemCode.asClosure}).toList()'); +- } +- } else if (resolvedType is TypeMap) { +- ToJsonCode keyCode; +- if (dartType(resolvedType.keyType) != 'String') { +- keyCode = toJsonCode(resolvedType.keyType); +- } else { +- keyCode = new ToJsonIdentity(dartType(resolvedType.keyType)); +- } +- ToJsonCode valueCode = toJsonCode(resolvedType.valueType); +- if (keyCode.isIdentity && valueCode.isIdentity) { +- return new ToJsonIdentity(dartType(resolvedType)); +- } else { +- return new ToJsonSnippet(dartType(type), (String value) { +- StringBuffer result = new StringBuffer(); +- result.write('mapMap($value'); +- if (!keyCode.isIdentity) { +- result.write(', keyCallback: ${keyCode.asClosure}'); +- } +- if (!valueCode.isIdentity) { +- result.write(', valueCallback: ${valueCode.asClosure}'); +- } +- result.write(')'); +- return result.toString(); +- }); +- } +- } else if (resolvedType is TypeUnion) { +- for (TypeDecl choice in resolvedType.choices) { +- if (resolveTypeReferenceChain(choice) is! TypeObject) { +- throw new Exception('Union types must be unions of objects'); +- } +- } +- return new ToJsonSnippet( +- dartType(type), (String value) => '$value.toJson()'); +- } else if (resolvedType is TypeObject || resolvedType is TypeEnum) { +- return new ToJsonSnippet( +- dartType(type), (String value) => '$value.toJson()'); +- } else { +- throw new Exception("Can't convert $resolvedType from JSON"); +- } +- } +- +- @override +- visitApi() { +- outputHeader(year: '2017'); +- writeln(); +- emitImports(); +- emitClasses(getClassesToEmit()); +- } +-} +- +-/** +- * Container for code that can be used to translate a data type from JSON. +- */ +-abstract class FromJsonCode { +- /** +- * Get the translation code in the form of a closure. +- */ +- String get asClosure; +- +- /** +- * True if the data type is already in JSON form, so the translation is the +- * identity function. +- */ +- bool get isIdentity; +- +- /** +- * Get the translation code in the form of a code snippet, where [jsonPath] +- * is the variable holding the JSON path, and [json] is the variable holding +- * the raw JSON. +- */ +- String asSnippet(String jsonPath, String json); +-} +- +-/** +- * Representation of FromJsonCode for a function defined elsewhere. +- */ +-class FromJsonFunction extends FromJsonCode { +- @override +- final String asClosure; +- +- FromJsonFunction(this.asClosure); +- +- @override +- bool get isIdentity => false; +- +- @override +- String asSnippet(String jsonPath, String json) => +- '$asClosure($jsonPath, $json)'; +-} +- +-/** +- * Representation of FromJsonCode for the identity transformation. +- */ +-class FromJsonIdentity extends FromJsonSnippet { +- FromJsonIdentity() : super((String jsonPath, String json) => json); +- +- @override +- bool get isIdentity => true; +-} +- +-/** +- * Representation of FromJsonCode for a snippet of inline code. +- */ +-class FromJsonSnippet extends FromJsonCode { +- /** +- * Callback that can be used to generate the code snippet, once the names +- * of the [jsonPath] and [json] variables are known. +- */ +- final FromJsonSnippetCallback callback; +- +- FromJsonSnippet(this.callback); +- +- @override +- String get asClosure => +- '(String jsonPath, Object json) => ${callback('jsonPath', 'json')}'; +- +- @override +- bool get isIdentity => false; +- +- @override +- String asSnippet(String jsonPath, String json) => callback(jsonPath, json); +-} +- +-/** +- * Container for code that can be used to translate a data type to JSON. +- */ +-abstract class ToJsonCode { +- /** +- * Get the translation code in the form of a closure. +- */ +- String get asClosure; +- +- /** +- * True if the data type is already in JSON form, so the translation is the +- * identity function. +- */ +- bool get isIdentity; +- +- /** +- * Get the translation code in the form of a code snippet, where [value] +- * is the variable holding the object to be translated. +- */ +- String asSnippet(String value); +-} +- +-/** +- * Representation of ToJsonCode for a function defined elsewhere. +- */ +-class ToJsonFunction extends ToJsonCode { +- @override +- final String asClosure; +- +- ToJsonFunction(this.asClosure); +- +- @override +- bool get isIdentity => false; +- +- @override +- String asSnippet(String value) => '$asClosure($value)'; +-} +- +-/** +- * Representation of FromJsonCode for the identity transformation. +- */ +-class ToJsonIdentity extends ToJsonSnippet { +- ToJsonIdentity(String type) : super(type, (String value) => value); +- +- @override +- bool get isIdentity => true; +-} +- +-/** +- * Representation of ToJsonCode for a snippet of inline code. +- */ +-class ToJsonSnippet extends ToJsonCode { +- /** +- * Callback that can be used to generate the code snippet, once the name +- * of the [value] variable is known. +- */ +- final ToJsonSnippetCallback callback; +- +- /** +- * Dart type of the [value] variable. +- */ +- final String type; +- +- ToJsonSnippet(this.type, this.callback); +- +- @override +- String get asClosure => '($type value) => ${callback('value')}'; +- +- @override +- bool get isIdentity => false; +- +- @override +- String asSnippet(String value) => callback(value); +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart +deleted file mode 100644 +index 06b26e688bb..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart ++++ /dev/null +@@ -1,275 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code generation for the file "integration_test_methods.dart". +- */ +-import 'dart:convert'; +- +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:path/path.dart' as path; +- +-import 'api.dart'; +-import 'codegen_dart.dart'; +-import 'from_html.dart'; +-import 'to_html.dart'; +- +-final GeneratedFile target = +- new GeneratedFile('test/integration/support/integration_test_methods.dart', +- (String pkgPath) async { +- CodegenInttestMethodsVisitor visitor = new CodegenInttestMethodsVisitor( +- path.basename(pkgPath), readApi(pkgPath)); +- return visitor.collectCode(visitor.visitApi); +-}); +- +-/** +- * Visitor that generates the code for integration_test_methods.dart +- */ +-class CodegenInttestMethodsVisitor extends DartCodegenVisitor +- with CodeGenerator { +- /** +- * The name of the package into which code is being generated. +- */ +- final String packageName; +- +- /** +- * Visitor used to produce doc comments. +- */ +- final ToHtmlVisitor toHtmlVisitor; +- +- /** +- * Code snippets concatenated to initialize all of the class fields. +- */ +- List fieldInitializationCode = []; +- +- /** +- * Code snippets concatenated to produce the contents of the switch statement +- * for dispatching notifications. +- */ +- List notificationSwitchContents = []; +- +- CodegenInttestMethodsVisitor(this.packageName, Api api) +- : toHtmlVisitor = new ToHtmlVisitor(api), +- super(api) { +- codeGeneratorSettings.commentLineLength = 79; +- codeGeneratorSettings.languageName = 'dart'; +- } +- +- /** +- * Generate a function argument for the given parameter field. +- */ +- String formatArgument(TypeObjectField field) => +- '${dartType(field.type)} ${field.name}'; +- +- /** +- * Figure out the appropriate Dart type for data having the given API +- * protocol [type]. +- */ +- String jsonType(TypeDecl type) { +- type = resolveTypeReferenceChain(type); +- if (type is TypeEnum) { +- return 'String'; +- } else if (type is TypeList) { +- return 'List<${jsonType(type.itemType)}>'; +- } else if (type is TypeMap) { +- return 'Map'; +- } else if (type is TypeObject) { +- return 'Map'; +- } else if (type is TypeReference) { +- switch (type.typeName) { +- case 'String': +- case 'int': +- case 'bool': +- // These types correspond exactly to Dart types +- return type.typeName; +- case 'object': +- return 'Map'; +- default: +- throw new Exception(type.typeName); +- } +- } else if (type is TypeUnion) { +- return 'Object'; +- } else { +- throw new Exception('Unexpected kind of TypeDecl'); +- } +- } +- +- @override +- visitApi() { +- outputHeader(year: '2017'); +- writeln(); +- writeln('/**'); +- writeln(' * Convenience methods for running integration tests'); +- writeln(' */'); +- writeln("import 'dart:async';"); +- writeln(); +- writeln("import 'package:$packageName/protocol/protocol_generated.dart';"); +- writeln( +- "import 'package:$packageName/src/protocol/protocol_internal.dart';"); +- writeln("import 'package:test/test.dart';"); +- writeln(); +- writeln("import 'integration_tests.dart';"); +- writeln("import 'protocol_matchers.dart';"); +- for (String uri in api.types.importUris) { +- write("import '"); +- write(uri); +- writeln("';"); +- } +- writeln(); +- writeln('/**'); +- writeln(' * Convenience methods for running integration tests'); +- writeln(' */'); +- writeln('abstract class IntegrationTestMixin {'); +- indent(() { +- writeln('Server get server;'); +- super.visitApi(); +- writeln(); +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.writeln('Initialize the fields in InttestMixin, and'); +- toHtmlVisitor.writeln('ensure that notifications will be handled.'); +- })); +- writeln('void initializeInttestMixin() {'); +- indent(() { +- write(fieldInitializationCode.join()); +- }); +- writeln('}'); +- writeln(); +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.writeln('Dispatch the notification named [event], and'); +- toHtmlVisitor.writeln('containing parameters [params], to the'); +- toHtmlVisitor.writeln('appropriate stream.'); +- })); +- writeln('void dispatchNotification(String event, params) {'); +- indent(() { +- writeln('ResponseDecoder decoder = new ResponseDecoder(null);'); +- writeln('switch (event) {'); +- indent(() { +- write(notificationSwitchContents.join()); +- writeln('default:'); +- indent(() { +- writeln("fail('Unexpected notification: \$event');"); +- writeln('break;'); +- }); +- }); +- writeln('}'); +- }); +- writeln('}'); +- }); +- writeln('}'); +- } +- +- @override +- visitNotification(Notification notification) { +- String streamName = +- camelJoin(['on', notification.domainName, notification.event]); +- String className = camelJoin( +- [notification.domainName, notification.event, 'params'], +- doCapitalize: true); +- writeln(); +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(notification.html); +- toHtmlVisitor.describePayload(notification.params, 'Parameters'); +- })); +- writeln('Stream<$className> $streamName;'); +- writeln(); +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.write('Stream controller for [$streamName].'); +- })); +- writeln('StreamController<$className> _$streamName;'); +- fieldInitializationCode.add(collectCode(() { +- writeln('_$streamName = new StreamController<$className>(sync: true);'); +- writeln('$streamName = _$streamName.stream.asBroadcastStream();'); +- })); +- notificationSwitchContents.add(collectCode(() { +- writeln('case ${JSON.encode(notification.longEvent)}:'); +- indent(() { +- String paramsValidator = camelJoin( +- ['is', notification.domainName, notification.event, 'params']); +- writeln('outOfTestExpect(params, $paramsValidator);'); +- String constructorCall; +- if (notification.params == null) { +- constructorCall = 'new $className()'; +- } else { +- constructorCall = +- "new $className.fromJson(decoder, 'params', params)"; +- } +- writeln('_$streamName.add($constructorCall);'); +- writeln('break;'); +- }); +- })); +- } +- +- @override +- visitRequest(Request request) { +- String methodName = camelJoin(['send', request.domainName, request.method]); +- List args = []; +- List optionalArgs = []; +- if (request.params != null) { +- for (TypeObjectField field in request.params.fields) { +- if (field.optional) { +- optionalArgs.add(formatArgument(field)); +- } else { +- args.add(formatArgument(field)); +- } +- } +- } +- if (optionalArgs.isNotEmpty) { +- args.add('{${optionalArgs.join(', ')}}'); +- } +- writeln(); +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(request.html); +- toHtmlVisitor.describePayload(request.params, 'Parameters'); +- toHtmlVisitor.describePayload(request.result, 'Returns'); +- })); +- if (request.deprecated) { +- writeln('@deprecated'); +- } +- String resultClass; +- String futureClass; +- if (request.result == null) { +- futureClass = 'Future'; +- } else { +- resultClass = camelJoin([request.domainName, request.method, 'result'], +- doCapitalize: true); +- futureClass = 'Future<$resultClass>'; +- } +- writeln('$futureClass $methodName(${args.join(', ')}) async {'); +- indent(() { +- String requestClass = camelJoin( +- [request.domainName, request.method, 'params'], +- doCapitalize: true); +- String paramsVar = 'null'; +- if (request.params != null) { +- paramsVar = 'params'; +- List args = []; +- List optionalArgs = []; +- for (TypeObjectField field in request.params.fields) { +- if (field.optional) { +- optionalArgs.add('${field.name}: ${field.name}'); +- } else { +- args.add(field.name); +- } +- } +- args.addAll(optionalArgs); +- writeln('var params = new $requestClass(${args.join(', ')}).toJson();'); +- } +- String methodJson = JSON.encode(request.longMethod); +- writeln('var result = await server.send($methodJson, $paramsVar);'); +- if (request.result != null) { +- String kind = 'null'; +- if (requestClass == 'EditGetRefactoringParams') { +- kind = 'kind'; +- } +- writeln('ResponseDecoder decoder = new ResponseDecoder($kind);'); +- writeln("return new $resultClass.fromJson(decoder, 'result', result);"); +- } else { +- writeln('outOfTestExpect(result, isNull);'); +- writeln('return null;'); +- } +- }); +- writeln('}'); +- } +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart +deleted file mode 100644 +index 805d06a7895..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_java.dart ++++ /dev/null +@@ -1,301 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Tools for Java code generation. +- */ +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:html/dom.dart' as dom; +- +-import 'api.dart'; +-import 'from_html.dart'; +-import 'to_html.dart'; +- +-/** +- * Create a [GeneratedFile] that creates Java code and outputs it to [path]. +- * [path] uses Posix-style path separators regardless of the OS. +- */ +-GeneratedFile javaGeneratedFile( +- String path, CodegenJavaVisitor createVisitor(Api api)) { +- return new GeneratedFile(path, (String pkgPath) async { +- CodegenJavaVisitor visitor = createVisitor(readApi(pkgPath)); +- return visitor.collectCode(visitor.visitApi); +- }); +-} +- +-/** +- * Iterate through the values in [map] in the order of increasing keys. +- */ +-Iterable _valuesSortedByKey(Map map) { +- List keys = map.keys.toList(); +- keys.sort(); +- return keys.map((String key) => map[key]); +-} +- +-/** +- * Common code for all Java code generation. +- */ +-class CodegenJavaVisitor extends HierarchicalApiVisitor with CodeGenerator { +- /** +- * Variable names which must be changed in order to avoid conflict with +- * reserved words in Java. +- */ +- static const Map _variableRenames = const { +- 'default': 'defaultSdk' +- }; +- +- /** +- * Type references in the spec that are named something else in Java. +- */ +- static const Map _typeRenames = const { +- 'bool': 'boolean', +- 'int': 'int', +- 'ExecutionContextId': 'String', +- 'FilePath': 'String', +- 'DebugContextId': 'String', +- 'object': 'Object', +- 'Override': 'OverrideMember', +- }; +- +- _CodegenJavaState _state; +- +- /** +- * Visitor used to produce doc comments. +- */ +- final ToHtmlVisitor toHtmlVisitor; +- +- CodegenJavaVisitor(Api api) +- : toHtmlVisitor = new ToHtmlVisitor(api), +- super(api); +- +- /** +- * Create a constructor, using [callback] to create its contents. +- */ +- void constructor(String name, void callback()) { +- _state.constructors[name] = collectCode(callback); +- } +- +- /** +- * Return true iff the passed [TypeDecl] will represent an array in Java. +- */ +- bool isArray(TypeDecl type) { +- return type is TypeList && isPrimitive(type.itemType); +- } +- +- /** +- * Return true iff the passed [TypeDecl] is a type declared in the spec_input. +- */ +- bool isDeclaredInSpec(TypeDecl type) { +-// TypeReference resolvedType = super.resolveTypeReferenceChain(type); +-// if(resolvedType is TypeObject) { +-// return truye; +-// } +- if (type is TypeReference) { +- return api.types.containsKey(type.typeName) && javaType(type) != 'String'; +- } +- return false; +- } +- +- /** +- * Return true iff the passed [TypeDecl] will represent an array in Java. +- */ +- bool isList(TypeDecl type) { +- return type is TypeList && !isPrimitive(type.itemType); +- } +- +- /** +- * Return true iff the passed [TypeDecl] will represent a Map in type. +- */ +- bool isMap(TypeDecl type) { +- return type is TypeMap; +- } +- +- /** +- * Return true iff the passed [TypeDecl] will be represented as Object in Java. +- */ +- bool isObject(TypeDecl type) { +- String typeStr = javaType(type); +- return typeStr == 'Object'; +- } +- +- /** +- * Return true iff the passed [TypeDecl] will represent a primitive Java type. +- */ +- bool isPrimitive(TypeDecl type) { +- if (type is TypeReference) { +- String typeStr = javaType(type); +- return typeStr == 'boolean' || typeStr == 'int' || typeStr == 'long'; +- } +- return false; +- } +- +- /** +- * Convenience method for subclasses for calling docComment. +- */ +- void javadocComment(List docs) { +- docComment(docs); +- } +- +- /** +- * Return a Java type for the given [TypeObjectField]. +- */ +- String javaFieldType(TypeObjectField field) { +- return javaType(field.type, field.optional); +- } +- +- /** +- * Return a suitable representation of [name] as the name of a Java variable. +- */ +- String javaName(String name) { +- if (_variableRenames.containsKey(name)) { +- return _variableRenames[name]; +- } +- return name; +- } +- +- /** +- * Convert the given [TypeDecl] to a Java type. +- */ +- String javaType(TypeDecl type, [bool optional = false]) { +- if (type is TypeReference) { +- TypeReference resolvedType = resolveTypeReferenceChain(type); +- String typeName = resolvedType.typeName; +- if (_typeRenames.containsKey(typeName)) { +- typeName = _typeRenames[typeName]; +- if (optional) { +- if (typeName == 'boolean') { +- typeName = 'Boolean'; +- } else if (typeName == 'int') { +- typeName = 'Integer'; +- } +- } +- } +- return typeName; +- } else if (type is TypeList) { +- if (isPrimitive(type.itemType)) { +- return '${javaType(type.itemType)}[]'; +- } else { +- return 'List<${javaType(type.itemType)}>'; +- } +- } else if (type is TypeMap) { +- return 'Map<${javaType(type.keyType)}, ${javaType(type.valueType)}>'; +- } else if (type is TypeUnion) { +- return 'Object'; +- } else { +- throw new Exception("Can't make type buildable"); +- } +- } +- +- /** +- * Execute [callback], collecting any methods that are output using +- * [privateMethod] or [publicMethod], and insert the class (with methods +- * sorted). [header] is the part of the class declaration before the +- * opening brace. +- */ +- void makeClass(String header, void callback()) { +- _CodegenJavaState oldState = _state; +- try { +- _state = new _CodegenJavaState(); +- callback(); +- writeln('$header {'); +- indent(() { +- // fields +- List allFields = _state.publicFields.values.toList(); +- allFields.addAll(_state.privateFields.values.toList()); +- for (String field in allFields) { +- writeln(); +- write(field); +- } +- +- // constructors +- List allConstructors = _state.constructors.values.toList(); +- for (String constructor in allConstructors) { +- writeln(); +- write(constructor); +- } +- +- // methods (ordered by method name) +- List allMethods = +- _valuesSortedByKey(_state.publicMethods).toList(); +- allMethods.addAll(_valuesSortedByKey(_state.privateMethods)); +- for (String method in allMethods) { +- writeln(); +- write(method); +- } +- writeln(); +- }); +- writeln('}'); +- } finally { +- _state = oldState; +- } +- } +- +- /** +- * Create a private field, using [callback] to create its contents. +- */ +- void privateField(String fieldName, void callback()) { +- _state.privateFields[fieldName] = collectCode(callback); +- } +- +- /** +- * Create a private method, using [callback] to create its contents. +- */ +- void privateMethod(String methodName, void callback()) { +- _state.privateMethods[methodName] = collectCode(callback); +- } +- +- /** +- * Create a public field, using [callback] to create its contents. +- */ +- void publicField(String fieldName, void callback()) { +- _state.publicFields[fieldName] = collectCode(callback); +- } +- +- /** +- * Create a public method, using [callback] to create its contents. +- */ +- void publicMethod(String methodName, void callback()) { +- _state.publicMethods[methodName] = collectCode(callback); +- } +- +- @override +- TypeDecl resolveTypeReferenceChain(TypeDecl type) { +- TypeDecl typeDecl = super.resolveTypeReferenceChain(type); +- if (typeDecl is TypeEnum) { +- return new TypeReference('String', null); +- } +- return type; +- } +-} +- +-/** +- * State used by [CodegenJavaVisitor]. +- */ +-class _CodegenJavaState { +- /** +- * Temporary storage for public methods. +- */ +- Map publicMethods = {}; +- +- /** +- * Temporary storage for private methods. +- */ +- Map privateMethods = {}; +- +- /** +- * Temporary storage for public fields. +- */ +- Map publicFields = {}; +- +- /** +- * Temporary storage for private fields. +- */ +- Map privateFields = {}; +- +- /** +- * Temporary storage for constructors. +- */ +- Map constructors = {}; +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart +deleted file mode 100644 +index 85d6a9a6dcb..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart ++++ /dev/null +@@ -1,744 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code generation for the file "AnalysisServer.java". +- */ +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:html/dom.dart' as dom; +- +-import 'api.dart'; +-import 'codegen_java.dart'; +-import 'from_html.dart'; +-import 'implied_types.dart'; +- +-/** +- * A map between the field names and values for the Element object such as: +- * +- * private static final int ABSTRACT = 0x01; +- */ +-const Map _extraFieldsOnElement = const { +- 'ABSTRACT': '0x01', +- 'CONST': '0x02', +- 'FINAL': '0x04', +- 'TOP_LEVEL_STATIC': '0x08', +- 'PRIVATE': '0x10', +- 'DEPRECATED': '0x20', +-}; +- +-/** +- * A map between the method names and field names to generate additional methods on the Element object: +- * +- * public boolean isFinal() { +- * return (flags & FINAL) != 0; +- * } +- */ +-const Map _extraMethodsOnElement = const { +- 'isAbstract': 'ABSTRACT', +- 'isConst': 'CONST', +- 'isDeprecated': 'DEPRECATED', +- 'isFinal': 'FINAL', +- 'isPrivate': 'PRIVATE', +- 'isTopLevelOrStatic': 'TOP_LEVEL_STATIC', +-}; +- +-/** +- * Type references in the spec that are named something else in Java. +- */ +-const Map _typeRenames = const { +- 'Override': 'OverrideMember', +-}; +- +-final String pathToGenTypes = 'tool/spec/generated/java/types'; +- +-final GeneratedDirectory targetDir = +- new GeneratedDirectory(pathToGenTypes, (String pkgPath) { +- Api api = readApi(pkgPath); +- Map impliedTypes = computeImpliedTypes(api); +- Map map = +- new Map(); +- for (ImpliedType impliedType in impliedTypes.values) { +- String typeNameInSpec = capitalize(impliedType.camelName); +- bool isRefactoringFeedback = impliedType.kind == 'refactoringFeedback'; +- bool isRefactoringOption = impliedType.kind == 'refactoringOptions'; +- if (impliedType.kind == 'typeDefinition' || +- isRefactoringFeedback || +- isRefactoringOption) { +- TypeDecl type = impliedType.type; +- if (type is TypeObject || type is TypeEnum) { +- // This is for situations such as 'Override' where the name in the spec +- // doesn't match the java object that we generate: +- String typeNameInJava = typeNameInSpec; +- if (_typeRenames.containsKey(typeNameInSpec)) { +- typeNameInJava = _typeRenames[typeNameInSpec]; +- } +- map['$typeNameInJava.java'] = (String pkgPath) async { +- String superclassName = null; +- if (isRefactoringFeedback) { +- superclassName = 'RefactoringFeedback'; +- } +- if (isRefactoringOption) { +- superclassName = 'RefactoringOptions'; +- } +- // configure accessors +- bool generateGetters = true; +- bool generateSetters = false; +- if (isRefactoringOption || +- typeNameInSpec == 'Outline' || +- typeNameInSpec == 'RefactoringMethodParameter') { +- generateSetters = true; +- } +- // create the visitor +- CodegenJavaType visitor = new CodegenJavaType(api, typeNameInJava, +- superclassName, generateGetters, generateSetters); +- return visitor.collectCode(() { +- dom.Element doc = type.html; +- if (impliedType.apiNode is TypeDefinition) { +- doc = (impliedType.apiNode as TypeDefinition).html; +- } +- visitor.emitType(type, doc); +- }); +- }; +- } +- } +- } +- return map; +-}); +- +-class CodegenJavaType extends CodegenJavaVisitor { +- final String className; +- final String superclassName; +- final bool generateGetters; +- final bool generateSetters; +- +- CodegenJavaType(Api api, this.className, this.superclassName, +- this.generateGetters, this.generateSetters) +- : super(api); +- +- /** +- * Get the name of the consumer class for responses to this request. +- */ +- String consumerName(Request request) { +- return camelJoin([request.method, 'consumer'], doCapitalize: true); +- } +- +- void emitType(TypeDecl type, dom.Element html) { +- outputHeader(javaStyle: true); +- writeln('package org.dartlang.analysis.server.protocol;'); +- writeln(); +- if (type is TypeObject) { +- _writeTypeObject(type, html); +- } else if (type is TypeEnum) { +- _writeTypeEnum(type, html); +- } +- } +- +- String _getAsTypeMethodName(TypeDecl typeDecl) { +- String name = javaType(typeDecl, true); +- if (name == 'String') { +- return 'getAsString'; +- } else if (name == 'boolean' || name == 'Boolean') { +- return 'getAsBoolean'; +- } else if (name == 'int' || name == 'Integer') { +- return 'getAsInt'; +- } else if (name == 'long' || name == 'Long') { +- return 'getAsLong'; +- } else if (name.startsWith('List')) { +- return 'getAsJsonArray'; +- } else { +- // TODO (jwren) cleanup +- return 'getAsJsonArray'; +- } +- } +- +- String _getEqualsLogicForField(TypeObjectField field, String other) { +- String name = javaName(field.name); +- if (isPrimitive(field.type) && !field.optional) { +- return '$other.$name == $name'; +- } else if (isArray(field.type)) { +- return 'Arrays.equals(other.$name, $name)'; +- } else { +- return 'ObjectUtilities.equals($other.$name, $name)'; +- } +- } +- +- /** +- * For some [TypeObjectField] return the [String] source for the field value +- * for the toString generation. +- */ +- String _getToStringForField(TypeObjectField field) { +- String name = javaName(field.name); +- if (isArray(field.type) || isList(field.type)) { +- return 'StringUtils.join($name, ", ")'; +- } else { +- return name; +- } +- } +- +- bool _isTypeFieldInUpdateContentUnionType( +- String className, String fieldName) { +- if ((className == 'AddContentOverlay' || +- className == 'ChangeContentOverlay' || +- className == 'RemoveContentOverlay') && +- fieldName == 'type') { +- return true; +- } else { +- return false; +- } +- } +- +- /** +- * This method writes extra fields and methods to the Element type. +- */ +- void _writeExtraContentInElementType() { +- // +- // Extra fields on the Element type such as: +- // private static final int ABSTRACT = 0x01; +- // +- _extraFieldsOnElement.forEach((String name, String value) { +- publicField(javaName(name), () { +- writeln('private static final int $name = $value;'); +- }); +- }); +- +- // +- // Extra methods for the Element type such as: +- // public boolean isFinal() { +- // return (flags & FINAL) != 0; +- // } +- // +- _extraMethodsOnElement.forEach((String methodName, String fieldName) { +- publicMethod(methodName, () { +- writeln('public boolean $methodName() {'); +- writeln(' return (flags & $fieldName) != 0;'); +- writeln('}'); +- }); +- }); +- } +- +- /** +- * For some [TypeObjectField] write out the source that adds the field +- * information to the 'jsonObject'. +- */ +- void _writeOutJsonObjectAddStatement(TypeObjectField field) { +- String name = javaName(field.name); +- if (isDeclaredInSpec(field.type)) { +- writeln('jsonObject.add("$name", $name.toJson());'); +- } else if (field.type is TypeList) { +- TypeDecl listItemType = (field.type as TypeList).itemType; +- String jsonArrayName = 'jsonArray${capitalize(name)}'; +- writeln('JsonArray $jsonArrayName = new JsonArray();'); +- writeln('for (${javaType(listItemType)} elt : $name) {'); +- indent(() { +- if (isDeclaredInSpec(listItemType)) { +- writeln('$jsonArrayName.add(elt.toJson());'); +- } else { +- writeln('$jsonArrayName.add(new JsonPrimitive(elt));'); +- } +- }); +- writeln('}'); +- writeln('jsonObject.add("$name", $jsonArrayName);'); +- } else { +- writeln('jsonObject.addProperty("$name", $name);'); +- } +- } +- +- void _writeTypeEnum(TypeDecl type, dom.Element html) { +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(html); +- toHtmlVisitor.br(); +- toHtmlVisitor.write('@coverage dart.server.generated.types'); +- })); +- makeClass('public class $className', () { +- TypeEnum typeEnum = type as TypeEnum; +- List values = typeEnum.values; +- // +- // enum fields +- // +- for (TypeEnumValue value in values) { +- privateField(javaName(value.value), () { +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(value.html); +- })); +- writeln( +- 'public static final String ${value.value} = \"${value.value}\";'); +- }); +- } +- }); +- } +- +- void _writeTypeObject(TypeDecl type, dom.Element html) { +- writeln('import java.util.Arrays;'); +- writeln('import java.util.List;'); +- writeln('import java.util.Map;'); +- writeln('import com.google.common.collect.Lists;'); +- writeln('import com.google.dart.server.utilities.general.JsonUtilities;'); +- writeln('import com.google.dart.server.utilities.general.ObjectUtilities;'); +- writeln('import com.google.gson.JsonArray;'); +- writeln('import com.google.gson.JsonElement;'); +- writeln('import com.google.gson.JsonObject;'); +- writeln('import com.google.gson.JsonPrimitive;'); +- writeln('import org.apache.commons.lang3.builder.HashCodeBuilder;'); +- writeln('import java.util.ArrayList;'); +- writeln('import java.util.Iterator;'); +- writeln('import org.apache.commons.lang3.StringUtils;'); +- writeln(); +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(html); +- toHtmlVisitor.br(); +- toHtmlVisitor.write('@coverage dart.server.generated.types'); +- })); +- writeln('@SuppressWarnings("unused")'); +- String header = 'public class $className'; +- if (superclassName != null) { +- header += ' extends $superclassName'; +- } +- makeClass(header, () { +- // +- // fields +- // +- // +- // public static final "EMPTY_ARRAY" field +- // +- publicField(javaName("EMPTY_ARRAY"), () { +- writeln( +- 'public static final $className[] EMPTY_ARRAY = new $className[0];'); +- }); +- +- // +- // public static final "EMPTY_LIST" field +- // +- publicField(javaName("EMPTY_LIST"), () { +- writeln( +- 'public static final List<$className> EMPTY_LIST = Lists.newArrayList();'); +- }); +- +- // +- // "private static String name;" fields: +- // +- TypeObject typeObject = type as TypeObject; +- List fields = typeObject.fields; +- for (TypeObjectField field in fields) { +- String type = javaFieldType(field); +- String name = javaName(field.name); +- if (!(className == 'Outline' && name == 'children')) { +- privateField(name, () { +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(field.html); +- })); +- if (generateSetters) { +- writeln('private $type $name;'); +- } else { +- writeln('private final $type $name;'); +- } +- }); +- } +- } +- if (className == 'Outline') { +- privateField(javaName('parent'), () { +- writeln('private final Outline parent;'); +- }); +- privateField(javaName('children'), () { +- writeln('private List children;'); +- }); +- } +- if (className == 'NavigationRegion') { +- privateField(javaName('targetObjects'), () { +- writeln( +- 'private final List targetObjects = Lists.newArrayList();'); +- }); +- } +- if (className == 'NavigationTarget') { +- privateField(javaName('file'), () { +- writeln('private String file;'); +- }); +- } +- +- // +- // constructor +- // +- constructor(className, () { +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.write('Constructor for {@link $className}.'); +- })); +- write('public $className('); +- // write out parameters to constructor +- List parameters = new List(); +- if (className == 'Outline') { +- parameters.add('Outline parent'); +- } +- for (TypeObjectField field in fields) { +- String type = javaFieldType(field); +- String name = javaName(field.name); +- if (!_isTypeFieldInUpdateContentUnionType(className, field.name) && +- !(className == 'Outline' && name == 'children')) { +- parameters.add('$type $name'); +- } +- } +- write(parameters.join(', ')); +- writeln(') {'); +- // write out the assignments in the body of the constructor +- indent(() { +- if (className == 'Outline') { +- writeln('this.parent = parent;'); +- } +- for (TypeObjectField field in fields) { +- String name = javaName(field.name); +- if (!_isTypeFieldInUpdateContentUnionType(className, field.name) && +- !(className == 'Outline' && name == 'children')) { +- writeln('this.$name = $name;'); +- } else if (className == 'AddContentOverlay') { +- writeln('this.type = "add";'); +- } else if (className == 'ChangeContentOverlay') { +- writeln('this.type = "change";'); +- } else if (className == 'RemoveContentOverlay') { +- writeln('this.type = "remove";'); +- } +- } +- }); +- writeln('}'); +- }); +- +- // +- // getter methods +- // +- if (generateGetters) { +- for (TypeObjectField field in fields) { +- String type = javaFieldType(field); +- String name = javaName(field.name); +- publicMethod('get$name', () { +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(field.html); +- })); +- if (type == 'boolean') { +- writeln('public $type $name() {'); +- } else { +- writeln('public $type get${capitalize(name)}() {'); +- } +- writeln(' return $name;'); +- writeln('}'); +- }); +- } +- } +- +- // +- // setter methods +- // +- if (generateSetters) { +- for (TypeObjectField field in fields) { +- String type = javaFieldType(field); +- String name = javaName(field.name); +- publicMethod('set$name', () { +- javadocComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.translateHtml(field.html); +- })); +- String setterName = 'set' + capitalize(name); +- writeln('public void $setterName($type $name) {'); +- writeln(' this.$name = $name;'); +- writeln('}'); +- }); +- } +- } +- +- if (className == 'NavigationRegion') { +- publicMethod('lookupTargets', () { +- writeln( +- 'public void lookupTargets(List allTargets) {'); +- writeln(' for (int i = 0; i < targets.length; i++) {'); +- writeln(' int targetIndex = targets[i];'); +- writeln(' NavigationTarget target = allTargets.get(targetIndex);'); +- writeln(' targetObjects.add(target);'); +- writeln(' }'); +- writeln('}'); +- }); +- publicMethod('getTargetObjects', () { +- writeln('public List getTargetObjects() {'); +- writeln(' return targetObjects;'); +- writeln('}'); +- }); +- } +- if (className == 'NavigationTarget') { +- publicMethod('lookupFile', () { +- writeln('public void lookupFile(String[] allTargetFiles) {'); +- writeln(' file = allTargetFiles[fileIndex];'); +- writeln('}'); +- }); +- publicMethod('getFile', () { +- writeln('public String getFile() {'); +- writeln(' return file;'); +- writeln('}'); +- }); +- } +- +- // +- // fromJson(JsonObject) factory constructor, example: +-// public JsonObject toJson(JsonObject jsonObject) { +-// String x = jsonObject.get("x").getAsString(); +-// return new Y(x); +-// } +- if (className != 'Outline') { +- publicMethod('fromJson', () { +- writeln('public static $className fromJson(JsonObject jsonObject) {'); +- indent(() { +- for (TypeObjectField field in fields) { +- write('${javaFieldType(field)} ${javaName(field.name)} = '); +- if (field.optional) { +- write( +- 'jsonObject.get("${javaName(field.name)}") == null ? null : '); +- } +- if (isDeclaredInSpec(field.type)) { +- write('${javaFieldType(field)}.fromJson('); +- write( +- 'jsonObject.get("${javaName(field.name)}").getAsJsonObject())'); +- } else { +- if (isList(field.type)) { +- if (javaFieldType(field).endsWith('')) { +- write( +- 'JsonUtilities.decodeStringList(jsonObject.get("${javaName(field.name)}").${_getAsTypeMethodName(field.type)}())'); +- } else { +- write( +- '${javaType((field.type as TypeList).itemType)}.fromJsonArray(jsonObject.get("${javaName(field.name)}").${_getAsTypeMethodName(field.type)}())'); +- } +- } else if (isArray(field.type)) { +- if (javaFieldType(field).startsWith('int')) { +- write( +- 'JsonUtilities.decodeIntArray(jsonObject.get("${javaName(field.name)}").${_getAsTypeMethodName(field.type)}())'); +- } +- } else { +- write( +- 'jsonObject.get("${javaName(field.name)}").${_getAsTypeMethodName(field.type)}()'); +- } +- } +- writeln(';'); +- } +- write('return new $className('); +- List parameters = new List(); +- for (TypeObjectField field in fields) { +- if (!_isTypeFieldInUpdateContentUnionType( +- className, field.name)) { +- parameters.add('${javaName(field.name)}'); +- } +- } +- write(parameters.join(', ')); +- writeln(');'); +- }); +- writeln('}'); +- }); +- } else { +- publicMethod('fromJson', () { +- writeln( +- '''public static Outline fromJson(Outline parent, JsonObject outlineObject) { +- JsonObject elementObject = outlineObject.get("element").getAsJsonObject(); +- Element element = Element.fromJson(elementObject); +- int offset = outlineObject.get("offset").getAsInt(); +- int length = outlineObject.get("length").getAsInt(); +- +- // create outline object +- Outline outline = new Outline(parent, element, offset, length); +- +- // compute children recursively +- List childrenList = Lists.newArrayList(); +- JsonElement childrenJsonArray = outlineObject.get("children"); +- if (childrenJsonArray instanceof JsonArray) { +- Iterator childrenElementIterator = ((JsonArray) childrenJsonArray).iterator(); +- while (childrenElementIterator.hasNext()) { +- JsonObject childObject = childrenElementIterator.next().getAsJsonObject(); +- childrenList.add(fromJson(outline, childObject)); +- } +- } +- outline.setChildren(childrenList); +- return outline; +-}'''); +- }); +- publicMethod('getParent', () { +- writeln('''public Outline getParent() { +- return parent; +-}'''); +- }); +- } +- +- // +- // fromJson(JsonArray) factory constructor +- // +- if (className != 'Outline' && +- className != 'RefactoringFeedback' && +- className != 'RefactoringOptions') { +- publicMethod('fromJsonArray', () { +- writeln( +- 'public static List<$className> fromJsonArray(JsonArray jsonArray) {'); +- indent(() { +- writeln('if (jsonArray == null) {'); +- writeln(' return EMPTY_LIST;'); +- writeln('}'); +- writeln( +- 'ArrayList<$className> list = new ArrayList<$className>(jsonArray.size());'); +- writeln('Iterator iterator = jsonArray.iterator();'); +- writeln('while (iterator.hasNext()) {'); +- writeln(' list.add(fromJson(iterator.next().getAsJsonObject()));'); +- writeln('}'); +- writeln('return list;'); +- }); +- writeln('}'); +- }); +- } +- +- // +- // toJson() method, example: +-// public JsonObject toJson() { +-// JsonObject jsonObject = new JsonObject(); +-// jsonObject.addProperty("x", x); +-// jsonObject.addProperty("y", y); +-// return jsonObject; +-// } +- if (className != 'Outline') { +- publicMethod('toJson', () { +- writeln('public JsonObject toJson() {'); +- indent(() { +- writeln('JsonObject jsonObject = new JsonObject();'); +- for (TypeObjectField field in fields) { +- if (!isObject(field.type)) { +- if (field.optional) { +- writeln('if (${javaName(field.name)} != null) {'); +- indent(() { +- _writeOutJsonObjectAddStatement(field); +- }); +- writeln('}'); +- } else { +- _writeOutJsonObjectAddStatement(field); +- } +- } +- } +- writeln('return jsonObject;'); +- }); +- writeln('}'); +- }); +- } +- +- // +- // equals() method +- // +- publicMethod('equals', () { +- writeln('@Override'); +- writeln('public boolean equals(Object obj) {'); +- indent(() { +- writeln('if (obj instanceof $className) {'); +- indent(() { +- writeln('$className other = ($className) obj;'); +- writeln('return'); +- indent(() { +- List equalsForField = new List(); +- for (TypeObjectField field in fields) { +- equalsForField.add(_getEqualsLogicForField(field, 'other')); +- } +- if (equalsForField.isNotEmpty) { +- write(equalsForField.join(' && \n')); +- } else { +- write('true'); +- } +- }); +- writeln(';'); +- }); +- writeln('}'); +- writeln('return false;'); +- }); +- writeln('}'); +- }); +- +- // +- // containsInclusive(int x) +- // +- if (className == 'HighlightRegion' || +- className == 'NavigationRegion' || +- className == 'Outline') { +- publicMethod('containsInclusive', () { +- writeln('public boolean containsInclusive(int x) {'); +- indent(() { +- writeln('return offset <= x && x <= offset + length;'); +- }); +- writeln('}'); +- }); +- } +- +- // +- // contains(int x) +- // +- if (className == 'Occurrences') { +- publicMethod('containsInclusive', () { +- writeln('public boolean containsInclusive(int x) {'); +- indent(() { +- writeln('for (int offset : offsets) {'); +- writeln(' if (offset <= x && x <= offset + length) {'); +- writeln(' return true;'); +- writeln(' }'); +- writeln('}'); +- writeln('return false;'); +- }); +- writeln('}'); +- }); +- } +- +- // +- // hashCode +- // +- publicMethod('hashCode', () { +- writeln('@Override'); +- writeln('public int hashCode() {'); +- indent(() { +- writeln('HashCodeBuilder builder = new HashCodeBuilder();'); +- for (int i = 0; i < fields.length; i++) { +- writeln("builder.append(${javaName(fields[i].name)});"); +- } +- writeln('return builder.toHashCode();'); +- }); +- writeln('}'); +- }); +- +- // +- // toString +- // +- publicMethod('toString', () { +- writeln('@Override'); +- writeln('public String toString() {'); +- indent(() { +- writeln('StringBuilder builder = new StringBuilder();'); +- writeln('builder.append(\"[\");'); +- for (int i = 0; i < fields.length; i++) { +- writeln("builder.append(\"${javaName(fields[i].name)}=\");"); +- write("builder.append(${_getToStringForField(fields[i])}"); +- if (i + 1 != fields.length) { +- // this is not the last field +- write(' + \", \"'); +- } +- writeln(');'); +- } +- writeln('builder.append(\"]\");'); +- writeln('return builder.toString();'); +- }); +- writeln('}'); +- }); +- +- if (className == 'Element') { +- _writeExtraContentInElementType(); +- } +- +- // +- // getBestName() +- // +- if (className == 'TypeHierarchyItem') { +- publicMethod('getBestName', () { +- writeln('public String getBestName() {'); +- indent(() { +- writeln('if (displayName == null) {'); +- writeln(' return classElement.getName();'); +- writeln('} else {'); +- writeln(' return displayName;'); +- writeln('}'); +- }); +- writeln('}'); +- }); +- } +- }); +- } +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart +deleted file mode 100644 +index a321ba07b14..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart ++++ /dev/null +@@ -1,191 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code generation for the file "matchers.dart". +- */ +-import 'dart:convert'; +- +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +- +-import 'api.dart'; +-import 'from_html.dart'; +-import 'implied_types.dart'; +-import 'to_html.dart'; +- +-final GeneratedFile target = new GeneratedFile( +- 'test/integration/support/protocol_matchers.dart', (String pkgPath) async { +- CodegenMatchersVisitor visitor = new CodegenMatchersVisitor(readApi(pkgPath)); +- return visitor.collectCode(visitor.visitApi); +-}); +- +-class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator { +- /** +- * Visitor used to produce doc comments. +- */ +- final ToHtmlVisitor toHtmlVisitor; +- +- /** +- * Short human-readable string describing the context of the matcher being +- * created. +- */ +- String context; +- +- CodegenMatchersVisitor(Api api) +- : toHtmlVisitor = new ToHtmlVisitor(api), +- super(api) { +- codeGeneratorSettings.commentLineLength = 79; +- codeGeneratorSettings.languageName = 'dart'; +- } +- +- /** +- * Create a matcher for the part of the API called [name], optionally +- * clarified by [nameSuffix]. The matcher should verify that its input +- * matches the given [type]. +- */ +- void makeMatcher(ImpliedType impliedType) { +- context = impliedType.humanReadableName; +- docComment(toHtmlVisitor.collectHtml(() { +- toHtmlVisitor.p(() { +- toHtmlVisitor.write(context); +- }); +- if (impliedType.type != null) { +- toHtmlVisitor.showType(null, impliedType.type); +- } +- })); +- write('final Matcher ${camelJoin(['is', impliedType.camelName])} = '); +- if (impliedType.type == null) { +- write('isNull'); +- } else { +- visitTypeDecl(impliedType.type); +- } +- writeln(';'); +- writeln(); +- } +- +- /** +- * Generate a map describing the given set of fields, for use as the +- * 'requiredFields' or 'optionalFields' argument to the [MatchesJsonObject] +- * constructor. +- */ +- void outputObjectFields(Iterable fields) { +- if (fields.isEmpty) { +- write('null'); +- return; +- } +- writeln('{'); +- indent(() { +- bool commaNeeded = false; +- for (TypeObjectField field in fields) { +- if (commaNeeded) { +- writeln(','); +- } +- write('${JSON.encode(field.name)}: '); +- if (field.value != null) { +- write('equals(${JSON.encode(field.value)})'); +- } else { +- visitTypeDecl(field.type); +- } +- commaNeeded = true; +- } +- writeln(); +- }); +- write('}'); +- } +- +- @override +- visitApi() { +- outputHeader(year: '2017'); +- writeln(); +- writeln('/**'); +- writeln(' * Matchers for data types defined in the analysis server API'); +- writeln(' */'); +- writeln("import 'package:test/test.dart';"); +- writeln(); +- writeln("import 'integration_tests.dart';"); +- writeln(); +- List impliedTypes = computeImpliedTypes(api).values.toList(); +- impliedTypes.sort((ImpliedType first, ImpliedType second) => +- first.camelName.compareTo(second.camelName)); +- for (ImpliedType impliedType in impliedTypes) { +- makeMatcher(impliedType); +- } +- } +- +- @override +- visitTypeEnum(TypeEnum typeEnum) { +- writeln('new MatchesEnum(${JSON.encode(context)}, ['); +- indent(() { +- bool commaNeeded = false; +- for (TypeEnumValue value in typeEnum.values) { +- if (commaNeeded) { +- writeln(','); +- } +- write('${JSON.encode(value.value)}'); +- commaNeeded = true; +- } +- writeln(); +- }); +- write('])'); +- } +- +- @override +- visitTypeList(TypeList typeList) { +- write('isListOf('); +- visitTypeDecl(typeList.itemType); +- write(')'); +- } +- +- @override +- visitTypeMap(TypeMap typeMap) { +- write('isMapOf('); +- visitTypeDecl(typeMap.keyType); +- write(', '); +- visitTypeDecl(typeMap.valueType); +- write(')'); +- } +- +- @override +- void visitTypeObject(TypeObject typeObject) { +- writeln('new LazyMatcher(() => new MatchesJsonObject('); +- indent(() { +- write('${JSON.encode(context)}, '); +- Iterable requiredFields = +- typeObject.fields.where((TypeObjectField field) => !field.optional); +- outputObjectFields(requiredFields); +- List optionalFields = typeObject.fields +- .where((TypeObjectField field) => field.optional) +- .toList(); +- if (optionalFields.isNotEmpty) { +- write(', optionalFields: '); +- outputObjectFields(optionalFields); +- } +- }); +- write('))'); +- } +- +- @override +- void visitTypeReference(TypeReference typeReference) { +- String typeName = typeReference.typeName; +- if (typeName == 'long') { +- typeName = 'int'; +- } +- write(camelJoin(['is', typeName])); +- } +- +- @override +- void visitTypeUnion(TypeUnion typeUnion) { +- bool commaNeeded = false; +- write('isOneOf(['); +- for (TypeDecl choice in typeUnion.choices) { +- if (commaNeeded) { +- write(', '); +- } +- visitTypeDecl(choice); +- commaNeeded = true; +- } +- write('])'); +- } +-} +diff --git a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart +deleted file mode 100644 +index cdb7c6a2454..00000000000 +--- a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart ++++ /dev/null +@@ -1,170 +0,0 @@ +-// 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 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +- +-import 'api.dart'; +-import 'codegen_dart.dart'; +-import 'from_html.dart'; +- +-final GeneratedFile target = new GeneratedFile( +- 'lib/protocol/protocol_constants.dart', (String pkgPath) async { +- CodegenVisitor visitor = new CodegenVisitor(readApi(pkgPath)); +- return visitor.collectCode(visitor.visitApi); +-}); +- +-/** +- * A visitor that produces Dart code defining constants associated with the API. +- */ +-class CodegenVisitor extends DartCodegenVisitor with CodeGenerator { +- CodegenVisitor(Api api) : super(api) { +- codeGeneratorSettings.commentLineLength = 79; +- codeGeneratorSettings.languageName = 'dart'; +- } +- +- /** +- * Generate all of the constants associates with the [api]. +- */ +- void generateConstants() { +- _ConstantVisitor visitor = new _ConstantVisitor(api); +- visitor.visitApi(); +- List<_Constant> constants = visitor.constants; +- constants.sort((first, second) => first.name.compareTo(second.name)); +- for (_Constant constant in constants) { +- generateContant(constant); +- } +- } +- +- /** +- * Generate the given [constant]. +- */ +- void generateContant(_Constant constant) { +- write('const String '); +- write(constant.name); +- write(' = '); +- write(constant.value); +- writeln(';'); +- } +- +- @override +- visitApi() { +- outputHeader(year: '2017'); +- writeln(); +- generateConstants(); +- } +-} +- +-/** +- * A representation of a constant that is to be generated. +- */ +-class _Constant { +- /** +- * The name of the constant. +- */ +- final String name; +- +- /** +- * The value of the constant. +- */ +- final String value; +- +- /** +- * Initialize a newly created constant. +- */ +- _Constant(this.name, this.value); +-} +- +-/** +- * A visitor that visits an API to compute a list of constants to be generated. +- */ +-class _ConstantVisitor extends HierarchicalApiVisitor { +- /** +- * The list of constants to be generated. +- */ +- List<_Constant> constants = <_Constant>[]; +- +- /** +- * Initialize a newly created visitor to visit the given [api]. +- */ +- _ConstantVisitor(Api api) : super(api); +- +- @override +- void visitNotification(Notification notification) { +- String domainName = notification.domainName; +- String event = notification.event; +- +- String constantName = _generateName(domainName, 'notification', event); +- constants.add(new _Constant(constantName, "'$domainName.$event'")); +- _addFieldConstants(constantName, notification.params); +- } +- +- @override +- void visitRequest(Request request) { +- String domainName = request.domainName; +- String method = request.method; +- +- String requestConstantName = _generateName(domainName, 'request', method); +- constants.add(new _Constant(requestConstantName, "'$domainName.$method'")); +- _addFieldConstants(requestConstantName, request.params); +- +- String responseConstantName = _generateName(domainName, 'response', method); +- _addFieldConstants(responseConstantName, request.result); +- } +- +- /** +- * Generate a constant for each of the fields in the given [type], where the +- * name of each constant will be composed from the [parentName] and the name +- * of the field. +- */ +- void _addFieldConstants(String parentName, TypeObject type) { +- if (type == null) { +- return; +- } +- type.fields.forEach((TypeObjectField field) { +- String name = field.name; +- List components = []; +- components.add(parentName); +- components.addAll(_split(name)); +- String fieldConstantName = _fromComponents(components); +- constants.add(new _Constant(fieldConstantName, "'$name'")); +- }); +- } +- +- /** +- * Return a name generated by converting each of the given [components] to an +- * uppercase equivalent, then joining them with underscores. +- */ +- String _fromComponents(List components) => +- components.map((String component) => component.toUpperCase()).join('_'); +- +- /** +- * Generate a name from the [domainName], [kind] and [name] components. +- */ +- String _generateName(String domainName, String kind, String name) { +- List components = []; +- components.addAll(_split(domainName)); +- components.add(kind); +- components.addAll(_split(name)); +- return _fromComponents(components); +- } +- +- /** +- * Return the components of the given [string] that are indicated by an upper +- * case letter. +- */ +- Iterable _split(String first) { +- RegExp regExp = new RegExp('[A-Z]'); +- List components = []; +- int start = 1; +- int index = first.indexOf(regExp, start); +- while (index >= 0) { +- components.add(first.substring(start - 1, index)); +- start = index + 1; +- index = first.indexOf(regExp, start); +- } +- components.add(first.substring(start - 1)); +- return components; +- } +-} +diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart +deleted file mode 100644 +index 26c6eb9122d..00000000000 +--- a/pkg/analysis_server/tool/spec/from_html.dart ++++ /dev/null +@@ -1,609 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code for reading an HTML API description. +- */ +-import 'dart:io'; +- +-import 'package:analyzer/src/codegen/html.dart'; +-import 'package:html/dom.dart' as dom; +-import 'package:html/parser.dart' as parser; +-import 'package:path/path.dart'; +- +-import 'api.dart'; +- +-/** +- * Read the API description from the file 'plugin_spec.html'. [pkgPath] is the +- * path to the current package. +- */ +-Api readApi(String pkgPath) { +- ApiReader reader = +- new ApiReader(join(pkgPath, 'tool', 'spec', 'spec_input.html')); +- return reader.readApi(); +-} +- +-typedef void ElementProcessor(dom.Element element); +- +-typedef void TextProcessor(dom.Text text); +- +-class ApiReader { +- static const List specialElements = const [ +- 'domain', +- 'feedback', +- 'object', +- 'refactorings', +- 'refactoring', +- 'type', +- 'types', +- 'request', +- 'notification', +- 'params', +- 'result', +- 'field', +- 'list', +- 'map', +- 'enum', +- 'key', +- 'value', +- 'options', +- 'ref', +- 'code', +- 'version', +- 'union', +- 'index', +- 'include' +- ]; +- +- /** +- * The absolute and normalized path to the file being read. +- */ +- final String filePath; +- +- /** +- * Initialize a newly created API reader to read from the file with the given +- * [filePath]. +- */ +- ApiReader(this.filePath); +- +- /** +- * Create an [Api] object from an HTML representation such as: +- * +- * +- * ... +- * +- * ... 1.0 ... +- * ... +- * ... +- * ... +- * +- * +- * +- * Child elements of can occur in any order. +- */ +- Api apiFromHtml(dom.Element html) { +- Api api; +- List versions = []; +- List domains = []; +- Types types = null; +- Refactorings refactorings = null; +- recurse(html, 'api', { +- 'domain': (dom.Element element) { +- domains.add(domainFromHtml(element)); +- }, +- 'refactorings': (dom.Element element) { +- refactorings = refactoringsFromHtml(element); +- }, +- 'types': (dom.Element element) { +- types = typesFromHtml(element); +- }, +- 'version': (dom.Element element) { +- versions.add(innerText(element)); +- }, +- 'index': (dom.Element element) { +- /* Ignore; generated dynamically. */ +- } +- }); +- if (versions.length != 1) { +- throw new Exception('The API must contain exactly one element'); +- } +- api = new Api(versions[0], domains, types, refactorings, html); +- return api; +- } +- +- /** +- * Check that the given [element] has all of the attributes in +- * [requiredAttributes], possibly some of the attributes in +- * [optionalAttributes], and no others. +- */ +- void checkAttributes( +- dom.Element element, List requiredAttributes, String context, +- {List optionalAttributes: const []}) { +- Set attributesFound = new Set(); +- element.attributes.forEach((name, value) { +- if (!requiredAttributes.contains(name) && +- !optionalAttributes.contains(name)) { +- throw new Exception( +- '$context: Unexpected attribute in ${element.localName}: $name'); +- } +- attributesFound.add(name); +- }); +- for (String expectedAttribute in requiredAttributes) { +- if (!attributesFound.contains(expectedAttribute)) { +- throw new Exception('$context: ${element +- .localName} must contain attribute $expectedAttribute'); +- } +- } +- } +- +- /** +- * Check that the given [element] has the given [expectedName]. +- */ +- void checkName(dom.Element element, String expectedName, [String context]) { +- if (element.localName != expectedName) { +- if (context == null) { +- context = element.localName; +- } +- throw new Exception( +- '$context: Expected $expectedName, found ${element.localName}'); +- } +- } +- +- /** +- * Create a [Domain] object from an HTML representation such as: +- * +- * +- * ... +- * ... +- * +- * +- * Child elements can occur in any order. +- */ +- Domain domainFromHtml(dom.Element html) { +- checkName(html, 'domain'); +- String name = html.attributes['name']; +- String context = name ?? 'domain'; +- bool experimental = html.attributes['experimental'] == 'true'; +- checkAttributes(html, ['name'], context, +- optionalAttributes: ['experimental']); +- List requests = []; +- List notifications = []; +- recurse(html, context, { +- 'request': (dom.Element child) { +- requests.add(requestFromHtml(child, context)); +- }, +- 'notification': (dom.Element child) { +- notifications.add(notificationFromHtml(child, context)); +- } +- }); +- return new Domain(name, requests, notifications, html, +- experimental: experimental); +- } +- +- dom.Element getAncestor(dom.Element html, String name, String context) { +- dom.Element ancestor = html.parent; +- while (ancestor != null) { +- if (ancestor.localName == name) { +- return ancestor; +- } +- ancestor = ancestor.parent; +- } +- throw new Exception( +- '$context: <${html.localName}> must be nested within <$name>'); +- } +- +- /** +- * Create a [Notification] object from an HTML representation such as: +- * +- * +- * ... +- * +- * +- * Note that the event name should not include the domain name. +- * +- * has the same form as , as described in [typeDeclFromHtml]. +- * +- * Child elements can occur in any order. +- */ +- Notification notificationFromHtml(dom.Element html, String context) { +- String domainName = getAncestor(html, 'domain', context).attributes['name']; +- checkName(html, 'notification', context); +- String event = html.attributes['event']; +- context = '$context.${event != null ? event : 'event'}'; +- checkAttributes(html, ['event'], context, +- optionalAttributes: ['experimental']); +- bool experimental = html.attributes['experimental'] == 'true'; +- TypeDecl params; +- recurse(html, context, { +- 'params': (dom.Element child) { +- params = typeObjectFromHtml(child, '$context.params'); +- } +- }); +- return new Notification(domainName, event, params, html, +- experimental: experimental); +- } +- +- /** +- * Create a single of [TypeDecl] corresponding to the type defined inside the +- * given HTML element. +- */ +- TypeDecl processContentsAsType(dom.Element html, String context) { +- List types = processContentsAsTypes(html, context); +- if (types.length != 1) { +- throw new Exception('$context: Exactly one type must be specified'); +- } +- return types[0]; +- } +- +- /** +- * Create a list of [TypeDecl]s corresponding to the types defined inside the +- * given HTML element. The following forms are supported. +- * +- * To refer to a type declared elsewhere (or a built-in type): +- * +- * typeName +- * +- * For a list: ItemType +- * +- * For a map: KeyTypeValueType +- * +- * For a JSON object: +- * +- * +- * ... +- * +- * +- * For an enum: +- * +- * +- * ... +- * +- * +- * For a union type: +- * +- * TYPE +- * +- */ +- List processContentsAsTypes(dom.Element html, String context) { +- List types = []; +- recurse(html, context, { +- 'object': (dom.Element child) { +- types.add(typeObjectFromHtml(child, context)); +- }, +- 'list': (dom.Element child) { +- checkAttributes(child, [], context); +- types.add(new TypeList(processContentsAsType(child, context), child)); +- }, +- 'map': (dom.Element child) { +- checkAttributes(child, [], context); +- TypeDecl keyType; +- TypeDecl valueType; +- recurse(child, context, { +- 'key': (dom.Element child) { +- if (keyType != null) { +- throw new Exception('$context: Key type already specified'); +- } +- keyType = processContentsAsType(child, '$context.key'); +- }, +- 'value': (dom.Element child) { +- if (valueType != null) { +- throw new Exception('$context: Value type already specified'); +- } +- valueType = processContentsAsType(child, '$context.value'); +- } +- }); +- if (keyType == null) { +- throw new Exception('$context: Key type not specified'); +- } +- if (valueType == null) { +- throw new Exception('$context: Value type not specified'); +- } +- types.add(new TypeMap(keyType, valueType, child)); +- }, +- 'enum': (dom.Element child) { +- types.add(typeEnumFromHtml(child, context)); +- }, +- 'ref': (dom.Element child) { +- checkAttributes(child, [], context); +- types.add(new TypeReference(innerText(child), child)); +- }, +- 'union': (dom.Element child) { +- checkAttributes(child, ['field'], context); +- String field = child.attributes['field']; +- types.add(new TypeUnion( +- processContentsAsTypes(child, context), field, child)); +- } +- }); +- return types; +- } +- +- /** +- * Read the API description from file with the given [filePath]. +- */ +- Api readApi() { +- String htmlContents = new File(filePath).readAsStringSync(); +- dom.Document document = parser.parse(htmlContents); +- dom.Element htmlElement = document.children +- .singleWhere((element) => element.localName.toLowerCase() == 'html'); +- return apiFromHtml(htmlElement); +- } +- +- void recurse(dom.Element parent, String context, +- Map elementProcessors) { +- for (String key in elementProcessors.keys) { +- if (!specialElements.contains(key)) { +- throw new Exception('$context: $key is not a special element'); +- } +- } +- for (dom.Node node in parent.nodes) { +- if (node is dom.Element) { +- if (elementProcessors.containsKey(node.localName)) { +- elementProcessors[node.localName](node); +- } else if (specialElements.contains(node.localName)) { +- throw new Exception( +- '$context: Unexpected use of <${node.localName}>'); +- } else { +- recurse(node, context, elementProcessors); +- } +- } +- } +- } +- +- /** +- * Create a [Refactoring] object from an HTML representation such as: +- * +- * +- * ... +- * ... +- * +- * +- * and have the same form as , as described in +- * [typeDeclFromHtml]. +- * +- * Child elements can occur in any order. +- */ +- Refactoring refactoringFromHtml(dom.Element html) { +- checkName(html, 'refactoring'); +- String kind = html.attributes['kind']; +- String context = kind != null ? kind : 'refactoring'; +- checkAttributes(html, ['kind'], context); +- TypeDecl feedback; +- TypeDecl options; +- recurse(html, context, { +- 'feedback': (dom.Element child) { +- feedback = typeObjectFromHtml(child, '$context.feedback'); +- }, +- 'options': (dom.Element child) { +- options = typeObjectFromHtml(child, '$context.options'); +- } +- }); +- return new Refactoring(kind, feedback, options, html); +- } +- +- /** +- * Create a [Refactorings] object from an HTML representation such as: +- * +- * +- * ... +- * +- */ +- Refactorings refactoringsFromHtml(dom.Element html) { +- checkName(html, 'refactorings'); +- String context = 'refactorings'; +- checkAttributes(html, [], context); +- List refactorings = []; +- recurse(html, context, { +- 'refactoring': (dom.Element child) { +- refactorings.add(refactoringFromHtml(child)); +- } +- }); +- return new Refactorings(refactorings, html); +- } +- +- /** +- * Create a [Request] object from an HTML representation such as: +- * +- * +- * ... +- * ... +- * +- * +- * Note that the method name should not include the domain name. +- * +- * and have the same form as , as described in +- * [typeDeclFromHtml]. +- * +- * Child elements can occur in any order. +- */ +- Request requestFromHtml(dom.Element html, String context) { +- String domainName = getAncestor(html, 'domain', context).attributes['name']; +- checkName(html, 'request', context); +- String method = html.attributes['method']; +- context = '$context.${method != null ? method : 'method'}'; +- checkAttributes(html, ['method'], context, +- optionalAttributes: ['experimental', 'deprecated']); +- bool experimental = html.attributes['experimental'] == 'true'; +- bool deprecated = html.attributes['deprecated'] == 'true'; +- TypeDecl params; +- TypeDecl result; +- recurse(html, context, { +- 'params': (dom.Element child) { +- params = typeObjectFromHtml(child, '$context.params'); +- }, +- 'result': (dom.Element child) { +- result = typeObjectFromHtml(child, '$context.result'); +- } +- }); +- return new Request(domainName, method, params, result, html, +- experimental: experimental, deprecated: deprecated); +- } +- +- /** +- * Create a [TypeDefinition] object from an HTML representation such as: +- * +- * +- * TYPE +- * +- * +- * Where TYPE is any HTML that can be parsed by [typeDeclFromHtml]. +- * +- * Child elements can occur in any order. +- */ +- TypeDefinition typeDefinitionFromHtml(dom.Element html) { +- checkName(html, 'type'); +- String name = html.attributes['name']; +- String context = name != null ? name : 'type'; +- checkAttributes(html, ['name'], context, +- optionalAttributes: ['experimental', 'deprecated']); +- TypeDecl type = processContentsAsType(html, context); +- bool experimental = html.attributes['experimental'] == 'true'; +- bool deprecated = html.attributes['deprecated'] == 'true'; +- return new TypeDefinition(name, type, html, +- experimental: experimental, deprecated: deprecated); +- } +- +- /** +- * Create a [TypeEnum] from an HTML description. +- */ +- TypeEnum typeEnumFromHtml(dom.Element html, String context) { +- checkName(html, 'enum', context); +- checkAttributes(html, [], context); +- List values = []; +- recurse(html, context, { +- 'value': (dom.Element child) { +- values.add(typeEnumValueFromHtml(child, context)); +- } +- }); +- return new TypeEnum(values, html); +- } +- +- /** +- * Create a [TypeEnumValue] from an HTML description such as: +- * +- * +- * VALUE +- * +- * +- * Where VALUE is the text of the enumerated value. +- * +- * Child elements can occur in any order. +- */ +- TypeEnumValue typeEnumValueFromHtml(dom.Element html, String context) { +- checkName(html, 'value', context); +- checkAttributes(html, [], context, optionalAttributes: ['deprecated']); +- bool deprecated = html.attributes['deprecated'] == 'true'; +- List values = []; +- recurse(html, context, { +- 'code': (dom.Element child) { +- String text = innerText(child).trim(); +- values.add(text); +- } +- }); +- if (values.length != 1) { +- throw new Exception('$context: Exactly one value must be specified'); +- } +- return new TypeEnumValue(values[0], html, deprecated: deprecated); +- } +- +- /** +- * Create a [TypeObjectField] from an HTML description such as: +- * +- * +- * TYPE +- * +- * +- * Where TYPE is any HTML that can be parsed by [typeDeclFromHtml]. +- * +- * In addition, the attribute optional="true" may be used to specify that the +- * field is optional, and the attribute value="..." may be used to specify that +- * the field is required to have a certain value. +- * +- * Child elements can occur in any order. +- */ +- TypeObjectField typeObjectFieldFromHtml(dom.Element html, String context) { +- checkName(html, 'field', context); +- String name = html.attributes['name']; +- context = '$context.${name != null ? name : 'field'}'; +- checkAttributes(html, ['name'], context, +- optionalAttributes: ['optional', 'value', 'deprecated']); +- bool deprecated = html.attributes['deprecated'] == 'true'; +- bool optional = false; +- String optionalString = html.attributes['optional']; +- if (optionalString != null) { +- switch (optionalString) { +- case 'true': +- optional = true; +- break; +- case 'false': +- optional = false; +- break; +- default: +- throw new Exception( +- '$context: field contains invalid "optional" attribute: "$optionalString"'); +- } +- } +- String value = html.attributes['value']; +- TypeDecl type = processContentsAsType(html, context); +- return new TypeObjectField(name, type, html, +- optional: optional, value: value, deprecated: deprecated); +- } +- +- /** +- * Create a [TypeObject] from an HTML description. +- */ +- TypeObject typeObjectFromHtml(dom.Element html, String context) { +- checkAttributes(html, [], context, optionalAttributes: ['experimental']); +- List fields = []; +- recurse(html, context, { +- 'field': (dom.Element child) { +- fields.add(typeObjectFieldFromHtml(child, context)); +- } +- }); +- bool experimental = html.attributes['experimental'] == 'true'; +- return new TypeObject(fields, html, experimental: experimental); +- } +- +- /** +- * Create a [Types] object from an HTML representation such as: +- * +- * +- * ... +- * +- */ +- Types typesFromHtml(dom.Element html) { +- checkName(html, 'types'); +- String context = 'types'; +- checkAttributes(html, [], context); +- List importUris = []; +- Map typeMap = {}; +- List childElements = []; +- recurse(html, context, { +- 'include': (dom.Element child) { +- String importUri = child.attributes['import']; +- if (importUri != null) { +- importUris.add(importUri); +- } +- String relativePath = child.attributes['path']; +- String path = normalize(join(dirname(filePath), relativePath)); +- ApiReader reader = new ApiReader(path); +- Api api = reader.readApi(); +- for (TypeDefinition typeDefinition in api.types) { +- typeDefinition.isExternal = true; +- childElements.add(typeDefinition.html); +- typeMap[typeDefinition.name] = typeDefinition; +- } +- }, +- 'type': (dom.Element child) { +- TypeDefinition typeDefinition = typeDefinitionFromHtml(child); +- typeMap[typeDefinition.name] = typeDefinition; +- } +- }); +- for (dom.Element element in childElements) { +- html.append(element); +- } +- Types types = new Types(typeMap, html); +- types.importUris.addAll(importUris); +- return types; +- } +-} +diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart +deleted file mode 100644 +index c5dd126c01e..00000000000 +--- a/pkg/analysis_server/tool/spec/generate_all.dart ++++ /dev/null +@@ -1,40 +0,0 @@ +-// Copyright (c) 2014, 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:io'; +- +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:path/path.dart'; +- +-import 'codegen_analysis_server.dart' as codegen_analysis_server; +-import 'codegen_dart_protocol.dart' as codegen_dart_protocol; +-import 'codegen_inttest_methods.dart' as codegen_inttest_methods; +-import 'codegen_java_types.dart' as codegen_java_types; +-import 'codegen_matchers.dart' as codegen_matchers; +-import 'codegen_protocol_constants.dart' as codegen_protocol_constants; +-import 'to_html.dart' as to_html; +- +-/** +- * Generate all targets. +- */ +-main() async { +- String script = Platform.script.toFilePath(windows: Platform.isWindows); +- String pkgPath = normalize(join(dirname(script), '..', '..')); +- await GeneratedContent.generateAll(pkgPath, allTargets); +-} +- +-/** +- * Get a list of all generated targets. +- */ +-List get allTargets { +- List targets = []; +- targets.add(codegen_analysis_server.target); +- targets.add(codegen_dart_protocol.target(false)); +- targets.add(codegen_java_types.targetDir); +- targets.add(codegen_inttest_methods.target); +- targets.add(codegen_matchers.target); +- targets.add(codegen_protocol_constants.target); +- targets.add(to_html.target); +- return targets; +-} +diff --git a/pkg/analysis_server/tool/spec/generate_files b/pkg/analysis_server/tool/spec/generate_files +deleted file mode 100755 +index df2802d1f82..00000000000 +--- a/pkg/analysis_server/tool/spec/generate_files ++++ /dev/null +@@ -1,61 +0,0 @@ +-#!/usr/bin/env bash +-# Copyright (c) 2014, 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. +-# +-# This script generates the following files, based on the contents of +-# spec_input.html: +-# +-# - ../../doc/api.html: The human-readable API spec. +-# +-# - ../../test/integration/protocol_matchers.dart: matchers to be used by +-# integration tests. +-# +-# - ../../test/integration/integration_test_methods.dart: convenience methods +-# to be used by integration tests. +- +-set -e +- +-function follow_links() { +- file="$1" +- while [ -h "$file" ]; do +- # On Mac OS, readlink -f doesn't work. +- file="$(readlink "$file")" +- done +- echo "$file" +-} +- +-# Unlike $0, $BASH_SOURCE points to the absolute path of this file. +-PROG_NAME="$(follow_links "$BASH_SOURCE")" +- +-SCRIPT_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" +- +-ROOT_DIR="$(cd "${SCRIPT_DIR}/../../../.." ; pwd -P)" +- +-if [[ $1 == '--arch' && $2 == 'x64' ]]; +-then +- DART_CONFIGURATION="ReleaseX64" +-elif [ -z "$DART_CONFIGURATION" ]; +-then +- DART_CONFIGURATION="ReleaseIA32" +-fi +- +-if [[ `uname` == 'Darwin' ]]; +-then +- BUILD_DIR="${ROOT_DIR}/xcodebuild/$DART_CONFIGURATION" +-fi +- +-PKG_FILE="${ROOT_DIR}/.packages" +-if [[ !(-e $PKG_FILE) ]]; +-then +- PKG_FILE="${ROOT_DIR}/.packages" +-fi +- +-DART="${BUILD_DIR}/dart-sdk/bin/dart" +- +-declare -a VM_OPTIONS +-VM_OPTIONS+=("--checked") +-VM_OPTIONS+=("--packages=${PKG_FILE}") +- +-cd "${SCRIPT_DIR}" +-"${DART}" "${VM_OPTIONS[@]}" "generate_all.dart" +diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java +deleted file mode 100644 +index 24ff37d8cc5..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java ++++ /dev/null +@@ -1,757 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package com.google.dart.server.generated; +- +-import com.google.dart.server.*; +-import org.dartlang.analysis.server.protocol.*; +- +-import java.util.List; +-import java.util.Map; +- +-/** +- * The interface {@code AnalysisServer} defines the behavior of objects that interface to an +- * analysis server. +- * +- * @coverage dart.server +- */ +-public interface AnalysisServer { +- +- /** +- * Add the given listener to the list of listeners that will receive notification when new +- * analysis results become available. +- * +- * @param listener the listener to be added +- */ +- public void addAnalysisServerListener(AnalysisServerListener listener); +- +- /** +- * Add the given listener to the list of listeners that will receive notification when the server +- * is not active +- * +- * @param listener the listener to be added +- */ +- public void addStatusListener(AnalysisServerStatusListener listener); +- +- /** +- * {@code analysis.getErrors} +- * +- * Return the errors associated with the given file. If the errors for the given file have not yet +- * been computed, or the most recently computed errors for the given file are out of date, then the +- * response for this request will be delayed until they have been computed. If some or all of the +- * errors for the file cannot be computed, then the subset of the errors that can be computed will +- * be returned and the response will contain an error to indicate why the errors could not be +- * computed. If the content of the file changes after this request was received but before a +- * response could be sent, then an error of type CONTENT_MODIFIED will be generated. +- * +- * This request is intended to be used by clients that cannot asynchronously apply updated error +- * information. Clients that can apply error information as it becomes available should use the +- * information provided by the 'analysis.errors' notification. +- * +- * If a request is made for a file which does not exist, or which is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified to +- * analysis.setAnalysisRoots), an error of type GET_ERRORS_INVALID_FILE will be generated. +- * +- * @param file The file for which errors are being requested. +- */ +- public void analysis_getErrors(String file, GetErrorsConsumer consumer); +- +- /** +- * {@code analysis.getHover} +- * +- * Return the hover information associate with the given location. If some or all of the hover +- * information is not available at the time this request is processed the information will be +- * omitted from the response. +- * +- * @param file The file in which hover information is being requested. +- * @param offset The offset for which hover information is being requested. +- */ +- public void analysis_getHover(String file, int offset, GetHoverConsumer consumer); +- +- /** +- * {@code analysis.getImportedElements} +- * +- * Return a description of all of the elements referenced in a given region of a given file that +- * come from imported libraries. +- * +- * If a request is made for a file that does not exist, or that is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified via +- * analysis.setAnalysisRoots), an error of type GET_IMPORTED_ELEMENTS_INVALID_FILE will be +- * generated. +- * +- * @param file The file in which import information is being requested. +- * @param offset The offset of the region for which import information is being requested. +- * @param length The length of the region for which import information is being requested. +- */ +- public void analysis_getImportedElements(String file, int offset, int length, GetImportedElementsConsumer consumer); +- +- /** +- * {@code analysis.getLibraryDependencies} +- * +- * Return library dependency information for use in client-side indexing and package URI +- * resolution. +- * +- * Clients that are only using the libraries field should consider using the analyzedFiles +- * notification instead. +- */ +- public void analysis_getLibraryDependencies(GetLibraryDependenciesConsumer consumer); +- +- /** +- * {@code analysis.getNavigation} +- * +- * Return the navigation information associated with the given region of the given file. If the +- * navigation information for the given file has not yet been computed, or the most recently +- * computed navigation information for the given file is out of date, then the response for this +- * request will be delayed until it has been computed. If the content of the file changes after +- * this request was received but before a response could be sent, then an error of type +- * CONTENT_MODIFIED will be generated. +- * +- * If a navigation region overlaps (but extends either before or after) the given region of the +- * file it will be included in the result. This means that it is theoretically possible to get the +- * same navigation region in response to multiple requests. Clients can avoid this by always +- * choosing a region that starts at the beginning of a line and ends at the end of a (possibly +- * different) line in the file. +- * +- * If a request is made for a file which does not exist, or which is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified to +- * analysis.setAnalysisRoots), an error of type GET_NAVIGATION_INVALID_FILE will be generated. +- * +- * @param file The file in which navigation information is being requested. +- * @param offset The offset of the region for which navigation information is being requested. +- * @param length The length of the region for which navigation information is being requested. +- */ +- public void analysis_getNavigation(String file, int offset, int length, GetNavigationConsumer consumer); +- +- /** +- * {@code analysis.getReachableSources} +- * +- * Return the transitive closure of reachable sources for a given file. +- * +- * If a request is made for a file which does not exist, or which is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified to +- * analysis.setAnalysisRoots), an error of type GET_REACHABLE_SOURCES_INVALID_FILE will be +- * generated. +- * +- * @param file The file for which reachable source information is being requested. +- */ +- public void analysis_getReachableSources(String file, GetReachableSourcesConsumer consumer); +- +- /** +- * {@code analysis.reanalyze} +- * +- * Force the re-analysis of everything contained in the specified analysis roots. This will cause +- * all previously computed analysis results to be discarded and recomputed, and will cause all +- * subscribed notifications to be re-sent. +- * +- * If no analysis roots are provided, then all current analysis roots will be re-analyzed. If an +- * empty list of analysis roots is provided, then nothing will be re-analyzed. If the list contains +- * one or more paths that are not currently analysis roots, then an error of type +- * INVALID_ANALYSIS_ROOT will be generated. +- * +- * @param roots A list of the analysis roots that are to be re-analyzed. +- */ +- public void analysis_reanalyze(List roots); +- +- /** +- * {@code analysis.setAnalysisRoots} +- * +- * Sets the root paths used to determine which files to analyze. The set of files to be analyzed +- * are all of the files in one of the root paths that are not either explicitly or implicitly +- * excluded. A file is explicitly excluded if it is in one of the excluded paths. A file is +- * implicitly excluded if it is in a subdirectory of one of the root paths where the name of the +- * subdirectory starts with a period (that is, a hidden directory). +- * +- * Note that this request determines the set of requested analysis roots. The actual set of +- * analysis roots at any given time is the intersection of this set with the set of files and +- * directories actually present on the filesystem. When the filesystem changes, the actual set of +- * analysis roots is automatically updated, but the set of requested analysis roots is unchanged. +- * This means that if the client sets an analysis root before the root becomes visible to server in +- * the filesystem, there is no error; once the server sees the root in the filesystem it will start +- * analyzing it. Similarly, server will stop analyzing files that are removed from the file system +- * but they will remain in the set of requested roots. +- * +- * If an included path represents a file, then server will look in the directory containing the +- * file for a pubspec.yaml file. If none is found, then the parents of the directory will be +- * searched until such a file is found or the root of the file system is reached. If such a file is +- * found, it will be used to resolve package: URI’s within the file. +- * +- * @param included A list of the files and directories that should be analyzed. +- * @param excluded A list of the files and directories within the included directories that should +- * not be analyzed. +- * @param packageRoots A mapping from source directories to package roots that should override the +- * normal package: URI resolution mechanism. If a package root is a directory, then the +- * analyzer will behave as though the associated source directory in the map contains a +- * special pubspec.yaml file which resolves any package: URI to the corresponding path +- * within that package root directory. The effect is the same as specifying the package +- * root directory as a "--package_root" parameter to the Dart VM when executing any Dart +- * file inside the source directory. If a package root is a file, then the analyzer will +- * behave as though that file is a ".packages" file in the source directory. The effect is +- * the same as specifying the file as a "--packages" parameter to the Dart VM when +- * executing any Dart file inside the source directory. Files in any directories that are +- * not overridden by this mapping have their package: URI's resolved using the normal +- * pubspec.yaml mechanism. If this field is absent, or the empty map is specified, that +- * indicates that the normal pubspec.yaml mechanism should always be used. +- */ +- public void analysis_setAnalysisRoots(List included, List excluded, Map packageRoots); +- +- /** +- * {@code analysis.setGeneralSubscriptions} +- * +- * Subscribe for general services (that is, services that are not specific to individual files). +- * All previous subscriptions are replaced by the given set of services. +- * +- * It is an error if any of the elements in the list are not valid services. If there is an error, +- * then the current subscriptions will remain unchanged. +- * +- * @param subscriptions A list of the services being subscribed to. +- */ +- public void analysis_setGeneralSubscriptions(List subscriptions); +- +- /** +- * {@code analysis.setPriorityFiles} +- * +- * Set the priority files to the files in the given list. A priority file is a file that is given +- * priority when scheduling which analysis work to do first. The list typically contains those +- * files that are visible to the user and those for which analysis results will have the biggest +- * impact on the user experience. The order of the files within the list is significant: the first +- * file will be given higher priority than the second, the second higher priority than the third, +- * and so on. +- * +- * Note that this request determines the set of requested priority files. The actual set of +- * priority files is the intersection of the requested set of priority files with the set of files +- * currently subject to analysis. (See analysis.setSubscriptions for a description of files that +- * are subject to analysis.) +- * +- * If a requested priority file is a directory it is ignored, but remains in the set of requested +- * priority files so that if it later becomes a file it can be included in the set of actual +- * priority files. +- * +- * @param files The files that are to be a priority for analysis. +- */ +- public void analysis_setPriorityFiles(List files); +- +- /** +- * {@code analysis.setSubscriptions} +- * +- * Subscribe for services that are specific to individual files. All previous subscriptions are +- * replaced by the current set of subscriptions. If a given service is not included as a key in the +- * map then no files will be subscribed to the service, exactly as if the service had been included +- * in the map with an explicit empty list of files. +- * +- * Note that this request determines the set of requested subscriptions. The actual set of +- * subscriptions at any given time is the intersection of this set with the set of files currently +- * subject to analysis. The files currently subject to analysis are the set of files contained +- * within an actual analysis root but not excluded, plus all of the files transitively reachable +- * from those files via import, export and part directives. (See analysis.setAnalysisRoots for an +- * explanation of how the actual analysis roots are determined.) When the actual analysis roots +- * change, the actual set of subscriptions is automatically updated, but the set of requested +- * subscriptions is unchanged. +- * +- * If a requested subscription is a directory it is ignored, but remains in the set of requested +- * subscriptions so that if it later becomes a file it can be included in the set of actual +- * subscriptions. +- * +- * It is an error if any of the keys in the map are not valid services. If there is an error, then +- * the existing subscriptions will remain unchanged. +- * +- * @param subscriptions A table mapping services to a list of the files being subscribed to the +- * service. +- */ +- public void analysis_setSubscriptions(Map> subscriptions); +- +- /** +- * {@code analysis.updateContent} +- * +- * Update the content of one or more files. Files that were previously updated but not included in +- * this update remain unchanged. This effectively represents an overlay of the filesystem. The +- * files whose content is overridden are therefore seen by server as being files with the given +- * content, even if the files do not exist on the filesystem or if the file path represents the +- * path to a directory on the filesystem. +- * +- * @param files A table mapping the files whose content has changed to a description of the content +- * change. +- */ +- public void analysis_updateContent(Map files, UpdateContentConsumer consumer); +- +- /** +- * {@code analysis.updateOptions} +- * +- * Deprecated: all of the options can be set by users in an analysis options file. +- * +- * Update the options controlling analysis based on the given set of options. Any options that are +- * not included in the analysis options will not be changed. If there are options in the analysis +- * options that are not valid, they will be silently ignored. +- * +- * @param options The options that are to be used to control analysis. +- * +- * @deprecated +- */ +- public void analysis_updateOptions(AnalysisOptions options); +- +- /** +- * {@code analytics.enable} +- * +- * Enable or disable the sending of analytics data. Note that there are other ways for users to +- * change this setting, so clients cannot assume that they have complete control over this setting. +- * In particular, there is no guarantee that the result returned by the isEnabled request will +- * match the last value set via this request. +- * +- * @param value Enable or disable analytics. +- */ +- public void analytics_enable(boolean value); +- +- /** +- * {@code analytics.isEnabled} +- * +- * Query whether analytics is enabled. +- * +- * This flag controls whether the analysis server sends any analytics data to the cloud. If +- * disabled, the analysis server does not send any analytics data, and any data sent to it by +- * clients (from sendEvent and sendTiming) will be ignored. +- * +- * The value of this flag can be changed by other tools outside of the analysis server's process. +- * When you query the flag, you get the value of the flag at a given moment. Clients should not use +- * the value returned to decide whether or not to send the sendEvent and sendTiming requests. Those +- * requests should be used unconditionally and server will determine whether or not it is +- * appropriate to forward the information to the cloud at the time each request is received. +- */ +- public void analytics_isEnabled(IsEnabledConsumer consumer); +- +- /** +- * {@code analytics.sendEvent} +- * +- * Send information about client events. +- * +- * Ask the analysis server to include the fact that an action was performed in the client as part +- * of the analytics data being sent. The data will only be included if the sending of analytics +- * data is enabled at the time the request is processed. The action that was performed is indicated +- * by the value of the action field. +- * +- * The value of the action field should not include the identity of the client. The analytics data +- * sent by server will include the client id passed in using the --client-id command-line argument. +- * The request will be ignored if the client id was not provided when server was started. +- * +- * @param action The value used to indicate which action was performed. +- */ +- public void analytics_sendEvent(String action); +- +- /** +- * {@code analytics.sendTiming} +- * +- * Send timing information for client events (e.g. code completions). +- * +- * Ask the analysis server to include the fact that a timed event occurred as part of the analytics +- * data being sent. The data will only be included if the sending of analytics data is enabled at +- * the time the request is processed. +- * +- * The value of the event field should not include the identity of the client. The analytics data +- * sent by server will include the client id passed in using the --client-id command-line argument. +- * The request will be ignored if the client id was not provided when server was started. +- * +- * @param event The name of the event. +- * @param millis The duration of the event in milliseconds. +- */ +- public void analytics_sendTiming(String event, int millis); +- +- /** +- * {@code completion.getSuggestions} +- * +- * Request that completion suggestions for the given offset in the given file be returned. +- * +- * @param file The file containing the point at which suggestions are to be made. +- * @param offset The offset within the file at which suggestions are to be made. +- */ +- public void completion_getSuggestions(String file, int offset, GetSuggestionsConsumer consumer); +- +- /** +- * {@code diagnostic.getDiagnostics} +- * +- * Return server diagnostics. +- */ +- public void diagnostic_getDiagnostics(GetDiagnosticsConsumer consumer); +- +- /** +- * {@code diagnostic.getServerPort} +- * +- * Return the port of the diagnostic web server. If the server is not running this call will start +- * the server. If unable to start the diagnostic web server, this call will return an error of +- * DEBUG_PORT_COULD_NOT_BE_OPENED. +- */ +- public void diagnostic_getServerPort(GetServerPortConsumer consumer); +- +- /** +- * {@code edit.format} +- * +- * Format the contents of a single file. The currently selected region of text is passed in so that +- * the selection can be preserved across the formatting operation. The updated selection will be as +- * close to matching the original as possible, but whitespace at the beginning or end of the +- * selected region will be ignored. If preserving selection information is not required, zero (0) +- * can be specified for both the selection offset and selection length. +- * +- * If a request is made for a file which does not exist, or which is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified to +- * analysis.setAnalysisRoots), an error of type FORMAT_INVALID_FILE will be generated. If the +- * source contains syntax errors, an error of type FORMAT_WITH_ERRORS will be generated. +- * +- * @param file The file containing the code to be formatted. +- * @param selectionOffset The offset of the current selection in the file. +- * @param selectionLength The length of the current selection in the file. +- * @param lineLength The line length to be used by the formatter. +- */ +- public void edit_format(String file, int selectionOffset, int selectionLength, int lineLength, FormatConsumer consumer); +- +- /** +- * {@code edit.getAssists} +- * +- * Return the set of assists that are available at the given location. An assist is distinguished +- * from a refactoring primarily by the fact that it affects a single file and does not require user +- * input in order to be performed. +- * +- * @param file The file containing the code for which assists are being requested. +- * @param offset The offset of the code for which assists are being requested. +- * @param length The length of the code for which assists are being requested. +- */ +- public void edit_getAssists(String file, int offset, int length, GetAssistsConsumer consumer); +- +- /** +- * {@code edit.getAvailableRefactorings} +- * +- * Get a list of the kinds of refactorings that are valid for the given selection in the given +- * file. +- * +- * @param file The file containing the code on which the refactoring would be based. +- * @param offset The offset of the code on which the refactoring would be based. +- * @param length The length of the code on which the refactoring would be based. +- */ +- public void edit_getAvailableRefactorings(String file, int offset, int length, GetAvailableRefactoringsConsumer consumer); +- +- /** +- * {@code edit.getFixes} +- * +- * Return the set of fixes that are available for the errors at a given offset in a given file. +- * +- * @param file The file containing the errors for which fixes are being requested. +- * @param offset The offset used to select the errors for which fixes will be returned. +- */ +- public void edit_getFixes(String file, int offset, GetFixesConsumer consumer); +- +- /** +- * {@code edit.getPostfixCompletion} +- * +- * Get the changes required to convert the postfix template at the given location into the +- * template's expanded form. +- * +- * @param file The file containing the postfix template to be expanded. +- * @param key The unique name that identifies the template in use. +- * @param offset The offset used to identify the code to which the template will be applied. +- */ +- public void edit_getPostfixCompletion(String file, String key, int offset, GetPostfixCompletionConsumer consumer); +- +- /** +- * {@code edit.getRefactoring} +- * +- * Get the changes required to perform a refactoring. +- * +- * If another refactoring request is received during the processing of this one, an error of type +- * REFACTORING_REQUEST_CANCELLED will be generated. +- * +- * @param kind The kind of refactoring to be performed. +- * @param file The file containing the code involved in the refactoring. +- * @param offset The offset of the region involved in the refactoring. +- * @param length The length of the region involved in the refactoring. +- * @param validateOnly True if the client is only requesting that the values of the options be +- * validated and no change be generated. +- * @param options Data used to provide values provided by the user. The structure of the data is +- * dependent on the kind of refactoring being performed. The data that is expected is +- * documented in the section titled Refactorings, labeled as "Options". This field can be +- * omitted if the refactoring does not require any options or if the values of those +- * options are not known. +- */ +- public void edit_getRefactoring(String kind, String file, int offset, int length, boolean validateOnly, RefactoringOptions options, GetRefactoringConsumer consumer); +- +- /** +- * {@code edit.getStatementCompletion} +- * +- * Get the changes required to convert the partial statement at the given location into a +- * syntactically valid statement. If the current statement is already valid the change will insert +- * a newline plus appropriate indentation at the end of the line containing the offset. If a change +- * that makes the statement valid cannot be determined (perhaps because it has not yet been +- * implemented) the statement will be considered already valid and the appropriate change returned. +- * +- * @param file The file containing the statement to be completed. +- * @param offset The offset used to identify the statement to be completed. +- */ +- public void edit_getStatementCompletion(String file, int offset, GetStatementCompletionConsumer consumer); +- +- /** +- * {@code edit.importElements} +- * +- * Return a list of edits that would need to be applied in order to ensure that all of the elements +- * in the specified list of imported elements are accessible within the library. +- * +- * If a request is made for a file that does not exist, or that is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified via +- * analysis.setAnalysisRoots), an error of type IMPORT_ELEMENTS_INVALID_FILE will be generated. +- * +- * @param file The file in which the specified elements are to be made accessible. +- * @param elements The elements to be made accessible in the specified file. +- */ +- public void edit_importElements(String file, List elements, ImportElementsConsumer consumer); +- +- /** +- * {@code edit.isPostfixCompletionApplicable} +- * +- * Determine if the request postfix completion template is applicable at the given location in the +- * given file. +- * +- * @param file The file containing the postfix template to be expanded. +- * @param key The unique name that identifies the template in use. +- * @param offset The offset used to identify the code to which the template will be applied. +- */ +- public void edit_isPostfixCompletionApplicable(String file, String key, int offset, IsPostfixCompletionApplicableConsumer consumer); +- +- /** +- * {@code edit.listPostfixCompletionTemplates} +- * +- * Return a list of all postfix templates currently available. +- */ +- public void edit_listPostfixCompletionTemplates(ListPostfixCompletionTemplatesConsumer consumer); +- +- /** +- * {@code edit.organizeDirectives} +- * +- * Organizes all of the directives - removes unused imports and sorts directives of the given Dart +- * file according to the Dart Style Guide. +- * +- * If a request is made for a file that does not exist, does not belong to an analysis root or is +- * not a Dart file, FILE_NOT_ANALYZED will be generated. +- * +- * If directives of the Dart file cannot be organized, for example because it has scan or parse +- * errors, or by other reasons, ORGANIZE_DIRECTIVES_ERROR will be generated. The message will +- * provide details about the reason. +- * +- * @param file The Dart file to organize directives in. +- */ +- public void edit_organizeDirectives(String file, OrganizeDirectivesConsumer consumer); +- +- /** +- * {@code edit.sortMembers} +- * +- * Sort all of the directives, unit and class members of the given Dart file. +- * +- * If a request is made for a file that does not exist, does not belong to an analysis root or is +- * not a Dart file, SORT_MEMBERS_INVALID_FILE will be generated. +- * +- * If the Dart file has scan or parse errors, SORT_MEMBERS_PARSE_ERRORS will be generated. +- * +- * @param file The Dart file to sort. +- */ +- public void edit_sortMembers(String file, SortMembersConsumer consumer); +- +- /** +- * {@code execution.createContext} +- * +- * Create an execution context for the executable file with the given path. The context that is +- * created will persist until execution.deleteContext is used to delete it. Clients, therefore, are +- * responsible for managing the lifetime of execution contexts. +- * +- * @param contextRoot The path of the Dart or HTML file that will be launched, or the path of the +- * directory containing the file. +- */ +- public void execution_createContext(String contextRoot, CreateContextConsumer consumer); +- +- /** +- * {@code execution.deleteContext} +- * +- * Delete the execution context with the given identifier. The context id is no longer valid after +- * this command. The server is allowed to re-use ids when they are no longer valid. +- * +- * @param id The identifier of the execution context that is to be deleted. +- */ +- public void execution_deleteContext(String id); +- +- /** +- * {@code execution.mapUri} +- * +- * Map a URI from the execution context to the file that it corresponds to, or map a file to the +- * URI that it corresponds to in the execution context. +- * +- * Exactly one of the file and uri fields must be provided. If both fields are provided, then an +- * error of type INVALID_PARAMETER will be generated. Similarly, if neither field is provided, then +- * an error of type INVALID_PARAMETER will be generated. +- * +- * If the file field is provided and the value is not the path of a file (either the file does not +- * exist or the path references something other than a file), then an error of type +- * INVALID_PARAMETER will be generated. +- * +- * If the uri field is provided and the value is not a valid URI or if the URI references something +- * that is not a file (either a file that does not exist or something other than a file), then an +- * error of type INVALID_PARAMETER will be generated. +- * +- * If the contextRoot used to create the execution context does not exist, then an error of type +- * INVALID_EXECUTION_CONTEXT will be generated. +- * +- * @param id The identifier of the execution context in which the URI is to be mapped. +- * @param file The path of the file to be mapped into a URI. +- * @param uri The URI to be mapped into a file path. +- */ +- public void execution_mapUri(String id, String file, String uri, MapUriConsumer consumer); +- +- /** +- * {@code execution.setSubscriptions} +- * +- * Deprecated: the analysis server no longer fires LAUNCH_DATA events. +- * +- * Subscribe for services. All previous subscriptions are replaced by the given set of services. +- * +- * It is an error if any of the elements in the list are not valid services. If there is an error, +- * then the current subscriptions will remain unchanged. +- * +- * @param subscriptions A list of the services being subscribed to. +- * +- * @deprecated +- */ +- public void execution_setSubscriptions(List subscriptions); +- +- /** +- * Return {@code true} if the socket is open. +- */ +- public boolean isSocketOpen(); +- +- /** +- * {@code kythe.getKytheEntries} +- * +- * Return the list of KytheEntry objects for some file, given the current state of the file system +- * populated by "analysis.updateContent". +- * +- * If a request is made for a file that does not exist, or that is not currently subject to +- * analysis (e.g. because it is not associated with any analysis root specified to +- * analysis.setAnalysisRoots), an error of type GET_KYTHE_ENTRIES_INVALID_FILE will be generated. +- * +- * @param file The file containing the code for which the Kythe Entry objects are being requested. +- */ +- public void kythe_getKytheEntries(String file, GetKytheEntriesConsumer consumer); +- +- /** +- * Remove the given listener from the list of listeners that will receive notification when new +- * analysis results become available. +- * +- * @param listener the listener to be removed +- */ +- public void removeAnalysisServerListener(AnalysisServerListener listener); +- +- /** +- * {@code search.findElementReferences} +- * +- * Perform a search for references to the element defined or referenced at the given offset in the +- * given file. +- * +- * An identifier is returned immediately, and individual results will be returned via the +- * search.results notification as they become available. +- * +- * @param file The file containing the declaration of or reference to the element used to define +- * the search. +- * @param offset The offset within the file of the declaration of or reference to the element. +- * @param includePotential True if potential matches are to be included in the results. +- */ +- public void search_findElementReferences(String file, int offset, boolean includePotential, FindElementReferencesConsumer consumer); +- +- /** +- * {@code search.findMemberDeclarations} +- * +- * Perform a search for declarations of members whose name is equal to the given name. +- * +- * An identifier is returned immediately, and individual results will be returned via the +- * search.results notification as they become available. +- * +- * @param name The name of the declarations to be found. +- */ +- public void search_findMemberDeclarations(String name, FindMemberDeclarationsConsumer consumer); +- +- /** +- * {@code search.findMemberReferences} +- * +- * Perform a search for references to members whose name is equal to the given name. This search +- * does not check to see that there is a member defined with the given name, so it is able to find +- * references to undefined members as well. +- * +- * An identifier is returned immediately, and individual results will be returned via the +- * search.results notification as they become available. +- * +- * @param name The name of the references to be found. +- */ +- public void search_findMemberReferences(String name, FindMemberReferencesConsumer consumer); +- +- /** +- * {@code search.findTopLevelDeclarations} +- * +- * Perform a search for declarations of top-level elements (classes, typedefs, getters, setters, +- * functions and fields) whose name matches the given pattern. +- * +- * An identifier is returned immediately, and individual results will be returned via the +- * search.results notification as they become available. +- * +- * @param pattern The regular expression used to match the names of the declarations to be found. +- */ +- public void search_findTopLevelDeclarations(String pattern, FindTopLevelDeclarationsConsumer consumer); +- +- /** +- * {@code search.getTypeHierarchy} +- * +- * Return the type hierarchy of the class declared or referenced at the given location. +- * +- * @param file The file containing the declaration or reference to the type for which a hierarchy +- * is being requested. +- * @param offset The offset of the name of the type within the file. +- * @param superOnly True if the client is only requesting superclasses and interfaces hierarchy. +- */ +- public void search_getTypeHierarchy(String file, int offset, boolean superOnly, GetTypeHierarchyConsumer consumer); +- +- /** +- * {@code server.getVersion} +- * +- * Return the version number of the analysis server. +- */ +- public void server_getVersion(GetVersionConsumer consumer); +- +- /** +- * {@code server.setSubscriptions} +- * +- * Subscribe for services. All previous subscriptions are replaced by the given set of services. +- * +- * It is an error if any of the elements in the list are not valid services. If there is an error, +- * then the current subscriptions will remain unchanged. +- * +- * @param subscriptions A list of the services being subscribed to. +- */ +- public void server_setSubscriptions(List subscriptions); +- +- /** +- * {@code server.shutdown} +- * +- * Cleanly shutdown the analysis server. Requests that are received after this request will not be +- * processed. Requests that were received before this request, but for which a response has not yet +- * been sent, will not be responded to. No further responses or notifications will be sent after +- * the response to this request has been sent. +- */ +- public void server_shutdown(); +- +- /** +- * Start the analysis server. +- */ +- public void start() throws Exception; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java +deleted file mode 100644 +index 74249cad5b0..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AddContentOverlay.java ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A directive to begin overlaying the contents of a file. The supplied content will be used for +- * analysis in place of the file contents in the filesystem. +- * +- * If this directive is used on a file that already has a file content overlay, the old overlay is +- * discarded and replaced with the new one. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class AddContentOverlay { +- +- public static final AddContentOverlay[] EMPTY_ARRAY = new AddContentOverlay[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- private final String type; +- +- /** +- * The new content of the file. +- */ +- private final String content; +- +- /** +- * Constructor for {@link AddContentOverlay}. +- */ +- public AddContentOverlay(String content) { +- this.type = "add"; +- this.content = content; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof AddContentOverlay) { +- AddContentOverlay other = (AddContentOverlay) obj; +- return +- ObjectUtilities.equals(other.type, type) && +- ObjectUtilities.equals(other.content, content); +- } +- return false; +- } +- +- public static AddContentOverlay fromJson(JsonObject jsonObject) { +- String type = jsonObject.get("type").getAsString(); +- String content = jsonObject.get("content").getAsString(); +- return new AddContentOverlay(content); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The new content of the file. +- */ +- public String getContent() { +- return content; +- } +- +- public String getType() { +- return type; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(type); +- builder.append(content); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("type", type); +- jsonObject.addProperty("content", content); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("type="); +- builder.append(type + ", "); +- builder.append("content="); +- builder.append(content); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java +deleted file mode 100644 +index 00c44959aed..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java ++++ /dev/null +@@ -1,251 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An indication of an error, warning, or hint that was produced by the analysis. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class AnalysisError { +- +- public static final AnalysisError[] EMPTY_ARRAY = new AnalysisError[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The severity of the error. +- */ +- private final String severity; +- +- /** +- * The type of the error. +- */ +- private final String type; +- +- /** +- * The location associated with the error. +- */ +- private final Location location; +- +- /** +- * The message to be displayed for this error. The message should indicate what is wrong with the +- * code and why it is wrong. +- */ +- private final String message; +- +- /** +- * The correction message to be displayed for this error. The correction message should indicate +- * how the user can fix the error. The field is omitted if there is no correction message +- * associated with the error code. +- */ +- private final String correction; +- +- /** +- * The name, as a string, of the error code associated with this error. +- */ +- private final String code; +- +- /** +- * A hint to indicate to interested clients that this error has an associated fix (or fixes). The +- * absence of this field implies there are not known to be fixes. Note that since the operation to +- * calculate whether fixes apply needs to be performant it is possible that complicated tests will +- * be skipped and a false negative returned. For this reason, this attribute should be treated as a +- * "hint". Despite the possibility of false negatives, no false positives should be returned. If a +- * client sees this flag set they can proceed with the confidence that there are in fact associated +- * fixes. +- */ +- private final Boolean hasFix; +- +- /** +- * Constructor for {@link AnalysisError}. +- */ +- public AnalysisError(String severity, String type, Location location, String message, String correction, String code, Boolean hasFix) { +- this.severity = severity; +- this.type = type; +- this.location = location; +- this.message = message; +- this.correction = correction; +- this.code = code; +- this.hasFix = hasFix; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof AnalysisError) { +- AnalysisError other = (AnalysisError) obj; +- return +- ObjectUtilities.equals(other.severity, severity) && +- ObjectUtilities.equals(other.type, type) && +- ObjectUtilities.equals(other.location, location) && +- ObjectUtilities.equals(other.message, message) && +- ObjectUtilities.equals(other.correction, correction) && +- ObjectUtilities.equals(other.code, code) && +- ObjectUtilities.equals(other.hasFix, hasFix); +- } +- return false; +- } +- +- public static AnalysisError fromJson(JsonObject jsonObject) { +- String severity = jsonObject.get("severity").getAsString(); +- String type = jsonObject.get("type").getAsString(); +- Location location = Location.fromJson(jsonObject.get("location").getAsJsonObject()); +- String message = jsonObject.get("message").getAsString(); +- String correction = jsonObject.get("correction") == null ? null : jsonObject.get("correction").getAsString(); +- String code = jsonObject.get("code").getAsString(); +- Boolean hasFix = jsonObject.get("hasFix") == null ? null : jsonObject.get("hasFix").getAsBoolean(); +- return new AnalysisError(severity, type, location, message, correction, code, hasFix); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The name, as a string, of the error code associated with this error. +- */ +- public String getCode() { +- return code; +- } +- +- /** +- * The correction message to be displayed for this error. The correction message should indicate +- * how the user can fix the error. The field is omitted if there is no correction message +- * associated with the error code. +- */ +- public String getCorrection() { +- return correction; +- } +- +- /** +- * A hint to indicate to interested clients that this error has an associated fix (or fixes). The +- * absence of this field implies there are not known to be fixes. Note that since the operation to +- * calculate whether fixes apply needs to be performant it is possible that complicated tests will +- * be skipped and a false negative returned. For this reason, this attribute should be treated as a +- * "hint". Despite the possibility of false negatives, no false positives should be returned. If a +- * client sees this flag set they can proceed with the confidence that there are in fact associated +- * fixes. +- */ +- public Boolean getHasFix() { +- return hasFix; +- } +- +- /** +- * The location associated with the error. +- */ +- public Location getLocation() { +- return location; +- } +- +- /** +- * The message to be displayed for this error. The message should indicate what is wrong with the +- * code and why it is wrong. +- */ +- public String getMessage() { +- return message; +- } +- +- /** +- * The severity of the error. +- */ +- public String getSeverity() { +- return severity; +- } +- +- /** +- * The type of the error. +- */ +- public String getType() { +- return type; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(severity); +- builder.append(type); +- builder.append(location); +- builder.append(message); +- builder.append(correction); +- builder.append(code); +- builder.append(hasFix); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("severity", severity); +- jsonObject.addProperty("type", type); +- jsonObject.add("location", location.toJson()); +- jsonObject.addProperty("message", message); +- if (correction != null) { +- jsonObject.addProperty("correction", correction); +- } +- jsonObject.addProperty("code", code); +- if (hasFix != null) { +- jsonObject.addProperty("hasFix", hasFix); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("severity="); +- builder.append(severity + ", "); +- builder.append("type="); +- builder.append(type + ", "); +- builder.append("location="); +- builder.append(location + ", "); +- builder.append("message="); +- builder.append(message + ", "); +- builder.append("correction="); +- builder.append(correction + ", "); +- builder.append("code="); +- builder.append(code + ", "); +- builder.append("hasFix="); +- builder.append(hasFix); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java +deleted file mode 100644 +index a45caa1a2ce..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorFixes.java ++++ /dev/null +@@ -1,138 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A list of fixes associated with a specific error. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class AnalysisErrorFixes { +- +- public static final AnalysisErrorFixes[] EMPTY_ARRAY = new AnalysisErrorFixes[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The error with which the fixes are associated. +- */ +- private final AnalysisError error; +- +- /** +- * The fixes associated with the error. +- */ +- private final List fixes; +- +- /** +- * Constructor for {@link AnalysisErrorFixes}. +- */ +- public AnalysisErrorFixes(AnalysisError error, List fixes) { +- this.error = error; +- this.fixes = fixes; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof AnalysisErrorFixes) { +- AnalysisErrorFixes other = (AnalysisErrorFixes) obj; +- return +- ObjectUtilities.equals(other.error, error) && +- ObjectUtilities.equals(other.fixes, fixes); +- } +- return false; +- } +- +- public static AnalysisErrorFixes fromJson(JsonObject jsonObject) { +- AnalysisError error = AnalysisError.fromJson(jsonObject.get("error").getAsJsonObject()); +- List fixes = SourceChange.fromJsonArray(jsonObject.get("fixes").getAsJsonArray()); +- return new AnalysisErrorFixes(error, fixes); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The error with which the fixes are associated. +- */ +- public AnalysisError getError() { +- return error; +- } +- +- /** +- * The fixes associated with the error. +- */ +- public List getFixes() { +- return fixes; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(error); +- builder.append(fixes); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.add("error", error.toJson()); +- JsonArray jsonArrayFixes = new JsonArray(); +- for (SourceChange elt : fixes) { +- jsonArrayFixes.add(elt.toJson()); +- } +- jsonObject.add("fixes", jsonArrayFixes); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("error="); +- builder.append(error + ", "); +- builder.append("fixes="); +- builder.append(StringUtils.join(fixes, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java +deleted file mode 100644 +index e07df408f3b..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorSeverity.java ++++ /dev/null +@@ -1,32 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the possible severities of analysis errors. +- * +- * @coverage dart.server.generated.types +- */ +-public class AnalysisErrorSeverity { +- +- public static final String INFO = "INFO"; +- +- public static final String WARNING = "WARNING"; +- +- public static final String ERROR = "ERROR"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java +deleted file mode 100644 +index db6fe7669de..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisErrorType.java ++++ /dev/null +@@ -1,42 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the possible types of analysis errors. +- * +- * @coverage dart.server.generated.types +- */ +-public class AnalysisErrorType { +- +- public static final String CHECKED_MODE_COMPILE_TIME_ERROR = "CHECKED_MODE_COMPILE_TIME_ERROR"; +- +- public static final String COMPILE_TIME_ERROR = "COMPILE_TIME_ERROR"; +- +- public static final String HINT = "HINT"; +- +- public static final String LINT = "LINT"; +- +- public static final String STATIC_TYPE_WARNING = "STATIC_TYPE_WARNING"; +- +- public static final String STATIC_WARNING = "STATIC_WARNING"; +- +- public static final String SYNTACTIC_ERROR = "SYNTACTIC_ERROR"; +- +- public static final String TODO = "TODO"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java +deleted file mode 100644 +index 12f2cbc0cb2..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java ++++ /dev/null +@@ -1,287 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * Deprecated: the only reference to this type has been deprecated. +- * +- * A set of options controlling what kind of analysis is to be performed. If the value of a field +- * is omitted the value of the option will not be changed. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class AnalysisOptions { +- +- public static final AnalysisOptions[] EMPTY_ARRAY = new AnalysisOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed async feature. +- */ +- private final Boolean enableAsync; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed deferred loading feature. +- */ +- private final Boolean enableDeferredLoading; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed enum feature. +- */ +- private final Boolean enableEnums; +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed "null aware operators" feature. +- */ +- private final Boolean enableNullAwareOperators; +- +- /** +- * True if the client wants to enable support for the proposed "less restricted mixins" proposal +- * (DEP 34). +- */ +- private final Boolean enableSuperMixins; +- +- /** +- * True if hints that are specific to dart2js should be generated. This option is ignored if +- * generateHints is false. +- */ +- private final Boolean generateDart2jsHints; +- +- /** +- * True if hints should be generated as part of generating errors and warnings. +- */ +- private final Boolean generateHints; +- +- /** +- * True if lints should be generated as part of generating errors and warnings. +- */ +- private final Boolean generateLints; +- +- /** +- * Constructor for {@link AnalysisOptions}. +- */ +- public AnalysisOptions(Boolean enableAsync, Boolean enableDeferredLoading, Boolean enableEnums, Boolean enableNullAwareOperators, Boolean enableSuperMixins, Boolean generateDart2jsHints, Boolean generateHints, Boolean generateLints) { +- this.enableAsync = enableAsync; +- this.enableDeferredLoading = enableDeferredLoading; +- this.enableEnums = enableEnums; +- this.enableNullAwareOperators = enableNullAwareOperators; +- this.enableSuperMixins = enableSuperMixins; +- this.generateDart2jsHints = generateDart2jsHints; +- this.generateHints = generateHints; +- this.generateLints = generateLints; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof AnalysisOptions) { +- AnalysisOptions other = (AnalysisOptions) obj; +- return +- ObjectUtilities.equals(other.enableAsync, enableAsync) && +- ObjectUtilities.equals(other.enableDeferredLoading, enableDeferredLoading) && +- ObjectUtilities.equals(other.enableEnums, enableEnums) && +- ObjectUtilities.equals(other.enableNullAwareOperators, enableNullAwareOperators) && +- ObjectUtilities.equals(other.enableSuperMixins, enableSuperMixins) && +- ObjectUtilities.equals(other.generateDart2jsHints, generateDart2jsHints) && +- ObjectUtilities.equals(other.generateHints, generateHints) && +- ObjectUtilities.equals(other.generateLints, generateLints); +- } +- return false; +- } +- +- public static AnalysisOptions fromJson(JsonObject jsonObject) { +- Boolean enableAsync = jsonObject.get("enableAsync") == null ? null : jsonObject.get("enableAsync").getAsBoolean(); +- Boolean enableDeferredLoading = jsonObject.get("enableDeferredLoading") == null ? null : jsonObject.get("enableDeferredLoading").getAsBoolean(); +- Boolean enableEnums = jsonObject.get("enableEnums") == null ? null : jsonObject.get("enableEnums").getAsBoolean(); +- Boolean enableNullAwareOperators = jsonObject.get("enableNullAwareOperators") == null ? null : jsonObject.get("enableNullAwareOperators").getAsBoolean(); +- Boolean enableSuperMixins = jsonObject.get("enableSuperMixins") == null ? null : jsonObject.get("enableSuperMixins").getAsBoolean(); +- Boolean generateDart2jsHints = jsonObject.get("generateDart2jsHints") == null ? null : jsonObject.get("generateDart2jsHints").getAsBoolean(); +- Boolean generateHints = jsonObject.get("generateHints") == null ? null : jsonObject.get("generateHints").getAsBoolean(); +- Boolean generateLints = jsonObject.get("generateLints") == null ? null : jsonObject.get("generateLints").getAsBoolean(); +- return new AnalysisOptions(enableAsync, enableDeferredLoading, enableEnums, enableNullAwareOperators, enableSuperMixins, generateDart2jsHints, generateHints, generateLints); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed async feature. +- */ +- public Boolean getEnableAsync() { +- return enableAsync; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed deferred loading feature. +- */ +- public Boolean getEnableDeferredLoading() { +- return enableDeferredLoading; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed enum feature. +- */ +- public Boolean getEnableEnums() { +- return enableEnums; +- } +- +- /** +- * Deprecated: this feature is always enabled. +- * +- * True if the client wants to enable support for the proposed "null aware operators" feature. +- */ +- public Boolean getEnableNullAwareOperators() { +- return enableNullAwareOperators; +- } +- +- /** +- * True if the client wants to enable support for the proposed "less restricted mixins" proposal +- * (DEP 34). +- */ +- public Boolean getEnableSuperMixins() { +- return enableSuperMixins; +- } +- +- /** +- * True if hints that are specific to dart2js should be generated. This option is ignored if +- * generateHints is false. +- */ +- public Boolean getGenerateDart2jsHints() { +- return generateDart2jsHints; +- } +- +- /** +- * True if hints should be generated as part of generating errors and warnings. +- */ +- public Boolean getGenerateHints() { +- return generateHints; +- } +- +- /** +- * True if lints should be generated as part of generating errors and warnings. +- */ +- public Boolean getGenerateLints() { +- return generateLints; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(enableAsync); +- builder.append(enableDeferredLoading); +- builder.append(enableEnums); +- builder.append(enableNullAwareOperators); +- builder.append(enableSuperMixins); +- builder.append(generateDart2jsHints); +- builder.append(generateHints); +- builder.append(generateLints); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- if (enableAsync != null) { +- jsonObject.addProperty("enableAsync", enableAsync); +- } +- if (enableDeferredLoading != null) { +- jsonObject.addProperty("enableDeferredLoading", enableDeferredLoading); +- } +- if (enableEnums != null) { +- jsonObject.addProperty("enableEnums", enableEnums); +- } +- if (enableNullAwareOperators != null) { +- jsonObject.addProperty("enableNullAwareOperators", enableNullAwareOperators); +- } +- if (enableSuperMixins != null) { +- jsonObject.addProperty("enableSuperMixins", enableSuperMixins); +- } +- if (generateDart2jsHints != null) { +- jsonObject.addProperty("generateDart2jsHints", generateDart2jsHints); +- } +- if (generateHints != null) { +- jsonObject.addProperty("generateHints", generateHints); +- } +- if (generateLints != null) { +- jsonObject.addProperty("generateLints", generateLints); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("enableAsync="); +- builder.append(enableAsync + ", "); +- builder.append("enableDeferredLoading="); +- builder.append(enableDeferredLoading + ", "); +- builder.append("enableEnums="); +- builder.append(enableEnums + ", "); +- builder.append("enableNullAwareOperators="); +- builder.append(enableNullAwareOperators + ", "); +- builder.append("enableSuperMixins="); +- builder.append(enableSuperMixins + ", "); +- builder.append("generateDart2jsHints="); +- builder.append(generateDart2jsHints + ", "); +- builder.append("generateHints="); +- builder.append(generateHints + ", "); +- builder.append("generateLints="); +- builder.append(generateLints); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java +deleted file mode 100644 +index bd8579170a3..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisService.java ++++ /dev/null +@@ -1,49 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the services provided by the analysis domain that are related to a specific +- * list of files. +- * +- * @coverage dart.server.generated.types +- */ +-public class AnalysisService { +- +- public static final String CLOSING_LABELS = "CLOSING_LABELS"; +- +- public static final String FOLDING = "FOLDING"; +- +- public static final String HIGHLIGHTS = "HIGHLIGHTS"; +- +- public static final String IMPLEMENTED = "IMPLEMENTED"; +- +- /** +- * This service is not currently implemented and will become a GeneralAnalysisService in a future +- * release. +- */ +- public static final String INVALIDATE = "INVALIDATE"; +- +- public static final String NAVIGATION = "NAVIGATION"; +- +- public static final String OCCURRENCES = "OCCURRENCES"; +- +- public static final String OUTLINE = "OUTLINE"; +- +- public static final String OVERRIDES = "OVERRIDES"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java +deleted file mode 100644 +index 1a0cb7fa56f..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisStatus.java ++++ /dev/null +@@ -1,136 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An indication of the current state of analysis. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class AnalysisStatus { +- +- public static final AnalysisStatus[] EMPTY_ARRAY = new AnalysisStatus[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * True if analysis is currently being performed. +- */ +- private final boolean isAnalyzing; +- +- /** +- * The name of the current target of analysis. This field is omitted if analyzing is false. +- */ +- private final String analysisTarget; +- +- /** +- * Constructor for {@link AnalysisStatus}. +- */ +- public AnalysisStatus(boolean isAnalyzing, String analysisTarget) { +- this.isAnalyzing = isAnalyzing; +- this.analysisTarget = analysisTarget; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof AnalysisStatus) { +- AnalysisStatus other = (AnalysisStatus) obj; +- return +- other.isAnalyzing == isAnalyzing && +- ObjectUtilities.equals(other.analysisTarget, analysisTarget); +- } +- return false; +- } +- +- public static AnalysisStatus fromJson(JsonObject jsonObject) { +- boolean isAnalyzing = jsonObject.get("isAnalyzing").getAsBoolean(); +- String analysisTarget = jsonObject.get("analysisTarget") == null ? null : jsonObject.get("analysisTarget").getAsString(); +- return new AnalysisStatus(isAnalyzing, analysisTarget); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The name of the current target of analysis. This field is omitted if analyzing is false. +- */ +- public String getAnalysisTarget() { +- return analysisTarget; +- } +- +- /** +- * True if analysis is currently being performed. +- */ +- public boolean isAnalyzing() { +- return isAnalyzing; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(isAnalyzing); +- builder.append(analysisTarget); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("isAnalyzing", isAnalyzing); +- if (analysisTarget != null) { +- jsonObject.addProperty("analysisTarget", analysisTarget); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("isAnalyzing="); +- builder.append(isAnalyzing + ", "); +- builder.append("analysisTarget="); +- builder.append(analysisTarget); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java +deleted file mode 100644 +index e7b4062b3bd..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ChangeContentOverlay.java ++++ /dev/null +@@ -1,142 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A directive to modify an existing file content overlay. One or more ranges of text are deleted +- * from the old file content overlay and replaced with new text. +- * +- * The edits are applied in the order in which they occur in the list. This means that the offset +- * of each edit must be correct under the assumption that all previous edits have been applied. +- * +- * It is an error to use this overlay on a file that does not yet have a file content overlay or +- * that has had its overlay removed via RemoveContentOverlay. +- * +- * If any of the edits cannot be applied due to its offset or length being out of range, an +- * INVALID_OVERLAY_CHANGE error will be reported. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ChangeContentOverlay { +- +- public static final ChangeContentOverlay[] EMPTY_ARRAY = new ChangeContentOverlay[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- private final String type; +- +- /** +- * The edits to be applied to the file. +- */ +- private final List edits; +- +- /** +- * Constructor for {@link ChangeContentOverlay}. +- */ +- public ChangeContentOverlay(List edits) { +- this.type = "change"; +- this.edits = edits; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ChangeContentOverlay) { +- ChangeContentOverlay other = (ChangeContentOverlay) obj; +- return +- ObjectUtilities.equals(other.type, type) && +- ObjectUtilities.equals(other.edits, edits); +- } +- return false; +- } +- +- public static ChangeContentOverlay fromJson(JsonObject jsonObject) { +- String type = jsonObject.get("type").getAsString(); +- List edits = SourceEdit.fromJsonArray(jsonObject.get("edits").getAsJsonArray()); +- return new ChangeContentOverlay(edits); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The edits to be applied to the file. +- */ +- public List getEdits() { +- return edits; +- } +- +- public String getType() { +- return type; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(type); +- builder.append(edits); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("type", type); +- JsonArray jsonArrayEdits = new JsonArray(); +- for (SourceEdit elt : edits) { +- jsonArrayEdits.add(elt.toJson()); +- } +- jsonObject.add("edits", jsonArrayEdits); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("type="); +- builder.append(type + ", "); +- builder.append("edits="); +- builder.append(StringUtils.join(edits, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java b/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java +deleted file mode 100644 +index 4cf5979bbd9..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ClosingLabel.java ++++ /dev/null +@@ -1,156 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A label that is associated with a range of code that may be useful to render at the end of the +- * range to aid code readability. For example, a constructor call that spans multiple lines may +- * result in a closing label to allow the constructor type/name to be rendered alongside the +- * closing parenthesis. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ClosingLabel { +- +- public static final ClosingLabel[] EMPTY_ARRAY = new ClosingLabel[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the construct being labelled. +- */ +- private final int offset; +- +- /** +- * The length of the whole construct to be labelled. +- */ +- private final int length; +- +- /** +- * The label associated with this range that should be displayed to the user. +- */ +- private final String label; +- +- /** +- * Constructor for {@link ClosingLabel}. +- */ +- public ClosingLabel(int offset, int length, String label) { +- this.offset = offset; +- this.length = length; +- this.label = label; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ClosingLabel) { +- ClosingLabel other = (ClosingLabel) obj; +- return +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.label, label); +- } +- return false; +- } +- +- public static ClosingLabel fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- String label = jsonObject.get("label").getAsString(); +- return new ClosingLabel(offset, length, label); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The label associated with this range that should be displayed to the user. +- */ +- public String getLabel() { +- return label; +- } +- +- /** +- * The length of the whole construct to be labelled. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the construct being labelled. +- */ +- public int getOffset() { +- return offset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(label); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- jsonObject.addProperty("label", label); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("label="); +- builder.append(label); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java +deleted file mode 100644 +index 125322ccf71..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java ++++ /dev/null +@@ -1,574 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A suggestion for how to complete partially entered text. Many of the fields are optional, +- * depending on the kind of element being suggested. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class CompletionSuggestion { +- +- public static final CompletionSuggestion[] EMPTY_ARRAY = new CompletionSuggestion[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The kind of element being suggested. +- */ +- private final String kind; +- +- /** +- * The relevance of this completion suggestion where a higher number indicates a higher relevance. +- */ +- private final int relevance; +- +- /** +- * The identifier to be inserted if the suggestion is selected. If the suggestion is for a method +- * or function, the client might want to additionally insert a template for the parameters. The +- * information required in order to do so is contained in other fields. +- */ +- private final String completion; +- +- /** +- * The offset, relative to the beginning of the completion, of where the selection should be placed +- * after insertion. +- */ +- private final int selectionOffset; +- +- /** +- * The number of characters that should be selected after insertion. +- */ +- private final int selectionLength; +- +- /** +- * True if the suggested element is deprecated. +- */ +- private final boolean isDeprecated; +- +- /** +- * True if the element is not known to be valid for the target. This happens if the type of the +- * target is dynamic. +- */ +- private final boolean isPotential; +- +- /** +- * An abbreviated version of the Dartdoc associated with the element being suggested, This field is +- * omitted if there is no Dartdoc associated with the element. +- */ +- private final String docSummary; +- +- /** +- * The Dartdoc associated with the element being suggested. This field is omitted if there is no +- * Dartdoc associated with the element. +- */ +- private final String docComplete; +- +- /** +- * The class that declares the element being suggested. This field is omitted if the suggested +- * element is not a member of a class. +- */ +- private final String declaringType; +- +- /** +- * A default String for use in generating argument list source contents on the client side. +- */ +- private final String defaultArgumentListString; +- +- /** +- * Pairs of offsets and lengths describing 'defaultArgumentListString' text ranges suitable for use +- * by clients to set up linked edits of default argument source contents. For example, given an +- * argument list string 'x, y', the corresponding text range [0, 1, 3, 1], indicates two text +- * ranges of length 1, starting at offsets 0 and 3. Clients can use these ranges to treat the 'x' +- * and 'y' values specially for linked edits. +- */ +- private final int[] defaultArgumentListTextRanges; +- +- /** +- * Information about the element reference being suggested. +- */ +- private final Element element; +- +- /** +- * The return type of the getter, function or method or the type of the field being suggested. This +- * field is omitted if the suggested element is not a getter, function or method. +- */ +- private final String returnType; +- +- /** +- * The names of the parameters of the function or method being suggested. This field is omitted if +- * the suggested element is not a setter, function or method. +- */ +- private final List parameterNames; +- +- /** +- * The types of the parameters of the function or method being suggested. This field is omitted if +- * the parameterNames field is omitted. +- */ +- private final List parameterTypes; +- +- /** +- * The number of required parameters for the function or method being suggested. This field is +- * omitted if the parameterNames field is omitted. +- */ +- private final Integer requiredParameterCount; +- +- /** +- * True if the function or method being suggested has at least one named parameter. This field is +- * omitted if the parameterNames field is omitted. +- */ +- private final Boolean hasNamedParameters; +- +- /** +- * The name of the optional parameter being suggested. This field is omitted if the suggestion is +- * not the addition of an optional argument within an argument list. +- */ +- private final String parameterName; +- +- /** +- * The type of the options parameter being suggested. This field is omitted if the parameterName +- * field is omitted. +- */ +- private final String parameterType; +- +- /** +- * The import to be added if the suggestion is out of scope and needs an import to be added to be +- * in scope. +- */ +- private final String importUri; +- +- /** +- * Constructor for {@link CompletionSuggestion}. +- */ +- public CompletionSuggestion(String kind, int relevance, String completion, int selectionOffset, int selectionLength, boolean isDeprecated, boolean isPotential, String docSummary, String docComplete, String declaringType, String defaultArgumentListString, int[] defaultArgumentListTextRanges, Element element, String returnType, List parameterNames, List parameterTypes, Integer requiredParameterCount, Boolean hasNamedParameters, String parameterName, String parameterType, String importUri) { +- this.kind = kind; +- this.relevance = relevance; +- this.completion = completion; +- this.selectionOffset = selectionOffset; +- this.selectionLength = selectionLength; +- this.isDeprecated = isDeprecated; +- this.isPotential = isPotential; +- this.docSummary = docSummary; +- this.docComplete = docComplete; +- this.declaringType = declaringType; +- this.defaultArgumentListString = defaultArgumentListString; +- this.defaultArgumentListTextRanges = defaultArgumentListTextRanges; +- this.element = element; +- this.returnType = returnType; +- this.parameterNames = parameterNames; +- this.parameterTypes = parameterTypes; +- this.requiredParameterCount = requiredParameterCount; +- this.hasNamedParameters = hasNamedParameters; +- this.parameterName = parameterName; +- this.parameterType = parameterType; +- this.importUri = importUri; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof CompletionSuggestion) { +- CompletionSuggestion other = (CompletionSuggestion) obj; +- return +- ObjectUtilities.equals(other.kind, kind) && +- other.relevance == relevance && +- ObjectUtilities.equals(other.completion, completion) && +- other.selectionOffset == selectionOffset && +- other.selectionLength == selectionLength && +- other.isDeprecated == isDeprecated && +- other.isPotential == isPotential && +- ObjectUtilities.equals(other.docSummary, docSummary) && +- ObjectUtilities.equals(other.docComplete, docComplete) && +- ObjectUtilities.equals(other.declaringType, declaringType) && +- ObjectUtilities.equals(other.defaultArgumentListString, defaultArgumentListString) && +- Arrays.equals(other.defaultArgumentListTextRanges, defaultArgumentListTextRanges) && +- ObjectUtilities.equals(other.element, element) && +- ObjectUtilities.equals(other.returnType, returnType) && +- ObjectUtilities.equals(other.parameterNames, parameterNames) && +- ObjectUtilities.equals(other.parameterTypes, parameterTypes) && +- ObjectUtilities.equals(other.requiredParameterCount, requiredParameterCount) && +- ObjectUtilities.equals(other.hasNamedParameters, hasNamedParameters) && +- ObjectUtilities.equals(other.parameterName, parameterName) && +- ObjectUtilities.equals(other.parameterType, parameterType) && +- ObjectUtilities.equals(other.importUri, importUri); +- } +- return false; +- } +- +- public static CompletionSuggestion fromJson(JsonObject jsonObject) { +- String kind = jsonObject.get("kind").getAsString(); +- int relevance = jsonObject.get("relevance").getAsInt(); +- String completion = jsonObject.get("completion").getAsString(); +- int selectionOffset = jsonObject.get("selectionOffset").getAsInt(); +- int selectionLength = jsonObject.get("selectionLength").getAsInt(); +- boolean isDeprecated = jsonObject.get("isDeprecated").getAsBoolean(); +- boolean isPotential = jsonObject.get("isPotential").getAsBoolean(); +- String docSummary = jsonObject.get("docSummary") == null ? null : jsonObject.get("docSummary").getAsString(); +- String docComplete = jsonObject.get("docComplete") == null ? null : jsonObject.get("docComplete").getAsString(); +- String declaringType = jsonObject.get("declaringType") == null ? null : jsonObject.get("declaringType").getAsString(); +- String defaultArgumentListString = jsonObject.get("defaultArgumentListString") == null ? null : jsonObject.get("defaultArgumentListString").getAsString(); +- int[] defaultArgumentListTextRanges = jsonObject.get("defaultArgumentListTextRanges") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("defaultArgumentListTextRanges").getAsJsonArray()); +- Element element = jsonObject.get("element") == null ? null : Element.fromJson(jsonObject.get("element").getAsJsonObject()); +- String returnType = jsonObject.get("returnType") == null ? null : jsonObject.get("returnType").getAsString(); +- List parameterNames = jsonObject.get("parameterNames") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("parameterNames").getAsJsonArray()); +- List parameterTypes = jsonObject.get("parameterTypes") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("parameterTypes").getAsJsonArray()); +- Integer requiredParameterCount = jsonObject.get("requiredParameterCount") == null ? null : jsonObject.get("requiredParameterCount").getAsInt(); +- Boolean hasNamedParameters = jsonObject.get("hasNamedParameters") == null ? null : jsonObject.get("hasNamedParameters").getAsBoolean(); +- String parameterName = jsonObject.get("parameterName") == null ? null : jsonObject.get("parameterName").getAsString(); +- String parameterType = jsonObject.get("parameterType") == null ? null : jsonObject.get("parameterType").getAsString(); +- String importUri = jsonObject.get("importUri") == null ? null : jsonObject.get("importUri").getAsString(); +- return new CompletionSuggestion(kind, relevance, completion, selectionOffset, selectionLength, isDeprecated, isPotential, docSummary, docComplete, declaringType, defaultArgumentListString, defaultArgumentListTextRanges, element, returnType, parameterNames, parameterTypes, requiredParameterCount, hasNamedParameters, parameterName, parameterType, importUri); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The identifier to be inserted if the suggestion is selected. If the suggestion is for a method +- * or function, the client might want to additionally insert a template for the parameters. The +- * information required in order to do so is contained in other fields. +- */ +- public String getCompletion() { +- return completion; +- } +- +- /** +- * The class that declares the element being suggested. This field is omitted if the suggested +- * element is not a member of a class. +- */ +- public String getDeclaringType() { +- return declaringType; +- } +- +- /** +- * A default String for use in generating argument list source contents on the client side. +- */ +- public String getDefaultArgumentListString() { +- return defaultArgumentListString; +- } +- +- /** +- * Pairs of offsets and lengths describing 'defaultArgumentListString' text ranges suitable for use +- * by clients to set up linked edits of default argument source contents. For example, given an +- * argument list string 'x, y', the corresponding text range [0, 1, 3, 1], indicates two text +- * ranges of length 1, starting at offsets 0 and 3. Clients can use these ranges to treat the 'x' +- * and 'y' values specially for linked edits. +- */ +- public int[] getDefaultArgumentListTextRanges() { +- return defaultArgumentListTextRanges; +- } +- +- /** +- * The Dartdoc associated with the element being suggested. This field is omitted if there is no +- * Dartdoc associated with the element. +- */ +- public String getDocComplete() { +- return docComplete; +- } +- +- /** +- * An abbreviated version of the Dartdoc associated with the element being suggested, This field is +- * omitted if there is no Dartdoc associated with the element. +- */ +- public String getDocSummary() { +- return docSummary; +- } +- +- /** +- * Information about the element reference being suggested. +- */ +- public Element getElement() { +- return element; +- } +- +- /** +- * True if the function or method being suggested has at least one named parameter. This field is +- * omitted if the parameterNames field is omitted. +- */ +- public Boolean getHasNamedParameters() { +- return hasNamedParameters; +- } +- +- /** +- * The import to be added if the suggestion is out of scope and needs an import to be added to be +- * in scope. +- */ +- public String getImportUri() { +- return importUri; +- } +- +- /** +- * True if the suggested element is deprecated. +- */ +- public boolean isDeprecated() { +- return isDeprecated; +- } +- +- /** +- * True if the element is not known to be valid for the target. This happens if the type of the +- * target is dynamic. +- */ +- public boolean isPotential() { +- return isPotential; +- } +- +- /** +- * The kind of element being suggested. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The name of the optional parameter being suggested. This field is omitted if the suggestion is +- * not the addition of an optional argument within an argument list. +- */ +- public String getParameterName() { +- return parameterName; +- } +- +- /** +- * The names of the parameters of the function or method being suggested. This field is omitted if +- * the suggested element is not a setter, function or method. +- */ +- public List getParameterNames() { +- return parameterNames; +- } +- +- /** +- * The type of the options parameter being suggested. This field is omitted if the parameterName +- * field is omitted. +- */ +- public String getParameterType() { +- return parameterType; +- } +- +- /** +- * The types of the parameters of the function or method being suggested. This field is omitted if +- * the parameterNames field is omitted. +- */ +- public List getParameterTypes() { +- return parameterTypes; +- } +- +- /** +- * The relevance of this completion suggestion where a higher number indicates a higher relevance. +- */ +- public int getRelevance() { +- return relevance; +- } +- +- /** +- * The number of required parameters for the function or method being suggested. This field is +- * omitted if the parameterNames field is omitted. +- */ +- public Integer getRequiredParameterCount() { +- return requiredParameterCount; +- } +- +- /** +- * The return type of the getter, function or method or the type of the field being suggested. This +- * field is omitted if the suggested element is not a getter, function or method. +- */ +- public String getReturnType() { +- return returnType; +- } +- +- /** +- * The number of characters that should be selected after insertion. +- */ +- public int getSelectionLength() { +- return selectionLength; +- } +- +- /** +- * The offset, relative to the beginning of the completion, of where the selection should be placed +- * after insertion. +- */ +- public int getSelectionOffset() { +- return selectionOffset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(kind); +- builder.append(relevance); +- builder.append(completion); +- builder.append(selectionOffset); +- builder.append(selectionLength); +- builder.append(isDeprecated); +- builder.append(isPotential); +- builder.append(docSummary); +- builder.append(docComplete); +- builder.append(declaringType); +- builder.append(defaultArgumentListString); +- builder.append(defaultArgumentListTextRanges); +- builder.append(element); +- builder.append(returnType); +- builder.append(parameterNames); +- builder.append(parameterTypes); +- builder.append(requiredParameterCount); +- builder.append(hasNamedParameters); +- builder.append(parameterName); +- builder.append(parameterType); +- builder.append(importUri); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("kind", kind); +- jsonObject.addProperty("relevance", relevance); +- jsonObject.addProperty("completion", completion); +- jsonObject.addProperty("selectionOffset", selectionOffset); +- jsonObject.addProperty("selectionLength", selectionLength); +- jsonObject.addProperty("isDeprecated", isDeprecated); +- jsonObject.addProperty("isPotential", isPotential); +- if (docSummary != null) { +- jsonObject.addProperty("docSummary", docSummary); +- } +- if (docComplete != null) { +- jsonObject.addProperty("docComplete", docComplete); +- } +- if (declaringType != null) { +- jsonObject.addProperty("declaringType", declaringType); +- } +- if (defaultArgumentListString != null) { +- jsonObject.addProperty("defaultArgumentListString", defaultArgumentListString); +- } +- if (defaultArgumentListTextRanges != null) { +- JsonArray jsonArrayDefaultArgumentListTextRanges = new JsonArray(); +- for (int elt : defaultArgumentListTextRanges) { +- jsonArrayDefaultArgumentListTextRanges.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("defaultArgumentListTextRanges", jsonArrayDefaultArgumentListTextRanges); +- } +- if (element != null) { +- jsonObject.add("element", element.toJson()); +- } +- if (returnType != null) { +- jsonObject.addProperty("returnType", returnType); +- } +- if (parameterNames != null) { +- JsonArray jsonArrayParameterNames = new JsonArray(); +- for (String elt : parameterNames) { +- jsonArrayParameterNames.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("parameterNames", jsonArrayParameterNames); +- } +- if (parameterTypes != null) { +- JsonArray jsonArrayParameterTypes = new JsonArray(); +- for (String elt : parameterTypes) { +- jsonArrayParameterTypes.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("parameterTypes", jsonArrayParameterTypes); +- } +- if (requiredParameterCount != null) { +- jsonObject.addProperty("requiredParameterCount", requiredParameterCount); +- } +- if (hasNamedParameters != null) { +- jsonObject.addProperty("hasNamedParameters", hasNamedParameters); +- } +- if (parameterName != null) { +- jsonObject.addProperty("parameterName", parameterName); +- } +- if (parameterType != null) { +- jsonObject.addProperty("parameterType", parameterType); +- } +- if (importUri != null) { +- jsonObject.addProperty("importUri", importUri); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("relevance="); +- builder.append(relevance + ", "); +- builder.append("completion="); +- builder.append(completion + ", "); +- builder.append("selectionOffset="); +- builder.append(selectionOffset + ", "); +- builder.append("selectionLength="); +- builder.append(selectionLength + ", "); +- builder.append("isDeprecated="); +- builder.append(isDeprecated + ", "); +- builder.append("isPotential="); +- builder.append(isPotential + ", "); +- builder.append("docSummary="); +- builder.append(docSummary + ", "); +- builder.append("docComplete="); +- builder.append(docComplete + ", "); +- builder.append("declaringType="); +- builder.append(declaringType + ", "); +- builder.append("defaultArgumentListString="); +- builder.append(defaultArgumentListString + ", "); +- builder.append("defaultArgumentListTextRanges="); +- builder.append(StringUtils.join(defaultArgumentListTextRanges, ", ") + ", "); +- builder.append("element="); +- builder.append(element + ", "); +- builder.append("returnType="); +- builder.append(returnType + ", "); +- builder.append("parameterNames="); +- builder.append(StringUtils.join(parameterNames, ", ") + ", "); +- builder.append("parameterTypes="); +- builder.append(StringUtils.join(parameterTypes, ", ") + ", "); +- builder.append("requiredParameterCount="); +- builder.append(requiredParameterCount + ", "); +- builder.append("hasNamedParameters="); +- builder.append(hasNamedParameters + ", "); +- builder.append("parameterName="); +- builder.append(parameterName + ", "); +- builder.append("parameterType="); +- builder.append(parameterType + ", "); +- builder.append("importUri="); +- builder.append(importUri); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java +deleted file mode 100644 +index 8216ce95b0e..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java ++++ /dev/null +@@ -1,64 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of elements that can be included in a completion suggestion. +- * +- * @coverage dart.server.generated.types +- */ +-public class CompletionSuggestionKind { +- +- /** +- * A list of arguments for the method or function that is being invoked. For this suggestion kind, +- * the completion field is a textual representation of the invocation and the parameterNames, +- * parameterTypes, and requiredParameterCount attributes are defined. +- */ +- public static final String ARGUMENT_LIST = "ARGUMENT_LIST"; +- +- public static final String IMPORT = "IMPORT"; +- +- /** +- * The element identifier should be inserted at the completion location. For example "someMethod" +- * in import 'myLib.dart' show someMethod;. For suggestions of this kind, the element attribute is +- * defined and the completion field is the element's identifier. +- */ +- public static final String IDENTIFIER = "IDENTIFIER"; +- +- /** +- * The element is being invoked at the completion location. For example, 'someMethod' in +- * x.someMethod();. For suggestions of this kind, the element attribute is defined and the +- * completion field is the element's identifier. +- */ +- public static final String INVOCATION = "INVOCATION"; +- +- /** +- * A keyword is being suggested. For suggestions of this kind, the completion is the keyword. +- */ +- public static final String KEYWORD = "KEYWORD"; +- +- /** +- * A named argument for the current call site is being suggested. For suggestions of this kind, the +- * completion is the named argument identifier including a trailing ':' and a space. +- */ +- public static final String NAMED_ARGUMENT = "NAMED_ARGUMENT"; +- +- public static final String OPTIONAL_ARGUMENT = "OPTIONAL_ARGUMENT"; +- +- public static final String PARAMETER = "PARAMETER"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java +deleted file mode 100644 +index ab4020c02af..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java ++++ /dev/null +@@ -1,195 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * Information about an analysis context. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ContextData { +- +- public static final ContextData[] EMPTY_ARRAY = new ContextData[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The name of the context. +- */ +- private final String name; +- +- /** +- * Explicitly analyzed files. +- */ +- private final int explicitFileCount; +- +- /** +- * Implicitly analyzed files. +- */ +- private final int implicitFileCount; +- +- /** +- * The number of work items in the queue. +- */ +- private final int workItemQueueLength; +- +- /** +- * Exceptions associated with cache entries. +- */ +- private final List cacheEntryExceptions; +- +- /** +- * Constructor for {@link ContextData}. +- */ +- public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List cacheEntryExceptions) { +- this.name = name; +- this.explicitFileCount = explicitFileCount; +- this.implicitFileCount = implicitFileCount; +- this.workItemQueueLength = workItemQueueLength; +- this.cacheEntryExceptions = cacheEntryExceptions; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ContextData) { +- ContextData other = (ContextData) obj; +- return +- ObjectUtilities.equals(other.name, name) && +- other.explicitFileCount == explicitFileCount && +- other.implicitFileCount == implicitFileCount && +- other.workItemQueueLength == workItemQueueLength && +- ObjectUtilities.equals(other.cacheEntryExceptions, cacheEntryExceptions); +- } +- return false; +- } +- +- public static ContextData fromJson(JsonObject jsonObject) { +- String name = jsonObject.get("name").getAsString(); +- int explicitFileCount = jsonObject.get("explicitFileCount").getAsInt(); +- int implicitFileCount = jsonObject.get("implicitFileCount").getAsInt(); +- int workItemQueueLength = jsonObject.get("workItemQueueLength").getAsInt(); +- List cacheEntryExceptions = JsonUtilities.decodeStringList(jsonObject.get("cacheEntryExceptions").getAsJsonArray()); +- return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * Exceptions associated with cache entries. +- */ +- public List getCacheEntryExceptions() { +- return cacheEntryExceptions; +- } +- +- /** +- * Explicitly analyzed files. +- */ +- public int getExplicitFileCount() { +- return explicitFileCount; +- } +- +- /** +- * Implicitly analyzed files. +- */ +- public int getImplicitFileCount() { +- return implicitFileCount; +- } +- +- /** +- * The name of the context. +- */ +- public String getName() { +- return name; +- } +- +- /** +- * The number of work items in the queue. +- */ +- public int getWorkItemQueueLength() { +- return workItemQueueLength; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(name); +- builder.append(explicitFileCount); +- builder.append(implicitFileCount); +- builder.append(workItemQueueLength); +- builder.append(cacheEntryExceptions); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("name", name); +- jsonObject.addProperty("explicitFileCount", explicitFileCount); +- jsonObject.addProperty("implicitFileCount", implicitFileCount); +- jsonObject.addProperty("workItemQueueLength", workItemQueueLength); +- JsonArray jsonArrayCacheEntryExceptions = new JsonArray(); +- for (String elt : cacheEntryExceptions) { +- jsonArrayCacheEntryExceptions.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("cacheEntryExceptions", jsonArrayCacheEntryExceptions); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("explicitFileCount="); +- builder.append(explicitFileCount + ", "); +- builder.append("implicitFileCount="); +- builder.append(implicitFileCount + ", "); +- builder.append("workItemQueueLength="); +- builder.append(workItemQueueLength + ", "); +- builder.append("cacheEntryExceptions="); +- builder.append(StringUtils.join(cacheEntryExceptions, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Element.java b/pkg/analysis_server/tool/spec/generated/java/types/Element.java +deleted file mode 100644 +index 579ef3f0e9a..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/Element.java ++++ /dev/null +@@ -1,297 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * Information about an element (something that can be declared in code). +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class Element { +- +- public static final Element[] EMPTY_ARRAY = new Element[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- private static final int ABSTRACT = 0x01; +- +- private static final int CONST = 0x02; +- +- private static final int FINAL = 0x04; +- +- private static final int TOP_LEVEL_STATIC = 0x08; +- +- private static final int PRIVATE = 0x10; +- +- private static final int DEPRECATED = 0x20; +- +- /** +- * The kind of the element. +- */ +- private final String kind; +- +- /** +- * The name of the element. This is typically used as the label in the outline. +- */ +- private final String name; +- +- /** +- * The location of the name in the declaration of the element. +- */ +- private final Location location; +- +- /** +- * A bit-map containing the following flags: +- * +- * - 0x01 - set if the element is explicitly or implicitly abstract +- * - 0x02 - set if the element was declared to be ‘const’ +- * - 0x04 - set if the element was declared to be ‘final’ +- * - 0x08 - set if the element is a static member of a class or is a top-level function or field +- * - 0x10 - set if the element is private +- * - 0x20 - set if the element is deprecated +- */ +- private final int flags; +- +- /** +- * The parameter list for the element. If the element is not a method or function this field will +- * not be defined. If the element doesn't have parameters (e.g. getter), this field will not be +- * defined. If the element has zero parameters, this field will have a value of "()". +- */ +- private final String parameters; +- +- /** +- * The return type of the element. If the element is not a method or function this field will not +- * be defined. If the element does not have a declared return type, this field will contain an +- * empty string. +- */ +- private final String returnType; +- +- /** +- * The type parameter list for the element. If the element doesn't have type parameters, this field +- * will not be defined. +- */ +- private final String typeParameters; +- +- /** +- * Constructor for {@link Element}. +- */ +- public Element(String kind, String name, Location location, int flags, String parameters, String returnType, String typeParameters) { +- this.kind = kind; +- this.name = name; +- this.location = location; +- this.flags = flags; +- this.parameters = parameters; +- this.returnType = returnType; +- this.typeParameters = typeParameters; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof Element) { +- Element other = (Element) obj; +- return +- ObjectUtilities.equals(other.kind, kind) && +- ObjectUtilities.equals(other.name, name) && +- ObjectUtilities.equals(other.location, location) && +- other.flags == flags && +- ObjectUtilities.equals(other.parameters, parameters) && +- ObjectUtilities.equals(other.returnType, returnType) && +- ObjectUtilities.equals(other.typeParameters, typeParameters); +- } +- return false; +- } +- +- public static Element fromJson(JsonObject jsonObject) { +- String kind = jsonObject.get("kind").getAsString(); +- String name = jsonObject.get("name").getAsString(); +- Location location = jsonObject.get("location") == null ? null : Location.fromJson(jsonObject.get("location").getAsJsonObject()); +- int flags = jsonObject.get("flags").getAsInt(); +- String parameters = jsonObject.get("parameters") == null ? null : jsonObject.get("parameters").getAsString(); +- String returnType = jsonObject.get("returnType") == null ? null : jsonObject.get("returnType").getAsString(); +- String typeParameters = jsonObject.get("typeParameters") == null ? null : jsonObject.get("typeParameters").getAsString(); +- return new Element(kind, name, location, flags, parameters, returnType, typeParameters); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A bit-map containing the following flags: +- * +- * - 0x01 - set if the element is explicitly or implicitly abstract +- * - 0x02 - set if the element was declared to be ‘const’ +- * - 0x04 - set if the element was declared to be ‘final’ +- * - 0x08 - set if the element is a static member of a class or is a top-level function or field +- * - 0x10 - set if the element is private +- * - 0x20 - set if the element is deprecated +- */ +- public int getFlags() { +- return flags; +- } +- +- /** +- * The kind of the element. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The location of the name in the declaration of the element. +- */ +- public Location getLocation() { +- return location; +- } +- +- /** +- * The name of the element. This is typically used as the label in the outline. +- */ +- public String getName() { +- return name; +- } +- +- /** +- * The parameter list for the element. If the element is not a method or function this field will +- * not be defined. If the element doesn't have parameters (e.g. getter), this field will not be +- * defined. If the element has zero parameters, this field will have a value of "()". +- */ +- public String getParameters() { +- return parameters; +- } +- +- /** +- * The return type of the element. If the element is not a method or function this field will not +- * be defined. If the element does not have a declared return type, this field will contain an +- * empty string. +- */ +- public String getReturnType() { +- return returnType; +- } +- +- /** +- * The type parameter list for the element. If the element doesn't have type parameters, this field +- * will not be defined. +- */ +- public String getTypeParameters() { +- return typeParameters; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(kind); +- builder.append(name); +- builder.append(location); +- builder.append(flags); +- builder.append(parameters); +- builder.append(returnType); +- builder.append(typeParameters); +- return builder.toHashCode(); +- } +- +- public boolean isAbstract() { +- return (flags & ABSTRACT) != 0; +- } +- +- public boolean isConst() { +- return (flags & CONST) != 0; +- } +- +- public boolean isDeprecated() { +- return (flags & DEPRECATED) != 0; +- } +- +- public boolean isFinal() { +- return (flags & FINAL) != 0; +- } +- +- public boolean isPrivate() { +- return (flags & PRIVATE) != 0; +- } +- +- public boolean isTopLevelOrStatic() { +- return (flags & TOP_LEVEL_STATIC) != 0; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("kind", kind); +- jsonObject.addProperty("name", name); +- if (location != null) { +- jsonObject.add("location", location.toJson()); +- } +- jsonObject.addProperty("flags", flags); +- if (parameters != null) { +- jsonObject.addProperty("parameters", parameters); +- } +- if (returnType != null) { +- jsonObject.addProperty("returnType", returnType); +- } +- if (typeParameters != null) { +- jsonObject.addProperty("typeParameters", typeParameters); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("location="); +- builder.append(location + ", "); +- builder.append("flags="); +- builder.append(flags + ", "); +- builder.append("parameters="); +- builder.append(parameters + ", "); +- builder.append("returnType="); +- builder.append(returnType + ", "); +- builder.append("typeParameters="); +- builder.append(typeParameters); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java +deleted file mode 100644 +index 0b9f43894e2..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java ++++ /dev/null +@@ -1,76 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of elements. +- * +- * @coverage dart.server.generated.types +- */ +-public class ElementKind { +- +- public static final String CLASS = "CLASS"; +- +- public static final String CLASS_TYPE_ALIAS = "CLASS_TYPE_ALIAS"; +- +- public static final String COMPILATION_UNIT = "COMPILATION_UNIT"; +- +- public static final String CONSTRUCTOR = "CONSTRUCTOR"; +- +- public static final String CONSTRUCTOR_INVOCATION = "CONSTRUCTOR_INVOCATION"; +- +- public static final String ENUM = "ENUM"; +- +- public static final String ENUM_CONSTANT = "ENUM_CONSTANT"; +- +- public static final String FIELD = "FIELD"; +- +- public static final String FILE = "FILE"; +- +- public static final String FUNCTION = "FUNCTION"; +- +- public static final String FUNCTION_INVOCATION = "FUNCTION_INVOCATION"; +- +- public static final String FUNCTION_TYPE_ALIAS = "FUNCTION_TYPE_ALIAS"; +- +- public static final String GETTER = "GETTER"; +- +- public static final String LABEL = "LABEL"; +- +- public static final String LIBRARY = "LIBRARY"; +- +- public static final String LOCAL_VARIABLE = "LOCAL_VARIABLE"; +- +- public static final String METHOD = "METHOD"; +- +- public static final String PARAMETER = "PARAMETER"; +- +- public static final String PREFIX = "PREFIX"; +- +- public static final String SETTER = "SETTER"; +- +- public static final String TOP_LEVEL_VARIABLE = "TOP_LEVEL_VARIABLE"; +- +- public static final String TYPE_PARAMETER = "TYPE_PARAMETER"; +- +- public static final String UNIT_TEST_GROUP = "UNIT_TEST_GROUP"; +- +- public static final String UNIT_TEST_TEST = "UNIT_TEST_TEST"; +- +- public static final String UNKNOWN = "UNKNOWN"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java +deleted file mode 100644 +index 52f0c9580f3..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableFile.java ++++ /dev/null +@@ -1,134 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of an executable file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ExecutableFile { +- +- public static final ExecutableFile[] EMPTY_ARRAY = new ExecutableFile[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The path of the executable file. +- */ +- private final String file; +- +- /** +- * The kind of the executable file. +- */ +- private final String kind; +- +- /** +- * Constructor for {@link ExecutableFile}. +- */ +- public ExecutableFile(String file, String kind) { +- this.file = file; +- this.kind = kind; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ExecutableFile) { +- ExecutableFile other = (ExecutableFile) obj; +- return +- ObjectUtilities.equals(other.file, file) && +- ObjectUtilities.equals(other.kind, kind); +- } +- return false; +- } +- +- public static ExecutableFile fromJson(JsonObject jsonObject) { +- String file = jsonObject.get("file").getAsString(); +- String kind = jsonObject.get("kind").getAsString(); +- return new ExecutableFile(file, kind); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The path of the executable file. +- */ +- public String getFile() { +- return file; +- } +- +- /** +- * The kind of the executable file. +- */ +- public String getKind() { +- return kind; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(file); +- builder.append(kind); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("file", file); +- jsonObject.addProperty("kind", kind); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("file="); +- builder.append(file + ", "); +- builder.append("kind="); +- builder.append(kind); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java +deleted file mode 100644 +index 407f36824e1..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutableKind.java ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of executable files. +- * +- * @coverage dart.server.generated.types +- */ +-public class ExecutableKind { +- +- public static final String CLIENT = "CLIENT"; +- +- public static final String EITHER = "EITHER"; +- +- public static final String NOT_EXECUTABLE = "NOT_EXECUTABLE"; +- +- public static final String SERVER = "SERVER"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java b/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java +deleted file mode 100644 +index 0e1b005c09f..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExecutionService.java ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the services provided by the execution domain. +- * +- * @coverage dart.server.generated.types +- */ +-public class ExecutionService { +- +- public static final String LAUNCH_DATA = "LAUNCH_DATA"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java +deleted file mode 100644 +index 8058954986b..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableFeedback.java ++++ /dev/null +@@ -1,221 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ExtractLocalVariableFeedback extends RefactoringFeedback { +- +- public static final ExtractLocalVariableFeedback[] EMPTY_ARRAY = new ExtractLocalVariableFeedback[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offsets of the expressions that cover the specified selection, from the down most to the up +- * most. +- */ +- private final int[] coveringExpressionOffsets; +- +- /** +- * The lengths of the expressions that cover the specified selection, from the down most to the up +- * most. +- */ +- private final int[] coveringExpressionLengths; +- +- /** +- * The proposed names for the local variable. +- */ +- private final List names; +- +- /** +- * The offsets of the expressions that would be replaced by a reference to the variable. +- */ +- private final int[] offsets; +- +- /** +- * The lengths of the expressions that would be replaced by a reference to the variable. The +- * lengths correspond to the offsets. In other words, for a given expression, if the offset of that +- * expression is offsets[i], then the length of that expression is lengths[i]. +- */ +- private final int[] lengths; +- +- /** +- * Constructor for {@link ExtractLocalVariableFeedback}. +- */ +- public ExtractLocalVariableFeedback(int[] coveringExpressionOffsets, int[] coveringExpressionLengths, List names, int[] offsets, int[] lengths) { +- this.coveringExpressionOffsets = coveringExpressionOffsets; +- this.coveringExpressionLengths = coveringExpressionLengths; +- this.names = names; +- this.offsets = offsets; +- this.lengths = lengths; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ExtractLocalVariableFeedback) { +- ExtractLocalVariableFeedback other = (ExtractLocalVariableFeedback) obj; +- return +- Arrays.equals(other.coveringExpressionOffsets, coveringExpressionOffsets) && +- Arrays.equals(other.coveringExpressionLengths, coveringExpressionLengths) && +- ObjectUtilities.equals(other.names, names) && +- Arrays.equals(other.offsets, offsets) && +- Arrays.equals(other.lengths, lengths); +- } +- return false; +- } +- +- public static ExtractLocalVariableFeedback fromJson(JsonObject jsonObject) { +- int[] coveringExpressionOffsets = jsonObject.get("coveringExpressionOffsets") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionOffsets").getAsJsonArray()); +- int[] coveringExpressionLengths = jsonObject.get("coveringExpressionLengths") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("coveringExpressionLengths").getAsJsonArray()); +- List names = JsonUtilities.decodeStringList(jsonObject.get("names").getAsJsonArray()); +- int[] offsets = JsonUtilities.decodeIntArray(jsonObject.get("offsets").getAsJsonArray()); +- int[] lengths = JsonUtilities.decodeIntArray(jsonObject.get("lengths").getAsJsonArray()); +- return new ExtractLocalVariableFeedback(coveringExpressionOffsets, coveringExpressionLengths, names, offsets, lengths); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The lengths of the expressions that cover the specified selection, from the down most to the up +- * most. +- */ +- public int[] getCoveringExpressionLengths() { +- return coveringExpressionLengths; +- } +- +- /** +- * The offsets of the expressions that cover the specified selection, from the down most to the up +- * most. +- */ +- public int[] getCoveringExpressionOffsets() { +- return coveringExpressionOffsets; +- } +- +- /** +- * The lengths of the expressions that would be replaced by a reference to the variable. The +- * lengths correspond to the offsets. In other words, for a given expression, if the offset of that +- * expression is offsets[i], then the length of that expression is lengths[i]. +- */ +- public int[] getLengths() { +- return lengths; +- } +- +- /** +- * The proposed names for the local variable. +- */ +- public List getNames() { +- return names; +- } +- +- /** +- * The offsets of the expressions that would be replaced by a reference to the variable. +- */ +- public int[] getOffsets() { +- return offsets; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(coveringExpressionOffsets); +- builder.append(coveringExpressionLengths); +- builder.append(names); +- builder.append(offsets); +- builder.append(lengths); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- if (coveringExpressionOffsets != null) { +- JsonArray jsonArrayCoveringExpressionOffsets = new JsonArray(); +- for (int elt : coveringExpressionOffsets) { +- jsonArrayCoveringExpressionOffsets.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("coveringExpressionOffsets", jsonArrayCoveringExpressionOffsets); +- } +- if (coveringExpressionLengths != null) { +- JsonArray jsonArrayCoveringExpressionLengths = new JsonArray(); +- for (int elt : coveringExpressionLengths) { +- jsonArrayCoveringExpressionLengths.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("coveringExpressionLengths", jsonArrayCoveringExpressionLengths); +- } +- JsonArray jsonArrayNames = new JsonArray(); +- for (String elt : names) { +- jsonArrayNames.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("names", jsonArrayNames); +- JsonArray jsonArrayOffsets = new JsonArray(); +- for (int elt : offsets) { +- jsonArrayOffsets.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("offsets", jsonArrayOffsets); +- JsonArray jsonArrayLengths = new JsonArray(); +- for (int elt : lengths) { +- jsonArrayLengths.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("lengths", jsonArrayLengths); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("coveringExpressionOffsets="); +- builder.append(StringUtils.join(coveringExpressionOffsets, ", ") + ", "); +- builder.append("coveringExpressionLengths="); +- builder.append(StringUtils.join(coveringExpressionLengths, ", ") + ", "); +- builder.append("names="); +- builder.append(StringUtils.join(names, ", ") + ", "); +- builder.append("offsets="); +- builder.append(StringUtils.join(offsets, ", ") + ", "); +- builder.append("lengths="); +- builder.append(StringUtils.join(lengths, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java +deleted file mode 100644 +index c0b9756aa3e..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractLocalVariableOptions.java ++++ /dev/null +@@ -1,152 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ExtractLocalVariableOptions extends RefactoringOptions { +- +- public static final ExtractLocalVariableOptions[] EMPTY_ARRAY = new ExtractLocalVariableOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The name that the local variable should be given. +- */ +- private String name; +- +- /** +- * True if all occurrences of the expression within the scope in which the variable will be defined +- * should be replaced by a reference to the local variable. The expression used to initiate the +- * refactoring will always be replaced. +- */ +- private boolean extractAll; +- +- /** +- * Constructor for {@link ExtractLocalVariableOptions}. +- */ +- public ExtractLocalVariableOptions(String name, boolean extractAll) { +- this.name = name; +- this.extractAll = extractAll; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ExtractLocalVariableOptions) { +- ExtractLocalVariableOptions other = (ExtractLocalVariableOptions) obj; +- return +- ObjectUtilities.equals(other.name, name) && +- other.extractAll == extractAll; +- } +- return false; +- } +- +- public static ExtractLocalVariableOptions fromJson(JsonObject jsonObject) { +- String name = jsonObject.get("name").getAsString(); +- boolean extractAll = jsonObject.get("extractAll").getAsBoolean(); +- return new ExtractLocalVariableOptions(name, extractAll); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * True if all occurrences of the expression within the scope in which the variable will be defined +- * should be replaced by a reference to the local variable. The expression used to initiate the +- * refactoring will always be replaced. +- */ +- public boolean extractAll() { +- return extractAll; +- } +- +- /** +- * The name that the local variable should be given. +- */ +- public String getName() { +- return name; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(name); +- builder.append(extractAll); +- return builder.toHashCode(); +- } +- +- /** +- * True if all occurrences of the expression within the scope in which the variable will be defined +- * should be replaced by a reference to the local variable. The expression used to initiate the +- * refactoring will always be replaced. +- */ +- public void setExtractAll(boolean extractAll) { +- this.extractAll = extractAll; +- } +- +- /** +- * The name that the local variable should be given. +- */ +- public void setName(String name) { +- this.name = name; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("name", name); +- jsonObject.addProperty("extractAll", extractAll); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("extractAll="); +- builder.append(extractAll); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java +deleted file mode 100644 +index 6bb32fe8155..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodFeedback.java ++++ /dev/null +@@ -1,272 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ExtractMethodFeedback extends RefactoringFeedback { +- +- public static final ExtractMethodFeedback[] EMPTY_ARRAY = new ExtractMethodFeedback[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset to the beginning of the expression or statements that will be extracted. +- */ +- private final int offset; +- +- /** +- * The length of the expression or statements that will be extracted. +- */ +- private final int length; +- +- /** +- * The proposed return type for the method. If the returned element does not have a declared return +- * type, this field will contain an empty string. +- */ +- private final String returnType; +- +- /** +- * The proposed names for the method. +- */ +- private final List names; +- +- /** +- * True if a getter could be created rather than a method. +- */ +- private final boolean canCreateGetter; +- +- /** +- * The proposed parameters for the method. +- */ +- private final List parameters; +- +- /** +- * The offsets of the expressions or statements that would be replaced by an invocation of the +- * method. +- */ +- private final int[] offsets; +- +- /** +- * The lengths of the expressions or statements that would be replaced by an invocation of the +- * method. The lengths correspond to the offsets. In other words, for a given expression (or block +- * of statements), if the offset of that expression is offsets[i], then the length of that +- * expression is lengths[i]. +- */ +- private final int[] lengths; +- +- /** +- * Constructor for {@link ExtractMethodFeedback}. +- */ +- public ExtractMethodFeedback(int offset, int length, String returnType, List names, boolean canCreateGetter, List parameters, int[] offsets, int[] lengths) { +- this.offset = offset; +- this.length = length; +- this.returnType = returnType; +- this.names = names; +- this.canCreateGetter = canCreateGetter; +- this.parameters = parameters; +- this.offsets = offsets; +- this.lengths = lengths; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ExtractMethodFeedback) { +- ExtractMethodFeedback other = (ExtractMethodFeedback) obj; +- return +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.returnType, returnType) && +- ObjectUtilities.equals(other.names, names) && +- other.canCreateGetter == canCreateGetter && +- ObjectUtilities.equals(other.parameters, parameters) && +- Arrays.equals(other.offsets, offsets) && +- Arrays.equals(other.lengths, lengths); +- } +- return false; +- } +- +- public static ExtractMethodFeedback fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- String returnType = jsonObject.get("returnType").getAsString(); +- List names = JsonUtilities.decodeStringList(jsonObject.get("names").getAsJsonArray()); +- boolean canCreateGetter = jsonObject.get("canCreateGetter").getAsBoolean(); +- List parameters = RefactoringMethodParameter.fromJsonArray(jsonObject.get("parameters").getAsJsonArray()); +- int[] offsets = JsonUtilities.decodeIntArray(jsonObject.get("offsets").getAsJsonArray()); +- int[] lengths = JsonUtilities.decodeIntArray(jsonObject.get("lengths").getAsJsonArray()); +- return new ExtractMethodFeedback(offset, length, returnType, names, canCreateGetter, parameters, offsets, lengths); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * True if a getter could be created rather than a method. +- */ +- public boolean canCreateGetter() { +- return canCreateGetter; +- } +- +- /** +- * The length of the expression or statements that will be extracted. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The lengths of the expressions or statements that would be replaced by an invocation of the +- * method. The lengths correspond to the offsets. In other words, for a given expression (or block +- * of statements), if the offset of that expression is offsets[i], then the length of that +- * expression is lengths[i]. +- */ +- public int[] getLengths() { +- return lengths; +- } +- +- /** +- * The proposed names for the method. +- */ +- public List getNames() { +- return names; +- } +- +- /** +- * The offset to the beginning of the expression or statements that will be extracted. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The offsets of the expressions or statements that would be replaced by an invocation of the +- * method. +- */ +- public int[] getOffsets() { +- return offsets; +- } +- +- /** +- * The proposed parameters for the method. +- */ +- public List getParameters() { +- return parameters; +- } +- +- /** +- * The proposed return type for the method. If the returned element does not have a declared return +- * type, this field will contain an empty string. +- */ +- public String getReturnType() { +- return returnType; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(returnType); +- builder.append(names); +- builder.append(canCreateGetter); +- builder.append(parameters); +- builder.append(offsets); +- builder.append(lengths); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- jsonObject.addProperty("returnType", returnType); +- JsonArray jsonArrayNames = new JsonArray(); +- for (String elt : names) { +- jsonArrayNames.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("names", jsonArrayNames); +- jsonObject.addProperty("canCreateGetter", canCreateGetter); +- JsonArray jsonArrayParameters = new JsonArray(); +- for (RefactoringMethodParameter elt : parameters) { +- jsonArrayParameters.add(elt.toJson()); +- } +- jsonObject.add("parameters", jsonArrayParameters); +- JsonArray jsonArrayOffsets = new JsonArray(); +- for (int elt : offsets) { +- jsonArrayOffsets.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("offsets", jsonArrayOffsets); +- JsonArray jsonArrayLengths = new JsonArray(); +- for (int elt : lengths) { +- jsonArrayLengths.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("lengths", jsonArrayLengths); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("returnType="); +- builder.append(returnType + ", "); +- builder.append("names="); +- builder.append(StringUtils.join(names, ", ") + ", "); +- builder.append("canCreateGetter="); +- builder.append(canCreateGetter + ", "); +- builder.append("parameters="); +- builder.append(StringUtils.join(parameters, ", ") + ", "); +- builder.append("offsets="); +- builder.append(StringUtils.join(offsets, ", ") + ", "); +- builder.append("lengths="); +- builder.append(StringUtils.join(lengths, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java +deleted file mode 100644 +index 1e71e435763..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ExtractMethodOptions.java ++++ /dev/null +@@ -1,261 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ExtractMethodOptions extends RefactoringOptions { +- +- public static final ExtractMethodOptions[] EMPTY_ARRAY = new ExtractMethodOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The return type that should be defined for the method. +- */ +- private String returnType; +- +- /** +- * True if a getter should be created rather than a method. It is an error if this field is true +- * and the list of parameters is non-empty. +- */ +- private boolean createGetter; +- +- /** +- * The name that the method should be given. +- */ +- private String name; +- +- /** +- * The parameters that should be defined for the method. +- * +- * It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL parameter. It is an error +- * if a REQUIRED or POSITIONAL parameter follows a NAMED parameter. +- * +- * - To change the order and/or update proposed parameters, add parameters with the same +- * identifiers as proposed. +- * - To add new parameters, omit their identifier. +- * - To remove some parameters, omit them in this list. +- */ +- private List parameters; +- +- /** +- * True if all occurrences of the expression or statements should be replaced by an invocation of +- * the method. The expression or statements used to initiate the refactoring will always be +- * replaced. +- */ +- private boolean extractAll; +- +- /** +- * Constructor for {@link ExtractMethodOptions}. +- */ +- public ExtractMethodOptions(String returnType, boolean createGetter, String name, List parameters, boolean extractAll) { +- this.returnType = returnType; +- this.createGetter = createGetter; +- this.name = name; +- this.parameters = parameters; +- this.extractAll = extractAll; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ExtractMethodOptions) { +- ExtractMethodOptions other = (ExtractMethodOptions) obj; +- return +- ObjectUtilities.equals(other.returnType, returnType) && +- other.createGetter == createGetter && +- ObjectUtilities.equals(other.name, name) && +- ObjectUtilities.equals(other.parameters, parameters) && +- other.extractAll == extractAll; +- } +- return false; +- } +- +- public static ExtractMethodOptions fromJson(JsonObject jsonObject) { +- String returnType = jsonObject.get("returnType").getAsString(); +- boolean createGetter = jsonObject.get("createGetter").getAsBoolean(); +- String name = jsonObject.get("name").getAsString(); +- List parameters = RefactoringMethodParameter.fromJsonArray(jsonObject.get("parameters").getAsJsonArray()); +- boolean extractAll = jsonObject.get("extractAll").getAsBoolean(); +- return new ExtractMethodOptions(returnType, createGetter, name, parameters, extractAll); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * True if a getter should be created rather than a method. It is an error if this field is true +- * and the list of parameters is non-empty. +- */ +- public boolean createGetter() { +- return createGetter; +- } +- +- /** +- * True if all occurrences of the expression or statements should be replaced by an invocation of +- * the method. The expression or statements used to initiate the refactoring will always be +- * replaced. +- */ +- public boolean extractAll() { +- return extractAll; +- } +- +- /** +- * The name that the method should be given. +- */ +- public String getName() { +- return name; +- } +- +- /** +- * The parameters that should be defined for the method. +- * +- * It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL parameter. It is an error +- * if a REQUIRED or POSITIONAL parameter follows a NAMED parameter. +- * +- * - To change the order and/or update proposed parameters, add parameters with the same +- * identifiers as proposed. +- * - To add new parameters, omit their identifier. +- * - To remove some parameters, omit them in this list. +- */ +- public List getParameters() { +- return parameters; +- } +- +- /** +- * The return type that should be defined for the method. +- */ +- public String getReturnType() { +- return returnType; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(returnType); +- builder.append(createGetter); +- builder.append(name); +- builder.append(parameters); +- builder.append(extractAll); +- return builder.toHashCode(); +- } +- +- /** +- * True if a getter should be created rather than a method. It is an error if this field is true +- * and the list of parameters is non-empty. +- */ +- public void setCreateGetter(boolean createGetter) { +- this.createGetter = createGetter; +- } +- +- /** +- * True if all occurrences of the expression or statements should be replaced by an invocation of +- * the method. The expression or statements used to initiate the refactoring will always be +- * replaced. +- */ +- public void setExtractAll(boolean extractAll) { +- this.extractAll = extractAll; +- } +- +- /** +- * The name that the method should be given. +- */ +- public void setName(String name) { +- this.name = name; +- } +- +- /** +- * The parameters that should be defined for the method. +- * +- * It is an error if a REQUIRED or NAMED parameter follows a POSITIONAL parameter. It is an error +- * if a REQUIRED or POSITIONAL parameter follows a NAMED parameter. +- * +- * - To change the order and/or update proposed parameters, add parameters with the same +- * identifiers as proposed. +- * - To add new parameters, omit their identifier. +- * - To remove some parameters, omit them in this list. +- */ +- public void setParameters(List parameters) { +- this.parameters = parameters; +- } +- +- /** +- * The return type that should be defined for the method. +- */ +- public void setReturnType(String returnType) { +- this.returnType = returnType; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("returnType", returnType); +- jsonObject.addProperty("createGetter", createGetter); +- jsonObject.addProperty("name", name); +- JsonArray jsonArrayParameters = new JsonArray(); +- for (RefactoringMethodParameter elt : parameters) { +- jsonArrayParameters.add(elt.toJson()); +- } +- jsonObject.add("parameters", jsonArrayParameters); +- jsonObject.addProperty("extractAll", extractAll); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("returnType="); +- builder.append(returnType + ", "); +- builder.append("createGetter="); +- builder.append(createGetter + ", "); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("parameters="); +- builder.append(StringUtils.join(parameters, ", ") + ", "); +- builder.append("extractAll="); +- builder.append(extractAll); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java +deleted file mode 100644 +index 827531094da..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/FileKind.java ++++ /dev/null +@@ -1,30 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of files. +- * +- * @coverage dart.server.generated.types +- */ +-public class FileKind { +- +- public static final String LIBRARY = "LIBRARY"; +- +- public static final String PART = "PART"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java +deleted file mode 100644 +index 4a281de9759..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingKind.java ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of folding regions. +- * +- * @coverage dart.server.generated.types +- */ +-public class FoldingKind { +- +- public static final String COMMENT = "COMMENT"; +- +- public static final String CLASS_MEMBER = "CLASS_MEMBER"; +- +- public static final String DIRECTIVES = "DIRECTIVES"; +- +- public static final String DOCUMENTATION_COMMENT = "DOCUMENTATION_COMMENT"; +- +- public static final String TOP_LEVEL_DECLARATION = "TOP_LEVEL_DECLARATION"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java +deleted file mode 100644 +index ebad0e79ca6..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/FoldingRegion.java ++++ /dev/null +@@ -1,153 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a region that can be folded. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class FoldingRegion { +- +- public static final FoldingRegion[] EMPTY_ARRAY = new FoldingRegion[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The kind of the region. +- */ +- private final String kind; +- +- /** +- * The offset of the region to be folded. +- */ +- private final int offset; +- +- /** +- * The length of the region to be folded. +- */ +- private final int length; +- +- /** +- * Constructor for {@link FoldingRegion}. +- */ +- public FoldingRegion(String kind, int offset, int length) { +- this.kind = kind; +- this.offset = offset; +- this.length = length; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof FoldingRegion) { +- FoldingRegion other = (FoldingRegion) obj; +- return +- ObjectUtilities.equals(other.kind, kind) && +- other.offset == offset && +- other.length == length; +- } +- return false; +- } +- +- public static FoldingRegion fromJson(JsonObject jsonObject) { +- String kind = jsonObject.get("kind").getAsString(); +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- return new FoldingRegion(kind, offset, length); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The kind of the region. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The length of the region to be folded. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the region to be folded. +- */ +- public int getOffset() { +- return offset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(kind); +- builder.append(offset); +- builder.append(length); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("kind", kind); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java b/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java +deleted file mode 100644 +index 80975fa5081..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/GeneralAnalysisService.java ++++ /dev/null +@@ -1,29 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the services provided by the analysis domain that are general in nature (that +- * is, are not specific to some list of files). +- * +- * @coverage dart.server.generated.types +- */ +-public class GeneralAnalysisService { +- +- public static final String ANALYZED_FILES = "ANALYZED_FILES"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java +deleted file mode 100644 +index ebbd41056bc..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegion.java ++++ /dev/null +@@ -1,157 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a region that could have special highlighting associated with it. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class HighlightRegion { +- +- public static final HighlightRegion[] EMPTY_ARRAY = new HighlightRegion[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The type of highlight associated with the region. +- */ +- private final String type; +- +- /** +- * The offset of the region to be highlighted. +- */ +- private final int offset; +- +- /** +- * The length of the region to be highlighted. +- */ +- private final int length; +- +- /** +- * Constructor for {@link HighlightRegion}. +- */ +- public HighlightRegion(String type, int offset, int length) { +- this.type = type; +- this.offset = offset; +- this.length = length; +- } +- +- public boolean containsInclusive(int x) { +- return offset <= x && x <= offset + length; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof HighlightRegion) { +- HighlightRegion other = (HighlightRegion) obj; +- return +- ObjectUtilities.equals(other.type, type) && +- other.offset == offset && +- other.length == length; +- } +- return false; +- } +- +- public static HighlightRegion fromJson(JsonObject jsonObject) { +- String type = jsonObject.get("type").getAsString(); +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- return new HighlightRegion(type, offset, length); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The length of the region to be highlighted. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the region to be highlighted. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The type of highlight associated with the region. +- */ +- public String getType() { +- return type; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(type); +- builder.append(offset); +- builder.append(length); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("type", type); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("type="); +- builder.append(type + ", "); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java +deleted file mode 100644 +index 15d1373a801..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java ++++ /dev/null +@@ -1,319 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of highlighting that can be applied to files. +- * +- * @coverage dart.server.generated.types +- */ +-public class HighlightRegionType { +- +- public static final String ANNOTATION = "ANNOTATION"; +- +- public static final String BUILT_IN = "BUILT_IN"; +- +- public static final String CLASS = "CLASS"; +- +- public static final String COMMENT_BLOCK = "COMMENT_BLOCK"; +- +- public static final String COMMENT_DOCUMENTATION = "COMMENT_DOCUMENTATION"; +- +- public static final String COMMENT_END_OF_LINE = "COMMENT_END_OF_LINE"; +- +- public static final String CONSTRUCTOR = "CONSTRUCTOR"; +- +- public static final String DIRECTIVE = "DIRECTIVE"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String DYNAMIC_TYPE = "DYNAMIC_TYPE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String DYNAMIC_LOCAL_VARIABLE_DECLARATION = "DYNAMIC_LOCAL_VARIABLE_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String DYNAMIC_LOCAL_VARIABLE_REFERENCE = "DYNAMIC_LOCAL_VARIABLE_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String DYNAMIC_PARAMETER_DECLARATION = "DYNAMIC_PARAMETER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String DYNAMIC_PARAMETER_REFERENCE = "DYNAMIC_PARAMETER_REFERENCE"; +- +- public static final String ENUM = "ENUM"; +- +- public static final String ENUM_CONSTANT = "ENUM_CONSTANT"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String FIELD = "FIELD"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String FIELD_STATIC = "FIELD_STATIC"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String FUNCTION = "FUNCTION"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String FUNCTION_DECLARATION = "FUNCTION_DECLARATION"; +- +- public static final String FUNCTION_TYPE_ALIAS = "FUNCTION_TYPE_ALIAS"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String GETTER_DECLARATION = "GETTER_DECLARATION"; +- +- public static final String IDENTIFIER_DEFAULT = "IDENTIFIER_DEFAULT"; +- +- public static final String IMPORT_PREFIX = "IMPORT_PREFIX"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_FIELD_DECLARATION = "INSTANCE_FIELD_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_FIELD_REFERENCE = "INSTANCE_FIELD_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_GETTER_DECLARATION = "INSTANCE_GETTER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_GETTER_REFERENCE = "INSTANCE_GETTER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_METHOD_DECLARATION = "INSTANCE_METHOD_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_METHOD_REFERENCE = "INSTANCE_METHOD_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_SETTER_DECLARATION = "INSTANCE_SETTER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INSTANCE_SETTER_REFERENCE = "INSTANCE_SETTER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String INVALID_STRING_ESCAPE = "INVALID_STRING_ESCAPE"; +- +- public static final String KEYWORD = "KEYWORD"; +- +- public static final String LABEL = "LABEL"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String LIBRARY_NAME = "LIBRARY_NAME"; +- +- public static final String LITERAL_BOOLEAN = "LITERAL_BOOLEAN"; +- +- public static final String LITERAL_DOUBLE = "LITERAL_DOUBLE"; +- +- public static final String LITERAL_INTEGER = "LITERAL_INTEGER"; +- +- public static final String LITERAL_LIST = "LITERAL_LIST"; +- +- public static final String LITERAL_MAP = "LITERAL_MAP"; +- +- public static final String LITERAL_STRING = "LITERAL_STRING"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String LOCAL_FUNCTION_DECLARATION = "LOCAL_FUNCTION_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String LOCAL_FUNCTION_REFERENCE = "LOCAL_FUNCTION_REFERENCE"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String LOCAL_VARIABLE = "LOCAL_VARIABLE"; +- +- public static final String LOCAL_VARIABLE_DECLARATION = "LOCAL_VARIABLE_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String LOCAL_VARIABLE_REFERENCE = "LOCAL_VARIABLE_REFERENCE"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String METHOD = "METHOD"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String METHOD_DECLARATION = "METHOD_DECLARATION"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String METHOD_DECLARATION_STATIC = "METHOD_DECLARATION_STATIC"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String METHOD_STATIC = "METHOD_STATIC"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String PARAMETER = "PARAMETER"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String SETTER_DECLARATION = "SETTER_DECLARATION"; +- +- /** +- * Only for version 1 of highlight. +- */ +- public static final String TOP_LEVEL_VARIABLE = "TOP_LEVEL_VARIABLE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String PARAMETER_DECLARATION = "PARAMETER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String PARAMETER_REFERENCE = "PARAMETER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_FIELD_DECLARATION = "STATIC_FIELD_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_GETTER_DECLARATION = "STATIC_GETTER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_GETTER_REFERENCE = "STATIC_GETTER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_METHOD_DECLARATION = "STATIC_METHOD_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_METHOD_REFERENCE = "STATIC_METHOD_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_SETTER_DECLARATION = "STATIC_SETTER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String STATIC_SETTER_REFERENCE = "STATIC_SETTER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_FUNCTION_DECLARATION = "TOP_LEVEL_FUNCTION_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_FUNCTION_REFERENCE = "TOP_LEVEL_FUNCTION_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_GETTER_DECLARATION = "TOP_LEVEL_GETTER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_GETTER_REFERENCE = "TOP_LEVEL_GETTER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_SETTER_DECLARATION = "TOP_LEVEL_SETTER_DECLARATION"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_SETTER_REFERENCE = "TOP_LEVEL_SETTER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String TOP_LEVEL_VARIABLE_DECLARATION = "TOP_LEVEL_VARIABLE_DECLARATION"; +- +- public static final String TYPE_NAME_DYNAMIC = "TYPE_NAME_DYNAMIC"; +- +- public static final String TYPE_PARAMETER = "TYPE_PARAMETER"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String UNRESOLVED_INSTANCE_MEMBER_REFERENCE = "UNRESOLVED_INSTANCE_MEMBER_REFERENCE"; +- +- /** +- * Only for version 2 of highlight. +- */ +- public static final String VALID_STRING_ESCAPE = "VALID_STRING_ESCAPE"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java b/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java +deleted file mode 100644 +index b9ca9819825..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/HoverInformation.java ++++ /dev/null +@@ -1,372 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * The hover information associated with a specific location. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class HoverInformation { +- +- public static final HoverInformation[] EMPTY_ARRAY = new HoverInformation[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the range of characters that encompasses the cursor position and has the same +- * hover information as the cursor position. +- */ +- private final int offset; +- +- /** +- * The length of the range of characters that encompasses the cursor position and has the same +- * hover information as the cursor position. +- */ +- private final int length; +- +- /** +- * The path to the defining compilation unit of the library in which the referenced element is +- * declared. This data is omitted if there is no referenced element, or if the element is declared +- * inside an HTML file. +- */ +- private final String containingLibraryPath; +- +- /** +- * The name of the library in which the referenced element is declared. This data is omitted if +- * there is no referenced element, or if the element is declared inside an HTML file. +- */ +- private final String containingLibraryName; +- +- /** +- * A human-readable description of the class declaring the element being referenced. This data is +- * omitted if there is no referenced element, or if the element is not a class member. +- */ +- private final String containingClassDescription; +- +- /** +- * The dartdoc associated with the referenced element. Other than the removal of the comment +- * delimiters, including leading asterisks in the case of a block comment, the dartdoc is +- * unprocessed markdown. This data is omitted if there is no referenced element, or if the element +- * has no dartdoc. +- */ +- private final String dartdoc; +- +- /** +- * A human-readable description of the element being referenced. This data is omitted if there is +- * no referenced element. +- */ +- private final String elementDescription; +- +- /** +- * A human-readable description of the kind of element being referenced (such as "class" or +- * "function type alias"). This data is omitted if there is no referenced element. +- */ +- private final String elementKind; +- +- /** +- * True if the referenced element is deprecated. +- */ +- private final Boolean isDeprecated; +- +- /** +- * A human-readable description of the parameter corresponding to the expression being hovered +- * over. This data is omitted if the location is not in an argument to a function. +- */ +- private final String parameter; +- +- /** +- * The name of the propagated type of the expression. This data is omitted if the location does not +- * correspond to an expression or if there is no propagated type information. +- */ +- private final String propagatedType; +- +- /** +- * The name of the static type of the expression. This data is omitted if the location does not +- * correspond to an expression. +- */ +- private final String staticType; +- +- /** +- * Constructor for {@link HoverInformation}. +- */ +- public HoverInformation(int offset, int length, String containingLibraryPath, String containingLibraryName, String containingClassDescription, String dartdoc, String elementDescription, String elementKind, Boolean isDeprecated, String parameter, String propagatedType, String staticType) { +- this.offset = offset; +- this.length = length; +- this.containingLibraryPath = containingLibraryPath; +- this.containingLibraryName = containingLibraryName; +- this.containingClassDescription = containingClassDescription; +- this.dartdoc = dartdoc; +- this.elementDescription = elementDescription; +- this.elementKind = elementKind; +- this.isDeprecated = isDeprecated; +- this.parameter = parameter; +- this.propagatedType = propagatedType; +- this.staticType = staticType; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof HoverInformation) { +- HoverInformation other = (HoverInformation) obj; +- return +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.containingLibraryPath, containingLibraryPath) && +- ObjectUtilities.equals(other.containingLibraryName, containingLibraryName) && +- ObjectUtilities.equals(other.containingClassDescription, containingClassDescription) && +- ObjectUtilities.equals(other.dartdoc, dartdoc) && +- ObjectUtilities.equals(other.elementDescription, elementDescription) && +- ObjectUtilities.equals(other.elementKind, elementKind) && +- ObjectUtilities.equals(other.isDeprecated, isDeprecated) && +- ObjectUtilities.equals(other.parameter, parameter) && +- ObjectUtilities.equals(other.propagatedType, propagatedType) && +- ObjectUtilities.equals(other.staticType, staticType); +- } +- return false; +- } +- +- public static HoverInformation fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- String containingLibraryPath = jsonObject.get("containingLibraryPath") == null ? null : jsonObject.get("containingLibraryPath").getAsString(); +- String containingLibraryName = jsonObject.get("containingLibraryName") == null ? null : jsonObject.get("containingLibraryName").getAsString(); +- String containingClassDescription = jsonObject.get("containingClassDescription") == null ? null : jsonObject.get("containingClassDescription").getAsString(); +- String dartdoc = jsonObject.get("dartdoc") == null ? null : jsonObject.get("dartdoc").getAsString(); +- String elementDescription = jsonObject.get("elementDescription") == null ? null : jsonObject.get("elementDescription").getAsString(); +- String elementKind = jsonObject.get("elementKind") == null ? null : jsonObject.get("elementKind").getAsString(); +- Boolean isDeprecated = jsonObject.get("isDeprecated") == null ? null : jsonObject.get("isDeprecated").getAsBoolean(); +- String parameter = jsonObject.get("parameter") == null ? null : jsonObject.get("parameter").getAsString(); +- String propagatedType = jsonObject.get("propagatedType") == null ? null : jsonObject.get("propagatedType").getAsString(); +- String staticType = jsonObject.get("staticType") == null ? null : jsonObject.get("staticType").getAsString(); +- return new HoverInformation(offset, length, containingLibraryPath, containingLibraryName, containingClassDescription, dartdoc, elementDescription, elementKind, isDeprecated, parameter, propagatedType, staticType); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A human-readable description of the class declaring the element being referenced. This data is +- * omitted if there is no referenced element, or if the element is not a class member. +- */ +- public String getContainingClassDescription() { +- return containingClassDescription; +- } +- +- /** +- * The name of the library in which the referenced element is declared. This data is omitted if +- * there is no referenced element, or if the element is declared inside an HTML file. +- */ +- public String getContainingLibraryName() { +- return containingLibraryName; +- } +- +- /** +- * The path to the defining compilation unit of the library in which the referenced element is +- * declared. This data is omitted if there is no referenced element, or if the element is declared +- * inside an HTML file. +- */ +- public String getContainingLibraryPath() { +- return containingLibraryPath; +- } +- +- /** +- * The dartdoc associated with the referenced element. Other than the removal of the comment +- * delimiters, including leading asterisks in the case of a block comment, the dartdoc is +- * unprocessed markdown. This data is omitted if there is no referenced element, or if the element +- * has no dartdoc. +- */ +- public String getDartdoc() { +- return dartdoc; +- } +- +- /** +- * A human-readable description of the element being referenced. This data is omitted if there is +- * no referenced element. +- */ +- public String getElementDescription() { +- return elementDescription; +- } +- +- /** +- * A human-readable description of the kind of element being referenced (such as "class" or +- * "function type alias"). This data is omitted if there is no referenced element. +- */ +- public String getElementKind() { +- return elementKind; +- } +- +- /** +- * True if the referenced element is deprecated. +- */ +- public Boolean getIsDeprecated() { +- return isDeprecated; +- } +- +- /** +- * The length of the range of characters that encompasses the cursor position and has the same +- * hover information as the cursor position. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the range of characters that encompasses the cursor position and has the same +- * hover information as the cursor position. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * A human-readable description of the parameter corresponding to the expression being hovered +- * over. This data is omitted if the location is not in an argument to a function. +- */ +- public String getParameter() { +- return parameter; +- } +- +- /** +- * The name of the propagated type of the expression. This data is omitted if the location does not +- * correspond to an expression or if there is no propagated type information. +- */ +- public String getPropagatedType() { +- return propagatedType; +- } +- +- /** +- * The name of the static type of the expression. This data is omitted if the location does not +- * correspond to an expression. +- */ +- public String getStaticType() { +- return staticType; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(containingLibraryPath); +- builder.append(containingLibraryName); +- builder.append(containingClassDescription); +- builder.append(dartdoc); +- builder.append(elementDescription); +- builder.append(elementKind); +- builder.append(isDeprecated); +- builder.append(parameter); +- builder.append(propagatedType); +- builder.append(staticType); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- if (containingLibraryPath != null) { +- jsonObject.addProperty("containingLibraryPath", containingLibraryPath); +- } +- if (containingLibraryName != null) { +- jsonObject.addProperty("containingLibraryName", containingLibraryName); +- } +- if (containingClassDescription != null) { +- jsonObject.addProperty("containingClassDescription", containingClassDescription); +- } +- if (dartdoc != null) { +- jsonObject.addProperty("dartdoc", dartdoc); +- } +- if (elementDescription != null) { +- jsonObject.addProperty("elementDescription", elementDescription); +- } +- if (elementKind != null) { +- jsonObject.addProperty("elementKind", elementKind); +- } +- if (isDeprecated != null) { +- jsonObject.addProperty("isDeprecated", isDeprecated); +- } +- if (parameter != null) { +- jsonObject.addProperty("parameter", parameter); +- } +- if (propagatedType != null) { +- jsonObject.addProperty("propagatedType", propagatedType); +- } +- if (staticType != null) { +- jsonObject.addProperty("staticType", staticType); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("containingLibraryPath="); +- builder.append(containingLibraryPath + ", "); +- builder.append("containingLibraryName="); +- builder.append(containingLibraryName + ", "); +- builder.append("containingClassDescription="); +- builder.append(containingClassDescription + ", "); +- builder.append("dartdoc="); +- builder.append(dartdoc + ", "); +- builder.append("elementDescription="); +- builder.append(elementDescription + ", "); +- builder.append("elementKind="); +- builder.append(elementKind + ", "); +- builder.append("isDeprecated="); +- builder.append(isDeprecated + ", "); +- builder.append("parameter="); +- builder.append(parameter + ", "); +- builder.append("propagatedType="); +- builder.append(propagatedType + ", "); +- builder.append("staticType="); +- builder.append(staticType); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java +deleted file mode 100644 +index 5c08f6b2acf..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedClass.java ++++ /dev/null +@@ -1,134 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a class that is implemented or extended. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ImplementedClass { +- +- public static final ImplementedClass[] EMPTY_ARRAY = new ImplementedClass[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the name of the implemented class. +- */ +- private final int offset; +- +- /** +- * The length of the name of the implemented class. +- */ +- private final int length; +- +- /** +- * Constructor for {@link ImplementedClass}. +- */ +- public ImplementedClass(int offset, int length) { +- this.offset = offset; +- this.length = length; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ImplementedClass) { +- ImplementedClass other = (ImplementedClass) obj; +- return +- other.offset == offset && +- other.length == length; +- } +- return false; +- } +- +- public static ImplementedClass fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- return new ImplementedClass(offset, length); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The length of the name of the implemented class. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the name of the implemented class. +- */ +- public int getOffset() { +- return offset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java b/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java +deleted file mode 100644 +index a18d6a4ae57..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ImplementedMember.java ++++ /dev/null +@@ -1,134 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a class member that is implemented or overridden. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ImplementedMember { +- +- public static final ImplementedMember[] EMPTY_ARRAY = new ImplementedMember[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the name of the implemented member. +- */ +- private final int offset; +- +- /** +- * The length of the name of the implemented member. +- */ +- private final int length; +- +- /** +- * Constructor for {@link ImplementedMember}. +- */ +- public ImplementedMember(int offset, int length) { +- this.offset = offset; +- this.length = length; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ImplementedMember) { +- ImplementedMember other = (ImplementedMember) obj; +- return +- other.offset == offset && +- other.length == length; +- } +- return false; +- } +- +- public static ImplementedMember fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- return new ImplementedMember(offset, length); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The length of the name of the implemented member. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the name of the implemented member. +- */ +- public int getOffset() { +- return offset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java b/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java +deleted file mode 100644 +index 7f5b0e73ffd..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ImportedElements.java ++++ /dev/null +@@ -1,158 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of the elements that are referenced in a region of a file that come from a single +- * imported library. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class ImportedElements { +- +- public static final ImportedElements[] EMPTY_ARRAY = new ImportedElements[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The absolute and normalized path of the file containing the library. +- */ +- private final String path; +- +- /** +- * The prefix that was used when importing the library into the original source. +- */ +- private final String prefix; +- +- /** +- * The names of the elements imported from the library. +- */ +- private final List elements; +- +- /** +- * Constructor for {@link ImportedElements}. +- */ +- public ImportedElements(String path, String prefix, List elements) { +- this.path = path; +- this.prefix = prefix; +- this.elements = elements; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof ImportedElements) { +- ImportedElements other = (ImportedElements) obj; +- return +- ObjectUtilities.equals(other.path, path) && +- ObjectUtilities.equals(other.prefix, prefix) && +- ObjectUtilities.equals(other.elements, elements); +- } +- return false; +- } +- +- public static ImportedElements fromJson(JsonObject jsonObject) { +- String path = jsonObject.get("path").getAsString(); +- String prefix = jsonObject.get("prefix").getAsString(); +- List elements = JsonUtilities.decodeStringList(jsonObject.get("elements").getAsJsonArray()); +- return new ImportedElements(path, prefix, elements); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The names of the elements imported from the library. +- */ +- public List getElements() { +- return elements; +- } +- +- /** +- * The absolute and normalized path of the file containing the library. +- */ +- public String getPath() { +- return path; +- } +- +- /** +- * The prefix that was used when importing the library into the original source. +- */ +- public String getPrefix() { +- return prefix; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(path); +- builder.append(prefix); +- builder.append(elements); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("path", path); +- jsonObject.addProperty("prefix", prefix); +- JsonArray jsonArrayElements = new JsonArray(); +- for (String elt : elements) { +- jsonArrayElements.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("elements", jsonArrayElements); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("path="); +- builder.append(path + ", "); +- builder.append("prefix="); +- builder.append(prefix + ", "); +- builder.append("elements="); +- builder.append(StringUtils.join(elements, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java +deleted file mode 100644 +index 65e4a869f41..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineLocalVariableFeedback.java ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class InlineLocalVariableFeedback extends RefactoringFeedback { +- +- public static final InlineLocalVariableFeedback[] EMPTY_ARRAY = new InlineLocalVariableFeedback[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The name of the variable being inlined. +- */ +- private final String name; +- +- /** +- * The number of times the variable occurs. +- */ +- private final int occurrences; +- +- /** +- * Constructor for {@link InlineLocalVariableFeedback}. +- */ +- public InlineLocalVariableFeedback(String name, int occurrences) { +- this.name = name; +- this.occurrences = occurrences; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof InlineLocalVariableFeedback) { +- InlineLocalVariableFeedback other = (InlineLocalVariableFeedback) obj; +- return +- ObjectUtilities.equals(other.name, name) && +- other.occurrences == occurrences; +- } +- return false; +- } +- +- public static InlineLocalVariableFeedback fromJson(JsonObject jsonObject) { +- String name = jsonObject.get("name").getAsString(); +- int occurrences = jsonObject.get("occurrences").getAsInt(); +- return new InlineLocalVariableFeedback(name, occurrences); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The name of the variable being inlined. +- */ +- public String getName() { +- return name; +- } +- +- /** +- * The number of times the variable occurs. +- */ +- public int getOccurrences() { +- return occurrences; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(name); +- builder.append(occurrences); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("name", name); +- jsonObject.addProperty("occurrences", occurrences); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("occurrences="); +- builder.append(occurrences); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java +deleted file mode 100644 +index 6d80cfa5fbe..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodFeedback.java ++++ /dev/null +@@ -1,155 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class InlineMethodFeedback extends RefactoringFeedback { +- +- public static final InlineMethodFeedback[] EMPTY_ARRAY = new InlineMethodFeedback[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The name of the class enclosing the method being inlined. If not a class member is being +- * inlined, this field will be absent. +- */ +- private final String className; +- +- /** +- * The name of the method (or function) being inlined. +- */ +- private final String methodName; +- +- /** +- * True if the declaration of the method is selected. So all references should be inlined. +- */ +- private final boolean isDeclaration; +- +- /** +- * Constructor for {@link InlineMethodFeedback}. +- */ +- public InlineMethodFeedback(String className, String methodName, boolean isDeclaration) { +- this.className = className; +- this.methodName = methodName; +- this.isDeclaration = isDeclaration; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof InlineMethodFeedback) { +- InlineMethodFeedback other = (InlineMethodFeedback) obj; +- return +- ObjectUtilities.equals(other.className, className) && +- ObjectUtilities.equals(other.methodName, methodName) && +- other.isDeclaration == isDeclaration; +- } +- return false; +- } +- +- public static InlineMethodFeedback fromJson(JsonObject jsonObject) { +- String className = jsonObject.get("className") == null ? null : jsonObject.get("className").getAsString(); +- String methodName = jsonObject.get("methodName").getAsString(); +- boolean isDeclaration = jsonObject.get("isDeclaration").getAsBoolean(); +- return new InlineMethodFeedback(className, methodName, isDeclaration); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The name of the class enclosing the method being inlined. If not a class member is being +- * inlined, this field will be absent. +- */ +- public String getClassName() { +- return className; +- } +- +- /** +- * True if the declaration of the method is selected. So all references should be inlined. +- */ +- public boolean isDeclaration() { +- return isDeclaration; +- } +- +- /** +- * The name of the method (or function) being inlined. +- */ +- public String getMethodName() { +- return methodName; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(className); +- builder.append(methodName); +- builder.append(isDeclaration); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- if (className != null) { +- jsonObject.addProperty("className", className); +- } +- jsonObject.addProperty("methodName", methodName); +- jsonObject.addProperty("isDeclaration", isDeclaration); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("className="); +- builder.append(className + ", "); +- builder.append("methodName="); +- builder.append(methodName + ", "); +- builder.append("isDeclaration="); +- builder.append(isDeclaration); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java +deleted file mode 100644 +index c13daa7de97..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/InlineMethodOptions.java ++++ /dev/null +@@ -1,152 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class InlineMethodOptions extends RefactoringOptions { +- +- public static final InlineMethodOptions[] EMPTY_ARRAY = new InlineMethodOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * True if the method being inlined should be removed. It is an error if this field is true and +- * inlineAll is false. +- */ +- private boolean deleteSource; +- +- /** +- * True if all invocations of the method should be inlined, or false if only the invocation site +- * used to create this refactoring should be inlined. +- */ +- private boolean inlineAll; +- +- /** +- * Constructor for {@link InlineMethodOptions}. +- */ +- public InlineMethodOptions(boolean deleteSource, boolean inlineAll) { +- this.deleteSource = deleteSource; +- this.inlineAll = inlineAll; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof InlineMethodOptions) { +- InlineMethodOptions other = (InlineMethodOptions) obj; +- return +- other.deleteSource == deleteSource && +- other.inlineAll == inlineAll; +- } +- return false; +- } +- +- public static InlineMethodOptions fromJson(JsonObject jsonObject) { +- boolean deleteSource = jsonObject.get("deleteSource").getAsBoolean(); +- boolean inlineAll = jsonObject.get("inlineAll").getAsBoolean(); +- return new InlineMethodOptions(deleteSource, inlineAll); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * True if the method being inlined should be removed. It is an error if this field is true and +- * inlineAll is false. +- */ +- public boolean deleteSource() { +- return deleteSource; +- } +- +- /** +- * True if all invocations of the method should be inlined, or false if only the invocation site +- * used to create this refactoring should be inlined. +- */ +- public boolean inlineAll() { +- return inlineAll; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(deleteSource); +- builder.append(inlineAll); +- return builder.toHashCode(); +- } +- +- /** +- * True if the method being inlined should be removed. It is an error if this field is true and +- * inlineAll is false. +- */ +- public void setDeleteSource(boolean deleteSource) { +- this.deleteSource = deleteSource; +- } +- +- /** +- * True if all invocations of the method should be inlined, or false if only the invocation site +- * used to create this refactoring should be inlined. +- */ +- public void setInlineAll(boolean inlineAll) { +- this.inlineAll = inlineAll; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("deleteSource", deleteSource); +- jsonObject.addProperty("inlineAll", inlineAll); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("deleteSource="); +- builder.append(deleteSource + ", "); +- builder.append("inlineAll="); +- builder.append(inlineAll); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java b/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java +deleted file mode 100644 +index 92fabffc587..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/KytheEntry.java ++++ /dev/null +@@ -1,202 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * This object matches the format and documentation of the Entry object documented in the Kythe +- * Storage Model. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class KytheEntry { +- +- public static final KytheEntry[] EMPTY_ARRAY = new KytheEntry[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The ticket of the source node. +- */ +- private final KytheVName source; +- +- /** +- * An edge label. The schema defines which labels are meaningful. +- */ +- private final String kind; +- +- /** +- * The ticket of the target node. +- */ +- private final KytheVName target; +- +- /** +- * A fact label. The schema defines which fact labels are meaningful. +- */ +- private final String fact; +- +- /** +- * The String value of the fact. +- */ +- private final int[] value; +- +- /** +- * Constructor for {@link KytheEntry}. +- */ +- public KytheEntry(KytheVName source, String kind, KytheVName target, String fact, int[] value) { +- this.source = source; +- this.kind = kind; +- this.target = target; +- this.fact = fact; +- this.value = value; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof KytheEntry) { +- KytheEntry other = (KytheEntry) obj; +- return +- ObjectUtilities.equals(other.source, source) && +- ObjectUtilities.equals(other.kind, kind) && +- ObjectUtilities.equals(other.target, target) && +- ObjectUtilities.equals(other.fact, fact) && +- Arrays.equals(other.value, value); +- } +- return false; +- } +- +- public static KytheEntry fromJson(JsonObject jsonObject) { +- KytheVName source = KytheVName.fromJson(jsonObject.get("source").getAsJsonObject()); +- String kind = jsonObject.get("kind") == null ? null : jsonObject.get("kind").getAsString(); +- KytheVName target = jsonObject.get("target") == null ? null : KytheVName.fromJson(jsonObject.get("target").getAsJsonObject()); +- String fact = jsonObject.get("fact").getAsString(); +- int[] value = jsonObject.get("value") == null ? null : JsonUtilities.decodeIntArray(jsonObject.get("value").getAsJsonArray()); +- return new KytheEntry(source, kind, target, fact, value); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A fact label. The schema defines which fact labels are meaningful. +- */ +- public String getFact() { +- return fact; +- } +- +- /** +- * An edge label. The schema defines which labels are meaningful. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The ticket of the source node. +- */ +- public KytheVName getSource() { +- return source; +- } +- +- /** +- * The ticket of the target node. +- */ +- public KytheVName getTarget() { +- return target; +- } +- +- /** +- * The String value of the fact. +- */ +- public int[] getValue() { +- return value; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(source); +- builder.append(kind); +- builder.append(target); +- builder.append(fact); +- builder.append(value); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.add("source", source.toJson()); +- if (kind != null) { +- jsonObject.addProperty("kind", kind); +- } +- if (target != null) { +- jsonObject.add("target", target.toJson()); +- } +- jsonObject.addProperty("fact", fact); +- if (value != null) { +- JsonArray jsonArrayValue = new JsonArray(); +- for (int elt : value) { +- jsonArrayValue.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("value", jsonArrayValue); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("source="); +- builder.append(source + ", "); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("target="); +- builder.append(target + ", "); +- builder.append("fact="); +- builder.append(fact + ", "); +- builder.append("value="); +- builder.append(StringUtils.join(value, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java b/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java +deleted file mode 100644 +index 2c56a72d888..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/KytheVName.java ++++ /dev/null +@@ -1,200 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * This object matches the format and documentation of the Vector-Name object documented in the +- * Kythe Storage Model. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class KytheVName { +- +- public static final KytheVName[] EMPTY_ARRAY = new KytheVName[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * An opaque signature generated by the analyzer. +- */ +- private final String signature; +- +- /** +- * The corpus of source code this KytheVName belongs to. Loosely, a corpus is a collection of +- * related files, such as the contents of a given source repository. +- */ +- private final String corpus; +- +- /** +- * A corpus-specific root label, typically a directory path or project identifier, denoting a +- * distinct subset of the corpus. This may also be used to designate virtual collections like +- * generated files. +- */ +- private final String root; +- +- /** +- * A path-structured label describing the “location” of the named object relative to the corpus and +- * the root. +- */ +- private final String path; +- +- /** +- * The language this name belongs to. +- */ +- private final String language; +- +- /** +- * Constructor for {@link KytheVName}. +- */ +- public KytheVName(String signature, String corpus, String root, String path, String language) { +- this.signature = signature; +- this.corpus = corpus; +- this.root = root; +- this.path = path; +- this.language = language; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof KytheVName) { +- KytheVName other = (KytheVName) obj; +- return +- ObjectUtilities.equals(other.signature, signature) && +- ObjectUtilities.equals(other.corpus, corpus) && +- ObjectUtilities.equals(other.root, root) && +- ObjectUtilities.equals(other.path, path) && +- ObjectUtilities.equals(other.language, language); +- } +- return false; +- } +- +- public static KytheVName fromJson(JsonObject jsonObject) { +- String signature = jsonObject.get("signature").getAsString(); +- String corpus = jsonObject.get("corpus").getAsString(); +- String root = jsonObject.get("root").getAsString(); +- String path = jsonObject.get("path").getAsString(); +- String language = jsonObject.get("language").getAsString(); +- return new KytheVName(signature, corpus, root, path, language); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The corpus of source code this KytheVName belongs to. Loosely, a corpus is a collection of +- * related files, such as the contents of a given source repository. +- */ +- public String getCorpus() { +- return corpus; +- } +- +- /** +- * The language this name belongs to. +- */ +- public String getLanguage() { +- return language; +- } +- +- /** +- * A path-structured label describing the “location” of the named object relative to the corpus and +- * the root. +- */ +- public String getPath() { +- return path; +- } +- +- /** +- * A corpus-specific root label, typically a directory path or project identifier, denoting a +- * distinct subset of the corpus. This may also be used to designate virtual collections like +- * generated files. +- */ +- public String getRoot() { +- return root; +- } +- +- /** +- * An opaque signature generated by the analyzer. +- */ +- public String getSignature() { +- return signature; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(signature); +- builder.append(corpus); +- builder.append(root); +- builder.append(path); +- builder.append(language); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("signature", signature); +- jsonObject.addProperty("corpus", corpus); +- jsonObject.addProperty("root", root); +- jsonObject.addProperty("path", path); +- jsonObject.addProperty("language", language); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("signature="); +- builder.append(signature + ", "); +- builder.append("corpus="); +- builder.append(corpus + ", "); +- builder.append("root="); +- builder.append(root + ", "); +- builder.append("path="); +- builder.append(path + ", "); +- builder.append("language="); +- builder.append(language); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java +deleted file mode 100644 +index b83f30447ce..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditGroup.java ++++ /dev/null +@@ -1,165 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A collection of positions that should be linked (edited simultaneously) for the purposes of +- * updating code after a source change. For example, if a set of edits introduced a new variable +- * name, the group would contain all of the positions of the variable name so that if the client +- * wanted to let the user edit the variable name after the operation, all occurrences of the name +- * could be edited simultaneously. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class LinkedEditGroup { +- +- public static final LinkedEditGroup[] EMPTY_ARRAY = new LinkedEditGroup[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The positions of the regions that should be edited simultaneously. +- */ +- private final List positions; +- +- /** +- * The length of the regions that should be edited simultaneously. +- */ +- private final int length; +- +- /** +- * Pre-computed suggestions for what every region might want to be changed to. +- */ +- private final List suggestions; +- +- /** +- * Constructor for {@link LinkedEditGroup}. +- */ +- public LinkedEditGroup(List positions, int length, List suggestions) { +- this.positions = positions; +- this.length = length; +- this.suggestions = suggestions; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof LinkedEditGroup) { +- LinkedEditGroup other = (LinkedEditGroup) obj; +- return +- ObjectUtilities.equals(other.positions, positions) && +- other.length == length && +- ObjectUtilities.equals(other.suggestions, suggestions); +- } +- return false; +- } +- +- public static LinkedEditGroup fromJson(JsonObject jsonObject) { +- List positions = Position.fromJsonArray(jsonObject.get("positions").getAsJsonArray()); +- int length = jsonObject.get("length").getAsInt(); +- List suggestions = LinkedEditSuggestion.fromJsonArray(jsonObject.get("suggestions").getAsJsonArray()); +- return new LinkedEditGroup(positions, length, suggestions); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The length of the regions that should be edited simultaneously. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The positions of the regions that should be edited simultaneously. +- */ +- public List getPositions() { +- return positions; +- } +- +- /** +- * Pre-computed suggestions for what every region might want to be changed to. +- */ +- public List getSuggestions() { +- return suggestions; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(positions); +- builder.append(length); +- builder.append(suggestions); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- JsonArray jsonArrayPositions = new JsonArray(); +- for (Position elt : positions) { +- jsonArrayPositions.add(elt.toJson()); +- } +- jsonObject.add("positions", jsonArrayPositions); +- jsonObject.addProperty("length", length); +- JsonArray jsonArraySuggestions = new JsonArray(); +- for (LinkedEditSuggestion elt : suggestions) { +- jsonArraySuggestions.add(elt.toJson()); +- } +- jsonObject.add("suggestions", jsonArraySuggestions); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("positions="); +- builder.append(StringUtils.join(positions, ", ") + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("suggestions="); +- builder.append(StringUtils.join(suggestions, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java +deleted file mode 100644 +index 2537bc50c24..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestion.java ++++ /dev/null +@@ -1,135 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A suggestion of a value that could be used to replace all of the linked edit regions in a +- * LinkedEditGroup. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class LinkedEditSuggestion { +- +- public static final LinkedEditSuggestion[] EMPTY_ARRAY = new LinkedEditSuggestion[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The value that could be used to replace all of the linked edit regions. +- */ +- private final String value; +- +- /** +- * The kind of value being proposed. +- */ +- private final String kind; +- +- /** +- * Constructor for {@link LinkedEditSuggestion}. +- */ +- public LinkedEditSuggestion(String value, String kind) { +- this.value = value; +- this.kind = kind; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof LinkedEditSuggestion) { +- LinkedEditSuggestion other = (LinkedEditSuggestion) obj; +- return +- ObjectUtilities.equals(other.value, value) && +- ObjectUtilities.equals(other.kind, kind); +- } +- return false; +- } +- +- public static LinkedEditSuggestion fromJson(JsonObject jsonObject) { +- String value = jsonObject.get("value").getAsString(); +- String kind = jsonObject.get("kind").getAsString(); +- return new LinkedEditSuggestion(value, kind); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The kind of value being proposed. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The value that could be used to replace all of the linked edit regions. +- */ +- public String getValue() { +- return value; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(value); +- builder.append(kind); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("value", value); +- jsonObject.addProperty("kind", kind); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("value="); +- builder.append(value + ", "); +- builder.append("kind="); +- builder.append(kind); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java +deleted file mode 100644 +index be193e0b6fe..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/LinkedEditSuggestionKind.java ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kind of values that can be suggested for a linked edit. +- * +- * @coverage dart.server.generated.types +- */ +-public class LinkedEditSuggestionKind { +- +- public static final String METHOD = "METHOD"; +- +- public static final String PARAMETER = "PARAMETER"; +- +- public static final String TYPE = "TYPE"; +- +- public static final String VARIABLE = "VARIABLE"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Location.java b/pkg/analysis_server/tool/spec/generated/java/types/Location.java +deleted file mode 100644 +index d9f8ae0d6f5..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/Location.java ++++ /dev/null +@@ -1,191 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A location (character range) within a file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class Location { +- +- public static final Location[] EMPTY_ARRAY = new Location[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The file containing the range. +- */ +- private final String file; +- +- /** +- * The offset of the range. +- */ +- private final int offset; +- +- /** +- * The length of the range. +- */ +- private final int length; +- +- /** +- * The one-based index of the line containing the first character of the range. +- */ +- private final int startLine; +- +- /** +- * The one-based index of the column containing the first character of the range. +- */ +- private final int startColumn; +- +- /** +- * Constructor for {@link Location}. +- */ +- public Location(String file, int offset, int length, int startLine, int startColumn) { +- this.file = file; +- this.offset = offset; +- this.length = length; +- this.startLine = startLine; +- this.startColumn = startColumn; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof Location) { +- Location other = (Location) obj; +- return +- ObjectUtilities.equals(other.file, file) && +- other.offset == offset && +- other.length == length && +- other.startLine == startLine && +- other.startColumn == startColumn; +- } +- return false; +- } +- +- public static Location fromJson(JsonObject jsonObject) { +- String file = jsonObject.get("file").getAsString(); +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- int startLine = jsonObject.get("startLine").getAsInt(); +- int startColumn = jsonObject.get("startColumn").getAsInt(); +- return new Location(file, offset, length, startLine, startColumn); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The file containing the range. +- */ +- public String getFile() { +- return file; +- } +- +- /** +- * The length of the range. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the range. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The one-based index of the column containing the first character of the range. +- */ +- public int getStartColumn() { +- return startColumn; +- } +- +- /** +- * The one-based index of the line containing the first character of the range. +- */ +- public int getStartLine() { +- return startLine; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(file); +- builder.append(offset); +- builder.append(length); +- builder.append(startLine); +- builder.append(startColumn); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("file", file); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- jsonObject.addProperty("startLine", startLine); +- jsonObject.addProperty("startColumn", startColumn); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("file="); +- builder.append(file + ", "); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("startLine="); +- builder.append(startLine + ", "); +- builder.append("startColumn="); +- builder.append(startColumn); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java +deleted file mode 100644 +index 4f04962be3b..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/MoveFileOptions.java ++++ /dev/null +@@ -1,120 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class MoveFileOptions extends RefactoringOptions { +- +- public static final MoveFileOptions[] EMPTY_ARRAY = new MoveFileOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The new file path to which the given file is being moved. +- */ +- private String newFile; +- +- /** +- * Constructor for {@link MoveFileOptions}. +- */ +- public MoveFileOptions(String newFile) { +- this.newFile = newFile; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof MoveFileOptions) { +- MoveFileOptions other = (MoveFileOptions) obj; +- return +- ObjectUtilities.equals(other.newFile, newFile); +- } +- return false; +- } +- +- public static MoveFileOptions fromJson(JsonObject jsonObject) { +- String newFile = jsonObject.get("newFile").getAsString(); +- return new MoveFileOptions(newFile); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The new file path to which the given file is being moved. +- */ +- public String getNewFile() { +- return newFile; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(newFile); +- return builder.toHashCode(); +- } +- +- /** +- * The new file path to which the given file is being moved. +- */ +- public void setNewFile(String newFile) { +- this.newFile = newFile; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("newFile", newFile); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("newFile="); +- builder.append(newFile); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java +deleted file mode 100644 +index 80565a9f9ce..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationRegion.java ++++ /dev/null +@@ -1,179 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a region from which the user can navigate to the declaration of an element. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class NavigationRegion { +- +- public static final NavigationRegion[] EMPTY_ARRAY = new NavigationRegion[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the region from which the user can navigate. +- */ +- private final int offset; +- +- /** +- * The length of the region from which the user can navigate. +- */ +- private final int length; +- +- /** +- * The indexes of the targets (in the enclosing navigation response) to which the given region is +- * bound. By opening the target, clients can implement one form of navigation. This list cannot be +- * empty. +- */ +- private final int[] targets; +- +- private final List targetObjects = Lists.newArrayList(); +- +- /** +- * Constructor for {@link NavigationRegion}. +- */ +- public NavigationRegion(int offset, int length, int[] targets) { +- this.offset = offset; +- this.length = length; +- this.targets = targets; +- } +- +- public boolean containsInclusive(int x) { +- return offset <= x && x <= offset + length; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof NavigationRegion) { +- NavigationRegion other = (NavigationRegion) obj; +- return +- other.offset == offset && +- other.length == length && +- Arrays.equals(other.targets, targets); +- } +- return false; +- } +- +- public static NavigationRegion fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- int[] targets = JsonUtilities.decodeIntArray(jsonObject.get("targets").getAsJsonArray()); +- return new NavigationRegion(offset, length, targets); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- public List getTargetObjects() { +- return targetObjects; +- } +- +- /** +- * The length of the region from which the user can navigate. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the region from which the user can navigate. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The indexes of the targets (in the enclosing navigation response) to which the given region is +- * bound. By opening the target, clients can implement one form of navigation. This list cannot be +- * empty. +- */ +- public int[] getTargets() { +- return targets; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(targets); +- return builder.toHashCode(); +- } +- +- public void lookupTargets(List allTargets) { +- for (int i = 0; i < targets.length; i++) { +- int targetIndex = targets[i]; +- NavigationTarget target = allTargets.get(targetIndex); +- targetObjects.add(target); +- } +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- JsonArray jsonArrayTargets = new JsonArray(); +- for (int elt : targets) { +- jsonArrayTargets.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("targets", jsonArrayTargets); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("targets="); +- builder.append(StringUtils.join(targets, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java b/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java +deleted file mode 100644 +index d1ef09fd094..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/NavigationTarget.java ++++ /dev/null +@@ -1,220 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a target to which the user can navigate. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class NavigationTarget { +- +- public static final NavigationTarget[] EMPTY_ARRAY = new NavigationTarget[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The kind of the element. +- */ +- private final String kind; +- +- /** +- * The index of the file (in the enclosing navigation response) to navigate to. +- */ +- private final int fileIndex; +- +- /** +- * The offset of the region to which the user can navigate. +- */ +- private final int offset; +- +- /** +- * The length of the region to which the user can navigate. +- */ +- private final int length; +- +- /** +- * The one-based index of the line containing the first character of the region. +- */ +- private final int startLine; +- +- /** +- * The one-based index of the column containing the first character of the region. +- */ +- private final int startColumn; +- +- private String file; +- +- /** +- * Constructor for {@link NavigationTarget}. +- */ +- public NavigationTarget(String kind, int fileIndex, int offset, int length, int startLine, int startColumn) { +- this.kind = kind; +- this.fileIndex = fileIndex; +- this.offset = offset; +- this.length = length; +- this.startLine = startLine; +- this.startColumn = startColumn; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof NavigationTarget) { +- NavigationTarget other = (NavigationTarget) obj; +- return +- ObjectUtilities.equals(other.kind, kind) && +- other.fileIndex == fileIndex && +- other.offset == offset && +- other.length == length && +- other.startLine == startLine && +- other.startColumn == startColumn; +- } +- return false; +- } +- +- public static NavigationTarget fromJson(JsonObject jsonObject) { +- String kind = jsonObject.get("kind").getAsString(); +- int fileIndex = jsonObject.get("fileIndex").getAsInt(); +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- int startLine = jsonObject.get("startLine").getAsInt(); +- int startColumn = jsonObject.get("startColumn").getAsInt(); +- return new NavigationTarget(kind, fileIndex, offset, length, startLine, startColumn); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- public String getFile() { +- return file; +- } +- +- /** +- * The index of the file (in the enclosing navigation response) to navigate to. +- */ +- public int getFileIndex() { +- return fileIndex; +- } +- +- /** +- * The kind of the element. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The length of the region to which the user can navigate. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the region to which the user can navigate. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The one-based index of the column containing the first character of the region. +- */ +- public int getStartColumn() { +- return startColumn; +- } +- +- /** +- * The one-based index of the line containing the first character of the region. +- */ +- public int getStartLine() { +- return startLine; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(kind); +- builder.append(fileIndex); +- builder.append(offset); +- builder.append(length); +- builder.append(startLine); +- builder.append(startColumn); +- return builder.toHashCode(); +- } +- +- public void lookupFile(String[] allTargetFiles) { +- file = allTargetFiles[fileIndex]; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("kind", kind); +- jsonObject.addProperty("fileIndex", fileIndex); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- jsonObject.addProperty("startLine", startLine); +- jsonObject.addProperty("startColumn", startColumn); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("fileIndex="); +- builder.append(fileIndex + ", "); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("startLine="); +- builder.append(startLine + ", "); +- builder.append("startColumn="); +- builder.append(startColumn); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java b/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java +deleted file mode 100644 +index 2f84e5595a0..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/Occurrences.java ++++ /dev/null +@@ -1,166 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of the references to a single element within a single file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class Occurrences { +- +- public static final Occurrences[] EMPTY_ARRAY = new Occurrences[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The element that was referenced. +- */ +- private final Element element; +- +- /** +- * The offsets of the name of the referenced element within the file. +- */ +- private final int[] offsets; +- +- /** +- * The length of the name of the referenced element. +- */ +- private final int length; +- +- /** +- * Constructor for {@link Occurrences}. +- */ +- public Occurrences(Element element, int[] offsets, int length) { +- this.element = element; +- this.offsets = offsets; +- this.length = length; +- } +- +- public boolean containsInclusive(int x) { +- for (int offset : offsets) { +- if (offset <= x && x <= offset + length) { +- return true; +- } +- } +- return false; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof Occurrences) { +- Occurrences other = (Occurrences) obj; +- return +- ObjectUtilities.equals(other.element, element) && +- Arrays.equals(other.offsets, offsets) && +- other.length == length; +- } +- return false; +- } +- +- public static Occurrences fromJson(JsonObject jsonObject) { +- Element element = Element.fromJson(jsonObject.get("element").getAsJsonObject()); +- int[] offsets = JsonUtilities.decodeIntArray(jsonObject.get("offsets").getAsJsonArray()); +- int length = jsonObject.get("length").getAsInt(); +- return new Occurrences(element, offsets, length); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The element that was referenced. +- */ +- public Element getElement() { +- return element; +- } +- +- /** +- * The length of the name of the referenced element. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offsets of the name of the referenced element within the file. +- */ +- public int[] getOffsets() { +- return offsets; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(element); +- builder.append(offsets); +- builder.append(length); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.add("element", element.toJson()); +- JsonArray jsonArrayOffsets = new JsonArray(); +- for (int elt : offsets) { +- jsonArrayOffsets.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("offsets", jsonArrayOffsets); +- jsonObject.addProperty("length", length); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("element="); +- builder.append(element + ", "); +- builder.append("offsets="); +- builder.append(StringUtils.join(offsets, ", ") + ", "); +- builder.append("length="); +- builder.append(length); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java b/pkg/analysis_server/tool/spec/generated/java/types/Outline.java +deleted file mode 100644 +index 142671f25a2..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/Outline.java ++++ /dev/null +@@ -1,207 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An node in the outline structure of a file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class Outline { +- +- public static final Outline[] EMPTY_ARRAY = new Outline[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * A description of the element represented by this node. +- */ +- private Element element; +- +- /** +- * The offset of the first character of the element. This is different than the offset in the +- * Element, which is the offset of the name of the element. It can be used, for example, to map +- * locations in the file back to an outline. +- */ +- private int offset; +- +- /** +- * The length of the element. +- */ +- private int length; +- +- private final Outline parent; +- +- private List children; +- +- /** +- * Constructor for {@link Outline}. +- */ +- public Outline(Outline parent, Element element, int offset, int length) { +- this.parent = parent; +- this.element = element; +- this.offset = offset; +- this.length = length; +- } +- +- public boolean containsInclusive(int x) { +- return offset <= x && x <= offset + length; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof Outline) { +- Outline other = (Outline) obj; +- return +- ObjectUtilities.equals(other.element, element) && +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.children, children); +- } +- return false; +- } +- +- public static Outline fromJson(Outline parent, JsonObject outlineObject) { +- JsonObject elementObject = outlineObject.get("element").getAsJsonObject(); +- Element element = Element.fromJson(elementObject); +- int offset = outlineObject.get("offset").getAsInt(); +- int length = outlineObject.get("length").getAsInt(); +- +- // create outline object +- Outline outline = new Outline(parent, element, offset, length); +- +- // compute children recursively +- List childrenList = Lists.newArrayList(); +- JsonElement childrenJsonArray = outlineObject.get("children"); +- if (childrenJsonArray instanceof JsonArray) { +- Iterator childrenElementIterator = ((JsonArray) childrenJsonArray).iterator(); +- while (childrenElementIterator.hasNext()) { +- JsonObject childObject = childrenElementIterator.next().getAsJsonObject(); +- childrenList.add(fromJson(outline, childObject)); +- } +- } +- outline.setChildren(childrenList); +- return outline; +- } +- +- public Outline getParent() { +- return parent; +- } +- +- /** +- * The children of the node. The field will be omitted if the node has no children. +- */ +- public List getChildren() { +- return children; +- } +- +- /** +- * A description of the element represented by this node. +- */ +- public Element getElement() { +- return element; +- } +- +- /** +- * The length of the element. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the first character of the element. This is different than the offset in the +- * Element, which is the offset of the name of the element. It can be used, for example, to map +- * locations in the file back to an outline. +- */ +- public int getOffset() { +- return offset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(element); +- builder.append(offset); +- builder.append(length); +- builder.append(children); +- return builder.toHashCode(); +- } +- +- /** +- * The children of the node. The field will be omitted if the node has no children. +- */ +- public void setChildren(List children) { +- this.children = children; +- } +- +- /** +- * A description of the element represented by this node. +- */ +- public void setElement(Element element) { +- this.element = element; +- } +- +- /** +- * The length of the element. +- */ +- public void setLength(int length) { +- this.length = length; +- } +- +- /** +- * The offset of the first character of the element. This is different than the offset in the +- * Element, which is the offset of the name of the element. It can be used, for example, to map +- * locations in the file back to an outline. +- */ +- public void setOffset(int offset) { +- this.offset = offset; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("element="); +- builder.append(element + ", "); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("children="); +- builder.append(StringUtils.join(children, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java +deleted file mode 100644 +index 6054c5583dc..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/OverriddenMember.java ++++ /dev/null +@@ -1,134 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a member that is being overridden. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class OverriddenMember { +- +- public static final OverriddenMember[] EMPTY_ARRAY = new OverriddenMember[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The element that is being overridden. +- */ +- private final Element element; +- +- /** +- * The name of the class in which the member is defined. +- */ +- private final String className; +- +- /** +- * Constructor for {@link OverriddenMember}. +- */ +- public OverriddenMember(Element element, String className) { +- this.element = element; +- this.className = className; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof OverriddenMember) { +- OverriddenMember other = (OverriddenMember) obj; +- return +- ObjectUtilities.equals(other.element, element) && +- ObjectUtilities.equals(other.className, className); +- } +- return false; +- } +- +- public static OverriddenMember fromJson(JsonObject jsonObject) { +- Element element = Element.fromJson(jsonObject.get("element").getAsJsonObject()); +- String className = jsonObject.get("className").getAsString(); +- return new OverriddenMember(element, className); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The name of the class in which the member is defined. +- */ +- public String getClassName() { +- return className; +- } +- +- /** +- * The element that is being overridden. +- */ +- public Element getElement() { +- return element; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(element); +- builder.append(className); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.add("element", element.toJson()); +- jsonObject.addProperty("className", className); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("element="); +- builder.append(element + ", "); +- builder.append("className="); +- builder.append(className); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java b/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java +deleted file mode 100644 +index 6f5936eefbb..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/OverrideMember.java ++++ /dev/null +@@ -1,186 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a member that overrides an inherited member. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class OverrideMember { +- +- public static final OverrideMember[] EMPTY_ARRAY = new OverrideMember[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the name of the overriding member. +- */ +- private final int offset; +- +- /** +- * The length of the name of the overriding member. +- */ +- private final int length; +- +- /** +- * The member inherited from a superclass that is overridden by the overriding member. The field is +- * omitted if there is no superclass member, in which case there must be at least one interface +- * member. +- */ +- private final OverriddenMember superclassMember; +- +- /** +- * The members inherited from interfaces that are overridden by the overriding member. The field is +- * omitted if there are no interface members, in which case there must be a superclass member. +- */ +- private final List interfaceMembers; +- +- /** +- * Constructor for {@link OverrideMember}. +- */ +- public OverrideMember(int offset, int length, OverriddenMember superclassMember, List interfaceMembers) { +- this.offset = offset; +- this.length = length; +- this.superclassMember = superclassMember; +- this.interfaceMembers = interfaceMembers; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof OverrideMember) { +- OverrideMember other = (OverrideMember) obj; +- return +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.superclassMember, superclassMember) && +- ObjectUtilities.equals(other.interfaceMembers, interfaceMembers); +- } +- return false; +- } +- +- public static OverrideMember fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- OverriddenMember superclassMember = jsonObject.get("superclassMember") == null ? null : OverriddenMember.fromJson(jsonObject.get("superclassMember").getAsJsonObject()); +- List interfaceMembers = jsonObject.get("interfaceMembers") == null ? null : OverriddenMember.fromJsonArray(jsonObject.get("interfaceMembers").getAsJsonArray()); +- return new OverrideMember(offset, length, superclassMember, interfaceMembers); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The members inherited from interfaces that are overridden by the overriding member. The field is +- * omitted if there are no interface members, in which case there must be a superclass member. +- */ +- public List getInterfaceMembers() { +- return interfaceMembers; +- } +- +- /** +- * The length of the name of the overriding member. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the name of the overriding member. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The member inherited from a superclass that is overridden by the overriding member. The field is +- * omitted if there is no superclass member, in which case there must be at least one interface +- * member. +- */ +- public OverriddenMember getSuperclassMember() { +- return superclassMember; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(superclassMember); +- builder.append(interfaceMembers); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- if (superclassMember != null) { +- jsonObject.add("superclassMember", superclassMember.toJson()); +- } +- if (interfaceMembers != null) { +- JsonArray jsonArrayInterfaceMembers = new JsonArray(); +- for (OverriddenMember elt : interfaceMembers) { +- jsonArrayInterfaceMembers.add(elt.toJson()); +- } +- jsonObject.add("interfaceMembers", jsonArrayInterfaceMembers); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("superclassMember="); +- builder.append(superclassMember + ", "); +- builder.append("interfaceMembers="); +- builder.append(StringUtils.join(interfaceMembers, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Position.java b/pkg/analysis_server/tool/spec/generated/java/types/Position.java +deleted file mode 100644 +index d9e36366d1b..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/Position.java ++++ /dev/null +@@ -1,134 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A position within a file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class Position { +- +- public static final Position[] EMPTY_ARRAY = new Position[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The file containing the position. +- */ +- private final String file; +- +- /** +- * The offset of the position. +- */ +- private final int offset; +- +- /** +- * Constructor for {@link Position}. +- */ +- public Position(String file, int offset) { +- this.file = file; +- this.offset = offset; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof Position) { +- Position other = (Position) obj; +- return +- ObjectUtilities.equals(other.file, file) && +- other.offset == offset; +- } +- return false; +- } +- +- public static Position fromJson(JsonObject jsonObject) { +- String file = jsonObject.get("file").getAsString(); +- int offset = jsonObject.get("offset").getAsInt(); +- return new Position(file, offset); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The file containing the position. +- */ +- public String getFile() { +- return file; +- } +- +- /** +- * The offset of the position. +- */ +- public int getOffset() { +- return offset; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(file); +- builder.append(offset); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("file", file); +- jsonObject.addProperty("offset", offset); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("file="); +- builder.append(file + ", "); +- builder.append("offset="); +- builder.append(offset); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java b/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java +deleted file mode 100644 +index 8358f363390..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/PostfixTemplateDescriptor.java ++++ /dev/null +@@ -1,153 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * The description of a postfix completion template. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class PostfixTemplateDescriptor { +- +- public static final PostfixTemplateDescriptor[] EMPTY_ARRAY = new PostfixTemplateDescriptor[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The template name, shown in the UI. +- */ +- private final String name; +- +- /** +- * The unique template key, not shown in the UI. +- */ +- private final String key; +- +- /** +- * A short example of the transformation performed when the template is applied. +- */ +- private final String example; +- +- /** +- * Constructor for {@link PostfixTemplateDescriptor}. +- */ +- public PostfixTemplateDescriptor(String name, String key, String example) { +- this.name = name; +- this.key = key; +- this.example = example; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof PostfixTemplateDescriptor) { +- PostfixTemplateDescriptor other = (PostfixTemplateDescriptor) obj; +- return +- ObjectUtilities.equals(other.name, name) && +- ObjectUtilities.equals(other.key, key) && +- ObjectUtilities.equals(other.example, example); +- } +- return false; +- } +- +- public static PostfixTemplateDescriptor fromJson(JsonObject jsonObject) { +- String name = jsonObject.get("name").getAsString(); +- String key = jsonObject.get("key").getAsString(); +- String example = jsonObject.get("example").getAsString(); +- return new PostfixTemplateDescriptor(name, key, example); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A short example of the transformation performed when the template is applied. +- */ +- public String getExample() { +- return example; +- } +- +- /** +- * The unique template key, not shown in the UI. +- */ +- public String getKey() { +- return key; +- } +- +- /** +- * The template name, shown in the UI. +- */ +- public String getName() { +- return name; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(name); +- builder.append(key); +- builder.append(example); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("name", name); +- jsonObject.addProperty("key", key); +- jsonObject.addProperty("example", example); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("key="); +- builder.append(key + ", "); +- builder.append("example="); +- builder.append(example); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java b/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java +deleted file mode 100644 +index 9d45a192ec8..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/PubStatus.java ++++ /dev/null +@@ -1,115 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An indication of the current state of pub execution. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class PubStatus { +- +- public static final PubStatus[] EMPTY_ARRAY = new PubStatus[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * True if the server is currently running pub to produce a list of package directories. +- */ +- private final boolean isListingPackageDirs; +- +- /** +- * Constructor for {@link PubStatus}. +- */ +- public PubStatus(boolean isListingPackageDirs) { +- this.isListingPackageDirs = isListingPackageDirs; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof PubStatus) { +- PubStatus other = (PubStatus) obj; +- return +- other.isListingPackageDirs == isListingPackageDirs; +- } +- return false; +- } +- +- public static PubStatus fromJson(JsonObject jsonObject) { +- boolean isListingPackageDirs = jsonObject.get("isListingPackageDirs").getAsBoolean(); +- return new PubStatus(isListingPackageDirs); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * True if the server is currently running pub to produce a list of package directories. +- */ +- public boolean isListingPackageDirs() { +- return isListingPackageDirs; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(isListingPackageDirs); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("isListingPackageDirs", isListingPackageDirs); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("isListingPackageDirs="); +- builder.append(isListingPackageDirs); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java +deleted file mode 100644 +index d3cfa25c7e0..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringFeedback.java ++++ /dev/null +@@ -1,85 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An abstract superclass of all refactoring feedbacks. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RefactoringFeedback { +- +- public static final RefactoringFeedback[] EMPTY_ARRAY = new RefactoringFeedback[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * Constructor for {@link RefactoringFeedback}. +- */ +- public RefactoringFeedback() { +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RefactoringFeedback) { +- RefactoringFeedback other = (RefactoringFeedback) obj; +- return +- true; +- } +- return false; +- } +- +- public static RefactoringFeedback fromJson(JsonObject jsonObject) { +- return new RefactoringFeedback(); +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java +deleted file mode 100644 +index b4eb166b6e9..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringKind.java ++++ /dev/null +@@ -1,44 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of refactorings that can be created. +- * +- * @coverage dart.server.generated.types +- */ +-public class RefactoringKind { +- +- public static final String CONVERT_GETTER_TO_METHOD = "CONVERT_GETTER_TO_METHOD"; +- +- public static final String CONVERT_METHOD_TO_GETTER = "CONVERT_METHOD_TO_GETTER"; +- +- public static final String EXTRACT_LOCAL_VARIABLE = "EXTRACT_LOCAL_VARIABLE"; +- +- public static final String EXTRACT_METHOD = "EXTRACT_METHOD"; +- +- public static final String INLINE_LOCAL_VARIABLE = "INLINE_LOCAL_VARIABLE"; +- +- public static final String INLINE_METHOD = "INLINE_METHOD"; +- +- public static final String MOVE_FILE = "MOVE_FILE"; +- +- public static final String RENAME = "RENAME"; +- +- public static final String SORT_MEMBERS = "SORT_MEMBERS"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java +deleted file mode 100644 +index ddad03276f8..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameter.java ++++ /dev/null +@@ -1,242 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a parameter in a method refactoring. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RefactoringMethodParameter { +- +- public static final RefactoringMethodParameter[] EMPTY_ARRAY = new RefactoringMethodParameter[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The unique identifier of the parameter. Clients may omit this field for the parameters they want +- * to add. +- */ +- private String id; +- +- /** +- * The kind of the parameter. +- */ +- private String kind; +- +- /** +- * The type that should be given to the parameter, or the return type of the parameter's function +- * type. +- */ +- private String type; +- +- /** +- * The name that should be given to the parameter. +- */ +- private String name; +- +- /** +- * The parameter list of the parameter's function type. If the parameter is not of a function type, +- * this field will not be defined. If the function type has zero parameters, this field will have a +- * value of '()'. +- */ +- private String parameters; +- +- /** +- * Constructor for {@link RefactoringMethodParameter}. +- */ +- public RefactoringMethodParameter(String id, String kind, String type, String name, String parameters) { +- this.id = id; +- this.kind = kind; +- this.type = type; +- this.name = name; +- this.parameters = parameters; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RefactoringMethodParameter) { +- RefactoringMethodParameter other = (RefactoringMethodParameter) obj; +- return +- ObjectUtilities.equals(other.id, id) && +- ObjectUtilities.equals(other.kind, kind) && +- ObjectUtilities.equals(other.type, type) && +- ObjectUtilities.equals(other.name, name) && +- ObjectUtilities.equals(other.parameters, parameters); +- } +- return false; +- } +- +- public static RefactoringMethodParameter fromJson(JsonObject jsonObject) { +- String id = jsonObject.get("id") == null ? null : jsonObject.get("id").getAsString(); +- String kind = jsonObject.get("kind").getAsString(); +- String type = jsonObject.get("type").getAsString(); +- String name = jsonObject.get("name").getAsString(); +- String parameters = jsonObject.get("parameters") == null ? null : jsonObject.get("parameters").getAsString(); +- return new RefactoringMethodParameter(id, kind, type, name, parameters); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The unique identifier of the parameter. Clients may omit this field for the parameters they want +- * to add. +- */ +- public String getId() { +- return id; +- } +- +- /** +- * The kind of the parameter. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The name that should be given to the parameter. +- */ +- public String getName() { +- return name; +- } +- +- /** +- * The parameter list of the parameter's function type. If the parameter is not of a function type, +- * this field will not be defined. If the function type has zero parameters, this field will have a +- * value of '()'. +- */ +- public String getParameters() { +- return parameters; +- } +- +- /** +- * The type that should be given to the parameter, or the return type of the parameter's function +- * type. +- */ +- public String getType() { +- return type; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(id); +- builder.append(kind); +- builder.append(type); +- builder.append(name); +- builder.append(parameters); +- return builder.toHashCode(); +- } +- +- /** +- * The unique identifier of the parameter. Clients may omit this field for the parameters they want +- * to add. +- */ +- public void setId(String id) { +- this.id = id; +- } +- +- /** +- * The kind of the parameter. +- */ +- public void setKind(String kind) { +- this.kind = kind; +- } +- +- /** +- * The name that should be given to the parameter. +- */ +- public void setName(String name) { +- this.name = name; +- } +- +- /** +- * The parameter list of the parameter's function type. If the parameter is not of a function type, +- * this field will not be defined. If the function type has zero parameters, this field will have a +- * value of '()'. +- */ +- public void setParameters(String parameters) { +- this.parameters = parameters; +- } +- +- /** +- * The type that should be given to the parameter, or the return type of the parameter's function +- * type. +- */ +- public void setType(String type) { +- this.type = type; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- if (id != null) { +- jsonObject.addProperty("id", id); +- } +- jsonObject.addProperty("kind", kind); +- jsonObject.addProperty("type", type); +- jsonObject.addProperty("name", name); +- if (parameters != null) { +- jsonObject.addProperty("parameters", parameters); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("id="); +- builder.append(id + ", "); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("type="); +- builder.append(type + ", "); +- builder.append("name="); +- builder.append(name + ", "); +- builder.append("parameters="); +- builder.append(parameters); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java +deleted file mode 100644 +index c71d8bbdcb1..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringMethodParameterKind.java ++++ /dev/null +@@ -1,32 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of parameters. +- * +- * @coverage dart.server.generated.types +- */ +-public class RefactoringMethodParameterKind { +- +- public static final String REQUIRED = "REQUIRED"; +- +- public static final String POSITIONAL = "POSITIONAL"; +- +- public static final String NAMED = "NAMED"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java +deleted file mode 100644 +index 67abd4bb1ba..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringOptions.java ++++ /dev/null +@@ -1,85 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An abstract superclass of all refactoring options. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RefactoringOptions { +- +- public static final RefactoringOptions[] EMPTY_ARRAY = new RefactoringOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * Constructor for {@link RefactoringOptions}. +- */ +- public RefactoringOptions() { +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RefactoringOptions) { +- RefactoringOptions other = (RefactoringOptions) obj; +- return +- true; +- } +- return false; +- } +- +- public static RefactoringOptions fromJson(JsonObject jsonObject) { +- return new RefactoringOptions(); +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java +deleted file mode 100644 +index 1b82e4a158a..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblem.java ++++ /dev/null +@@ -1,159 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a problem related to a refactoring. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RefactoringProblem { +- +- public static final RefactoringProblem[] EMPTY_ARRAY = new RefactoringProblem[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The severity of the problem being represented. +- */ +- private final String severity; +- +- /** +- * A human-readable description of the problem being represented. +- */ +- private final String message; +- +- /** +- * The location of the problem being represented. This field is omitted unless there is a specific +- * location associated with the problem (such as a location where an element being renamed will be +- * shadowed). +- */ +- private final Location location; +- +- /** +- * Constructor for {@link RefactoringProblem}. +- */ +- public RefactoringProblem(String severity, String message, Location location) { +- this.severity = severity; +- this.message = message; +- this.location = location; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RefactoringProblem) { +- RefactoringProblem other = (RefactoringProblem) obj; +- return +- ObjectUtilities.equals(other.severity, severity) && +- ObjectUtilities.equals(other.message, message) && +- ObjectUtilities.equals(other.location, location); +- } +- return false; +- } +- +- public static RefactoringProblem fromJson(JsonObject jsonObject) { +- String severity = jsonObject.get("severity").getAsString(); +- String message = jsonObject.get("message").getAsString(); +- Location location = jsonObject.get("location") == null ? null : Location.fromJson(jsonObject.get("location").getAsJsonObject()); +- return new RefactoringProblem(severity, message, location); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The location of the problem being represented. This field is omitted unless there is a specific +- * location associated with the problem (such as a location where an element being renamed will be +- * shadowed). +- */ +- public Location getLocation() { +- return location; +- } +- +- /** +- * A human-readable description of the problem being represented. +- */ +- public String getMessage() { +- return message; +- } +- +- /** +- * The severity of the problem being represented. +- */ +- public String getSeverity() { +- return severity; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(severity); +- builder.append(message); +- builder.append(location); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("severity", severity); +- jsonObject.addProperty("message", message); +- if (location != null) { +- jsonObject.add("location", location.toJson()); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("severity="); +- builder.append(severity + ", "); +- builder.append("message="); +- builder.append(message + ", "); +- builder.append("location="); +- builder.append(location); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java b/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java +deleted file mode 100644 +index 6befcd6ec96..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RefactoringProblemSeverity.java ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the severities of problems that can be returned by the refactoring requests. +- * +- * @coverage dart.server.generated.types +- */ +-public class RefactoringProblemSeverity { +- +- /** +- * A minor code problem. No example, because it is not used yet. +- */ +- public static final String INFO = "INFO"; +- +- /** +- * A minor code problem. For example names of local variables should be camel case and start with a +- * lower case letter. Staring the name of a variable with an upper case is OK from the language +- * point of view, but it is nice to warn the user. +- */ +- public static final String WARNING = "WARNING"; +- +- /** +- * The refactoring technically can be performed, but there is a logical problem. For example the +- * name of a local variable being extracted conflicts with another name in the scope, or duplicate +- * parameter names in the method being extracted, or a conflict between a parameter name and a +- * local variable, etc. In some cases the location of the problem is also provided, so the IDE can +- * show user the location and the problem, and let the user decide whether they want to perform the +- * refactoring. For example the name conflict might be expected, and the user wants to fix it +- * afterwards. +- */ +- public static final String ERROR = "ERROR"; +- +- /** +- * A fatal error, which prevents performing the refactoring. For example the name of a local +- * variable being extracted is not a valid identifier, or selection is not a valid expression. +- */ +- public static final String FATAL = "FATAL"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java b/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java +deleted file mode 100644 +index c9e14a401aa..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RemoveContentOverlay.java ++++ /dev/null +@@ -1,113 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A directive to remove an existing file content overlay. After processing this directive, the +- * file contents will once again be read from the file system. +- * +- * If this directive is used on a file that doesn't currently have a content overlay, it has no +- * effect. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RemoveContentOverlay { +- +- public static final RemoveContentOverlay[] EMPTY_ARRAY = new RemoveContentOverlay[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- private final String type; +- +- /** +- * Constructor for {@link RemoveContentOverlay}. +- */ +- public RemoveContentOverlay() { +- this.type = "remove"; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RemoveContentOverlay) { +- RemoveContentOverlay other = (RemoveContentOverlay) obj; +- return +- ObjectUtilities.equals(other.type, type); +- } +- return false; +- } +- +- public static RemoveContentOverlay fromJson(JsonObject jsonObject) { +- String type = jsonObject.get("type").getAsString(); +- return new RemoveContentOverlay(); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- public String getType() { +- return type; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(type); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("type", type); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("type="); +- builder.append(type); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java +deleted file mode 100644 +index c10021ff74e..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java ++++ /dev/null +@@ -1,172 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RenameFeedback extends RefactoringFeedback { +- +- public static final RenameFeedback[] EMPTY_ARRAY = new RenameFeedback[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset to the beginning of the name selected to be renamed. +- */ +- private final int offset; +- +- /** +- * The length of the name selected to be renamed. +- */ +- private final int length; +- +- /** +- * The human-readable description of the kind of element being renamed (such as "class" or +- * "function type alias"). +- */ +- private final String elementKindName; +- +- /** +- * The old name of the element before the refactoring. +- */ +- private final String oldName; +- +- /** +- * Constructor for {@link RenameFeedback}. +- */ +- public RenameFeedback(int offset, int length, String elementKindName, String oldName) { +- this.offset = offset; +- this.length = length; +- this.elementKindName = elementKindName; +- this.oldName = oldName; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RenameFeedback) { +- RenameFeedback other = (RenameFeedback) obj; +- return +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.elementKindName, elementKindName) && +- ObjectUtilities.equals(other.oldName, oldName); +- } +- return false; +- } +- +- public static RenameFeedback fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- String elementKindName = jsonObject.get("elementKindName").getAsString(); +- String oldName = jsonObject.get("oldName").getAsString(); +- return new RenameFeedback(offset, length, elementKindName, oldName); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The human-readable description of the kind of element being renamed (such as "class" or +- * "function type alias"). +- */ +- public String getElementKindName() { +- return elementKindName; +- } +- +- /** +- * The length of the name selected to be renamed. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset to the beginning of the name selected to be renamed. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The old name of the element before the refactoring. +- */ +- public String getOldName() { +- return oldName; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(elementKindName); +- builder.append(oldName); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- jsonObject.addProperty("elementKindName", elementKindName); +- jsonObject.addProperty("oldName", oldName); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("elementKindName="); +- builder.append(elementKindName + ", "); +- builder.append("oldName="); +- builder.append(oldName); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java +deleted file mode 100644 +index 18b80e019d5..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameOptions.java ++++ /dev/null +@@ -1,120 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RenameOptions extends RefactoringOptions { +- +- public static final RenameOptions[] EMPTY_ARRAY = new RenameOptions[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The name that the element should have after the refactoring. +- */ +- private String newName; +- +- /** +- * Constructor for {@link RenameOptions}. +- */ +- public RenameOptions(String newName) { +- this.newName = newName; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RenameOptions) { +- RenameOptions other = (RenameOptions) obj; +- return +- ObjectUtilities.equals(other.newName, newName); +- } +- return false; +- } +- +- public static RenameOptions fromJson(JsonObject jsonObject) { +- String newName = jsonObject.get("newName").getAsString(); +- return new RenameOptions(newName); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * The name that the element should have after the refactoring. +- */ +- public String getNewName() { +- return newName; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(newName); +- return builder.toHashCode(); +- } +- +- /** +- * The name that the element should have after the refactoring. +- */ +- public void setNewName(String newName) { +- this.newName = newName; +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("newName", newName); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("newName="); +- builder.append(newName); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java +deleted file mode 100644 +index 34c6b317988..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestError.java ++++ /dev/null +@@ -1,155 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * An indication of a problem with the execution of the server, typically in response to a request. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class RequestError { +- +- public static final RequestError[] EMPTY_ARRAY = new RequestError[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * A code that uniquely identifies the error that occurred. +- */ +- private final String code; +- +- /** +- * A short description of the error. +- */ +- private final String message; +- +- /** +- * The stack trace associated with processing the request, used for debugging the server. +- */ +- private final String stackTrace; +- +- /** +- * Constructor for {@link RequestError}. +- */ +- public RequestError(String code, String message, String stackTrace) { +- this.code = code; +- this.message = message; +- this.stackTrace = stackTrace; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof RequestError) { +- RequestError other = (RequestError) obj; +- return +- ObjectUtilities.equals(other.code, code) && +- ObjectUtilities.equals(other.message, message) && +- ObjectUtilities.equals(other.stackTrace, stackTrace); +- } +- return false; +- } +- +- public static RequestError fromJson(JsonObject jsonObject) { +- String code = jsonObject.get("code").getAsString(); +- String message = jsonObject.get("message").getAsString(); +- String stackTrace = jsonObject.get("stackTrace") == null ? null : jsonObject.get("stackTrace").getAsString(); +- return new RequestError(code, message, stackTrace); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A code that uniquely identifies the error that occurred. +- */ +- public String getCode() { +- return code; +- } +- +- /** +- * A short description of the error. +- */ +- public String getMessage() { +- return message; +- } +- +- /** +- * The stack trace associated with processing the request, used for debugging the server. +- */ +- public String getStackTrace() { +- return stackTrace; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(code); +- builder.append(message); +- builder.append(stackTrace); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("code", code); +- jsonObject.addProperty("message", message); +- if (stackTrace != null) { +- jsonObject.addProperty("stackTrace", stackTrace); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("code="); +- builder.append(code + ", "); +- builder.append("message="); +- builder.append(message + ", "); +- builder.append("stackTrace="); +- builder.append(stackTrace); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java +deleted file mode 100644 +index a389b5bfd2c..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java ++++ /dev/null +@@ -1,182 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the types of errors that can occur in the execution of the server. +- * +- * @coverage dart.server.generated.types +- */ +-public class RequestErrorCode { +- +- /** +- * An "analysis.getErrors" or "analysis.getNavigation" request could not be satisfied because the +- * content of the file changed before the requested results could be computed. +- */ +- public static final String CONTENT_MODIFIED = "CONTENT_MODIFIED"; +- +- /** +- * The server was unable to open a port for the diagnostic server. +- */ +- public static final String DEBUG_PORT_COULD_NOT_BE_OPENED = "DEBUG_PORT_COULD_NOT_BE_OPENED"; +- +- /** +- * A request specified a FilePath which does not match a file in an analysis root, or the requested +- * operation is not available for the file. +- */ +- public static final String FILE_NOT_ANALYZED = "FILE_NOT_ANALYZED"; +- +- /** +- * An "edit.format" request specified a FilePath which does not match a Dart file in an analysis +- * root. +- */ +- public static final String FORMAT_INVALID_FILE = "FORMAT_INVALID_FILE"; +- +- /** +- * An "edit.format" request specified a file that contains syntax errors. +- */ +- public static final String FORMAT_WITH_ERRORS = "FORMAT_WITH_ERRORS"; +- +- /** +- * An "analysis.getErrors" request specified a FilePath which does not match a file currently +- * subject to analysis. +- */ +- public static final String GET_ERRORS_INVALID_FILE = "GET_ERRORS_INVALID_FILE"; +- +- /** +- * An "analysis.getImportedElements" request specified a FilePath that does not match a file +- * currently subject to analysis. +- */ +- public static final String GET_IMPORTED_ELEMENTS_INVALID_FILE = "GET_IMPORTED_ELEMENTS_INVALID_FILE"; +- +- /** +- * An "analysis.getKytheEntries" request specified a FilePath that does not match a file that is +- * currently subject to analysis. +- */ +- public static final String GET_KYTHE_ENTRIES_INVALID_FILE = "GET_KYTHE_ENTRIES_INVALID_FILE"; +- +- /** +- * An "analysis.getNavigation" request specified a FilePath which does not match a file currently +- * subject to analysis. +- */ +- public static final String GET_NAVIGATION_INVALID_FILE = "GET_NAVIGATION_INVALID_FILE"; +- +- /** +- * An "analysis.getReachableSources" request specified a FilePath which does not match a file +- * currently subject to analysis. +- */ +- public static final String GET_REACHABLE_SOURCES_INVALID_FILE = "GET_REACHABLE_SOURCES_INVALID_FILE"; +- +- /** +- * An "edit.importElements" request specified a FilePath that does not match a file currently +- * subject to analysis. +- */ +- public static final String IMPORT_ELEMENTS_INVALID_FILE = "IMPORT_ELEMENTS_INVALID_FILE"; +- +- /** +- * A path passed as an argument to a request (such as analysis.reanalyze) is required to be an +- * analysis root, but isn't. +- */ +- public static final String INVALID_ANALYSIS_ROOT = "INVALID_ANALYSIS_ROOT"; +- +- /** +- * The context root used to create an execution context does not exist. +- */ +- public static final String INVALID_EXECUTION_CONTEXT = "INVALID_EXECUTION_CONTEXT"; +- +- /** +- * The format of the given file path is invalid, e.g. is not absolute and normalized. +- */ +- public static final String INVALID_FILE_PATH_FORMAT = "INVALID_FILE_PATH_FORMAT"; +- +- /** +- * An "analysis.updateContent" request contained a ChangeContentOverlay object which can't be +- * applied, due to an edit having an offset or length that is out of range. +- */ +- public static final String INVALID_OVERLAY_CHANGE = "INVALID_OVERLAY_CHANGE"; +- +- /** +- * One of the method parameters was invalid. +- */ +- public static final String INVALID_PARAMETER = "INVALID_PARAMETER"; +- +- /** +- * A malformed request was received. +- */ +- public static final String INVALID_REQUEST = "INVALID_REQUEST"; +- +- /** +- * An "edit.organizeDirectives" request specified a Dart file that cannot be analyzed. The reason +- * is described in the message. +- */ +- public static final String ORGANIZE_DIRECTIVES_ERROR = "ORGANIZE_DIRECTIVES_ERROR"; +- +- /** +- * Another refactoring request was received during processing of this one. +- */ +- public static final String REFACTORING_REQUEST_CANCELLED = "REFACTORING_REQUEST_CANCELLED"; +- +- /** +- * The analysis server has already been started (and hence won't accept new connections). +- * +- * This error is included for future expansion; at present the analysis server can only speak to +- * one client at a time so this error will never occur. +- */ +- public static final String SERVER_ALREADY_STARTED = "SERVER_ALREADY_STARTED"; +- +- /** +- * An internal error occurred in the analysis server. Also see the server.error notification. +- */ +- public static final String SERVER_ERROR = "SERVER_ERROR"; +- +- /** +- * An "edit.sortMembers" request specified a FilePath which does not match a Dart file in an +- * analysis root. +- */ +- public static final String SORT_MEMBERS_INVALID_FILE = "SORT_MEMBERS_INVALID_FILE"; +- +- /** +- * An "edit.sortMembers" request specified a Dart file that has scan or parse errors. +- */ +- public static final String SORT_MEMBERS_PARSE_ERRORS = "SORT_MEMBERS_PARSE_ERRORS"; +- +- /** +- * An "analysis.setPriorityFiles" request includes one or more files that are not being analyzed. +- * +- * This is a legacy error; it will be removed before the API reaches version 1.0. +- */ +- public static final String UNANALYZED_PRIORITY_FILES = "UNANALYZED_PRIORITY_FILES"; +- +- /** +- * A request was received which the analysis server does not recognize, or cannot handle in its +- * current configuration. +- */ +- public static final String UNKNOWN_REQUEST = "UNKNOWN_REQUEST"; +- +- /** +- * The analysis server was requested to perform an action on a source that does not exist. +- */ +- public static final String UNKNOWN_SOURCE = "UNKNOWN_SOURCE"; +- +- /** +- * The analysis server was requested to perform an action which is not supported. +- * +- * This is a legacy error; it will be removed before the API reaches version 1.0. +- */ +- public static final String UNSUPPORTED_FEATURE = "UNSUPPORTED_FEATURE"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java +deleted file mode 100644 +index 299aba0c1cc..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResult.java ++++ /dev/null +@@ -1,182 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A single result from a search request. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class SearchResult { +- +- public static final SearchResult[] EMPTY_ARRAY = new SearchResult[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The location of the code that matched the search criteria. +- */ +- private final Location location; +- +- /** +- * The kind of element that was found or the kind of reference that was found. +- */ +- private final String kind; +- +- /** +- * True if the result is a potential match but cannot be confirmed to be a match. For example, if +- * all references to a method m defined in some class were requested, and a reference to a method m +- * from an unknown class were found, it would be marked as being a potential match. +- */ +- private final boolean isPotential; +- +- /** +- * The elements that contain the result, starting with the most immediately enclosing ancestor and +- * ending with the library. +- */ +- private final List path; +- +- /** +- * Constructor for {@link SearchResult}. +- */ +- public SearchResult(Location location, String kind, boolean isPotential, List path) { +- this.location = location; +- this.kind = kind; +- this.isPotential = isPotential; +- this.path = path; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof SearchResult) { +- SearchResult other = (SearchResult) obj; +- return +- ObjectUtilities.equals(other.location, location) && +- ObjectUtilities.equals(other.kind, kind) && +- other.isPotential == isPotential && +- ObjectUtilities.equals(other.path, path); +- } +- return false; +- } +- +- public static SearchResult fromJson(JsonObject jsonObject) { +- Location location = Location.fromJson(jsonObject.get("location").getAsJsonObject()); +- String kind = jsonObject.get("kind").getAsString(); +- boolean isPotential = jsonObject.get("isPotential").getAsBoolean(); +- List path = Element.fromJsonArray(jsonObject.get("path").getAsJsonArray()); +- return new SearchResult(location, kind, isPotential, path); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * True if the result is a potential match but cannot be confirmed to be a match. For example, if +- * all references to a method m defined in some class were requested, and a reference to a method m +- * from an unknown class were found, it would be marked as being a potential match. +- */ +- public boolean isPotential() { +- return isPotential; +- } +- +- /** +- * The kind of element that was found or the kind of reference that was found. +- */ +- public String getKind() { +- return kind; +- } +- +- /** +- * The location of the code that matched the search criteria. +- */ +- public Location getLocation() { +- return location; +- } +- +- /** +- * The elements that contain the result, starting with the most immediately enclosing ancestor and +- * ending with the library. +- */ +- public List getPath() { +- return path; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(location); +- builder.append(kind); +- builder.append(isPotential); +- builder.append(path); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.add("location", location.toJson()); +- jsonObject.addProperty("kind", kind); +- jsonObject.addProperty("isPotential", isPotential); +- JsonArray jsonArrayPath = new JsonArray(); +- for (Element elt : path) { +- jsonArrayPath.add(elt.toJson()); +- } +- jsonObject.add("path", jsonArrayPath); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("location="); +- builder.append(location + ", "); +- builder.append("kind="); +- builder.append(kind + ", "); +- builder.append("isPotential="); +- builder.append(isPotential + ", "); +- builder.append("path="); +- builder.append(StringUtils.join(path, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java b/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java +deleted file mode 100644 +index e5562728a9e..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/SearchResultKind.java ++++ /dev/null +@@ -1,61 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the kinds of search results returned by the search domain. +- * +- * @coverage dart.server.generated.types +- */ +-public class SearchResultKind { +- +- /** +- * The declaration of an element. +- */ +- public static final String DECLARATION = "DECLARATION"; +- +- /** +- * The invocation of a function or method. +- */ +- public static final String INVOCATION = "INVOCATION"; +- +- /** +- * A reference to a field, parameter or variable where it is being read. +- */ +- public static final String READ = "READ"; +- +- /** +- * A reference to a field, parameter or variable where it is being read and written. +- */ +- public static final String READ_WRITE = "READ_WRITE"; +- +- /** +- * A reference to an element. +- */ +- public static final String REFERENCE = "REFERENCE"; +- +- /** +- * Some other kind of search result. +- */ +- public static final String UNKNOWN = "UNKNOWN"; +- +- /** +- * A reference to a field, parameter or variable where it is being written. +- */ +- public static final String WRITE = "WRITE"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java b/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java +deleted file mode 100644 +index 6846e6ec066..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/ServerService.java ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-/** +- * An enumeration of the services provided by the server domain. +- * +- * @coverage dart.server.generated.types +- */ +-public class ServerService { +- +- public static final String STATUS = "STATUS"; +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java +deleted file mode 100644 +index 6842e2fedf6..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceChange.java ++++ /dev/null +@@ -1,182 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a set of edits that implement a single conceptual change. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class SourceChange { +- +- public static final SourceChange[] EMPTY_ARRAY = new SourceChange[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * A human-readable description of the change to be applied. +- */ +- private final String message; +- +- /** +- * A list of the edits used to effect the change, grouped by file. +- */ +- private final List edits; +- +- /** +- * A list of the linked editing groups used to customize the changes that were made. +- */ +- private final List linkedEditGroups; +- +- /** +- * The position that should be selected after the edits have been applied. +- */ +- private final Position selection; +- +- /** +- * Constructor for {@link SourceChange}. +- */ +- public SourceChange(String message, List edits, List linkedEditGroups, Position selection) { +- this.message = message; +- this.edits = edits; +- this.linkedEditGroups = linkedEditGroups; +- this.selection = selection; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof SourceChange) { +- SourceChange other = (SourceChange) obj; +- return +- ObjectUtilities.equals(other.message, message) && +- ObjectUtilities.equals(other.edits, edits) && +- ObjectUtilities.equals(other.linkedEditGroups, linkedEditGroups) && +- ObjectUtilities.equals(other.selection, selection); +- } +- return false; +- } +- +- public static SourceChange fromJson(JsonObject jsonObject) { +- String message = jsonObject.get("message").getAsString(); +- List edits = SourceFileEdit.fromJsonArray(jsonObject.get("edits").getAsJsonArray()); +- List linkedEditGroups = LinkedEditGroup.fromJsonArray(jsonObject.get("linkedEditGroups").getAsJsonArray()); +- Position selection = jsonObject.get("selection") == null ? null : Position.fromJson(jsonObject.get("selection").getAsJsonObject()); +- return new SourceChange(message, edits, linkedEditGroups, selection); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A list of the edits used to effect the change, grouped by file. +- */ +- public List getEdits() { +- return edits; +- } +- +- /** +- * A list of the linked editing groups used to customize the changes that were made. +- */ +- public List getLinkedEditGroups() { +- return linkedEditGroups; +- } +- +- /** +- * A human-readable description of the change to be applied. +- */ +- public String getMessage() { +- return message; +- } +- +- /** +- * The position that should be selected after the edits have been applied. +- */ +- public Position getSelection() { +- return selection; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(message); +- builder.append(edits); +- builder.append(linkedEditGroups); +- builder.append(selection); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("message", message); +- JsonArray jsonArrayEdits = new JsonArray(); +- for (SourceFileEdit elt : edits) { +- jsonArrayEdits.add(elt.toJson()); +- } +- jsonObject.add("edits", jsonArrayEdits); +- JsonArray jsonArrayLinkedEditGroups = new JsonArray(); +- for (LinkedEditGroup elt : linkedEditGroups) { +- jsonArrayLinkedEditGroups.add(elt.toJson()); +- } +- jsonObject.add("linkedEditGroups", jsonArrayLinkedEditGroups); +- if (selection != null) { +- jsonObject.add("selection", selection.toJson()); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("message="); +- builder.append(message + ", "); +- builder.append("edits="); +- builder.append(StringUtils.join(edits, ", ") + ", "); +- builder.append("linkedEditGroups="); +- builder.append(StringUtils.join(linkedEditGroups, ", ") + ", "); +- builder.append("selection="); +- builder.append(selection); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java +deleted file mode 100644 +index 1d54802df1b..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceEdit.java ++++ /dev/null +@@ -1,186 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a single change to a single file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class SourceEdit { +- +- public static final SourceEdit[] EMPTY_ARRAY = new SourceEdit[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The offset of the region to be modified. +- */ +- private final int offset; +- +- /** +- * The length of the region to be modified. +- */ +- private final int length; +- +- /** +- * The code that is to replace the specified region in the original code. +- */ +- private final String replacement; +- +- /** +- * An identifier that uniquely identifies this source edit from other edits in the same response. +- * This field is omitted unless a containing structure needs to be able to identify the edit for +- * some reason. +- * +- * For example, some refactoring operations can produce edits that might not be appropriate +- * (referred to as potential edits). Such edits will have an id so that they can be referenced. +- * Edits in the same response that do not need to be referenced will not have an id. +- */ +- private final String id; +- +- /** +- * Constructor for {@link SourceEdit}. +- */ +- public SourceEdit(int offset, int length, String replacement, String id) { +- this.offset = offset; +- this.length = length; +- this.replacement = replacement; +- this.id = id; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof SourceEdit) { +- SourceEdit other = (SourceEdit) obj; +- return +- other.offset == offset && +- other.length == length && +- ObjectUtilities.equals(other.replacement, replacement) && +- ObjectUtilities.equals(other.id, id); +- } +- return false; +- } +- +- public static SourceEdit fromJson(JsonObject jsonObject) { +- int offset = jsonObject.get("offset").getAsInt(); +- int length = jsonObject.get("length").getAsInt(); +- String replacement = jsonObject.get("replacement").getAsString(); +- String id = jsonObject.get("id") == null ? null : jsonObject.get("id").getAsString(); +- return new SourceEdit(offset, length, replacement, id); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * An identifier that uniquely identifies this source edit from other edits in the same response. +- * This field is omitted unless a containing structure needs to be able to identify the edit for +- * some reason. +- * +- * For example, some refactoring operations can produce edits that might not be appropriate +- * (referred to as potential edits). Such edits will have an id so that they can be referenced. +- * Edits in the same response that do not need to be referenced will not have an id. +- */ +- public String getId() { +- return id; +- } +- +- /** +- * The length of the region to be modified. +- */ +- public int getLength() { +- return length; +- } +- +- /** +- * The offset of the region to be modified. +- */ +- public int getOffset() { +- return offset; +- } +- +- /** +- * The code that is to replace the specified region in the original code. +- */ +- public String getReplacement() { +- return replacement; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(offset); +- builder.append(length); +- builder.append(replacement); +- builder.append(id); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("offset", offset); +- jsonObject.addProperty("length", length); +- jsonObject.addProperty("replacement", replacement); +- if (id != null) { +- jsonObject.addProperty("id", id); +- } +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("offset="); +- builder.append(offset + ", "); +- builder.append("length="); +- builder.append(length + ", "); +- builder.append("replacement="); +- builder.append(replacement + ", "); +- builder.append("id="); +- builder.append(id); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java b/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java +deleted file mode 100644 +index 18fab9bd18f..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/SourceFileEdit.java ++++ /dev/null +@@ -1,163 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A description of a set of changes to a single file. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class SourceFileEdit { +- +- public static final SourceFileEdit[] EMPTY_ARRAY = new SourceFileEdit[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The file containing the code to be modified. +- */ +- private final String file; +- +- /** +- * The modification stamp of the file at the moment when the change was created, in milliseconds +- * since the "Unix epoch". Will be -1 if the file did not exist and should be created. The client +- * may use this field to make sure that the file was not changed since then, so it is safe to apply +- * the change. +- */ +- private final long fileStamp; +- +- /** +- * A list of the edits used to effect the change. +- */ +- private final List edits; +- +- /** +- * Constructor for {@link SourceFileEdit}. +- */ +- public SourceFileEdit(String file, long fileStamp, List edits) { +- this.file = file; +- this.fileStamp = fileStamp; +- this.edits = edits; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof SourceFileEdit) { +- SourceFileEdit other = (SourceFileEdit) obj; +- return +- ObjectUtilities.equals(other.file, file) && +- other.fileStamp == fileStamp && +- ObjectUtilities.equals(other.edits, edits); +- } +- return false; +- } +- +- public static SourceFileEdit fromJson(JsonObject jsonObject) { +- String file = jsonObject.get("file").getAsString(); +- long fileStamp = jsonObject.get("fileStamp").getAsLong(); +- List edits = SourceEdit.fromJsonArray(jsonObject.get("edits").getAsJsonArray()); +- return new SourceFileEdit(file, fileStamp, edits); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- /** +- * A list of the edits used to effect the change. +- */ +- public List getEdits() { +- return edits; +- } +- +- /** +- * The file containing the code to be modified. +- */ +- public String getFile() { +- return file; +- } +- +- /** +- * The modification stamp of the file at the moment when the change was created, in milliseconds +- * since the "Unix epoch". Will be -1 if the file did not exist and should be created. The client +- * may use this field to make sure that the file was not changed since then, so it is safe to apply +- * the change. +- */ +- public long getFileStamp() { +- return fileStamp; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(file); +- builder.append(fileStamp); +- builder.append(edits); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.addProperty("file", file); +- jsonObject.addProperty("fileStamp", fileStamp); +- JsonArray jsonArrayEdits = new JsonArray(); +- for (SourceEdit elt : edits) { +- jsonArrayEdits.add(elt.toJson()); +- } +- jsonObject.add("edits", jsonArrayEdits); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("file="); +- builder.append(file + ", "); +- builder.append("fileStamp="); +- builder.append(fileStamp + ", "); +- builder.append("edits="); +- builder.append(StringUtils.join(edits, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java b/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java +deleted file mode 100644 +index b6420a2a21c..00000000000 +--- a/pkg/analysis_server/tool/spec/generated/java/types/TypeHierarchyItem.java ++++ /dev/null +@@ -1,271 +0,0 @@ +-/* +- * Copyright (c) 2015, the Dart project authors. +- * +- * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except +- * in compliance with the License. You may obtain a copy of the License at +- * +- * http://www.eclipse.org/legal/epl-v10.html +- * +- * Unless required by applicable law or agreed to in writing, software distributed under the License +- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +- * or implied. See the License for the specific language governing permissions and limitations under +- * the License. +- * +- * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". +- */ +-package org.dartlang.analysis.server.protocol; +- +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; +-import com.google.common.collect.Lists; +-import com.google.dart.server.utilities.general.JsonUtilities; +-import com.google.dart.server.utilities.general.ObjectUtilities; +-import com.google.gson.JsonArray; +-import com.google.gson.JsonElement; +-import com.google.gson.JsonObject; +-import com.google.gson.JsonPrimitive; +-import org.apache.commons.lang3.builder.HashCodeBuilder; +-import java.util.ArrayList; +-import java.util.Iterator; +-import org.apache.commons.lang3.StringUtils; +- +-/** +- * A representation of a class in a type hierarchy. +- * +- * @coverage dart.server.generated.types +- */ +-@SuppressWarnings("unused") +-public class TypeHierarchyItem { +- +- public static final TypeHierarchyItem[] EMPTY_ARRAY = new TypeHierarchyItem[0]; +- +- public static final List EMPTY_LIST = Lists.newArrayList(); +- +- /** +- * The class element represented by this item. +- */ +- private final Element classElement; +- +- /** +- * The name to be displayed for the class. This field will be omitted if the display name is the +- * same as the name of the element. The display name is different if there is additional type +- * information to be displayed, such as type arguments. +- */ +- private final String displayName; +- +- /** +- * The member in the class corresponding to the member on which the hierarchy was requested. This +- * field will be omitted if the hierarchy was not requested for a member or if the class does not +- * have a corresponding member. +- */ +- private final Element memberElement; +- +- /** +- * The index of the item representing the superclass of this class. This field will be omitted if +- * this item represents the class Object. +- */ +- private final Integer superclass; +- +- /** +- * The indexes of the items representing the interfaces implemented by this class. The list will be +- * empty if there are no implemented interfaces. +- */ +- private final int[] interfaces; +- +- /** +- * The indexes of the items representing the mixins referenced by this class. The list will be +- * empty if there are no classes mixed in to this class. +- */ +- private final int[] mixins; +- +- /** +- * The indexes of the items representing the subtypes of this class. The list will be empty if +- * there are no subtypes or if this item represents a supertype of the pivot type. +- */ +- private final int[] subclasses; +- +- /** +- * Constructor for {@link TypeHierarchyItem}. +- */ +- public TypeHierarchyItem(Element classElement, String displayName, Element memberElement, Integer superclass, int[] interfaces, int[] mixins, int[] subclasses) { +- this.classElement = classElement; +- this.displayName = displayName; +- this.memberElement = memberElement; +- this.superclass = superclass; +- this.interfaces = interfaces; +- this.mixins = mixins; +- this.subclasses = subclasses; +- } +- +- @Override +- public boolean equals(Object obj) { +- if (obj instanceof TypeHierarchyItem) { +- TypeHierarchyItem other = (TypeHierarchyItem) obj; +- return +- ObjectUtilities.equals(other.classElement, classElement) && +- ObjectUtilities.equals(other.displayName, displayName) && +- ObjectUtilities.equals(other.memberElement, memberElement) && +- ObjectUtilities.equals(other.superclass, superclass) && +- Arrays.equals(other.interfaces, interfaces) && +- Arrays.equals(other.mixins, mixins) && +- Arrays.equals(other.subclasses, subclasses); +- } +- return false; +- } +- +- public static TypeHierarchyItem fromJson(JsonObject jsonObject) { +- Element classElement = Element.fromJson(jsonObject.get("classElement").getAsJsonObject()); +- String displayName = jsonObject.get("displayName") == null ? null : jsonObject.get("displayName").getAsString(); +- Element memberElement = jsonObject.get("memberElement") == null ? null : Element.fromJson(jsonObject.get("memberElement").getAsJsonObject()); +- Integer superclass = jsonObject.get("superclass") == null ? null : jsonObject.get("superclass").getAsInt(); +- int[] interfaces = JsonUtilities.decodeIntArray(jsonObject.get("interfaces").getAsJsonArray()); +- int[] mixins = JsonUtilities.decodeIntArray(jsonObject.get("mixins").getAsJsonArray()); +- int[] subclasses = JsonUtilities.decodeIntArray(jsonObject.get("subclasses").getAsJsonArray()); +- return new TypeHierarchyItem(classElement, displayName, memberElement, superclass, interfaces, mixins, subclasses); +- } +- +- public static List fromJsonArray(JsonArray jsonArray) { +- if (jsonArray == null) { +- return EMPTY_LIST; +- } +- ArrayList list = new ArrayList(jsonArray.size()); +- Iterator iterator = jsonArray.iterator(); +- while (iterator.hasNext()) { +- list.add(fromJson(iterator.next().getAsJsonObject())); +- } +- return list; +- } +- +- public String getBestName() { +- if (displayName == null) { +- return classElement.getName(); +- } else { +- return displayName; +- } +- } +- +- /** +- * The class element represented by this item. +- */ +- public Element getClassElement() { +- return classElement; +- } +- +- /** +- * The name to be displayed for the class. This field will be omitted if the display name is the +- * same as the name of the element. The display name is different if there is additional type +- * information to be displayed, such as type arguments. +- */ +- public String getDisplayName() { +- return displayName; +- } +- +- /** +- * The indexes of the items representing the interfaces implemented by this class. The list will be +- * empty if there are no implemented interfaces. +- */ +- public int[] getInterfaces() { +- return interfaces; +- } +- +- /** +- * The member in the class corresponding to the member on which the hierarchy was requested. This +- * field will be omitted if the hierarchy was not requested for a member or if the class does not +- * have a corresponding member. +- */ +- public Element getMemberElement() { +- return memberElement; +- } +- +- /** +- * The indexes of the items representing the mixins referenced by this class. The list will be +- * empty if there are no classes mixed in to this class. +- */ +- public int[] getMixins() { +- return mixins; +- } +- +- /** +- * The indexes of the items representing the subtypes of this class. The list will be empty if +- * there are no subtypes or if this item represents a supertype of the pivot type. +- */ +- public int[] getSubclasses() { +- return subclasses; +- } +- +- /** +- * The index of the item representing the superclass of this class. This field will be omitted if +- * this item represents the class Object. +- */ +- public Integer getSuperclass() { +- return superclass; +- } +- +- @Override +- public int hashCode() { +- HashCodeBuilder builder = new HashCodeBuilder(); +- builder.append(classElement); +- builder.append(displayName); +- builder.append(memberElement); +- builder.append(superclass); +- builder.append(interfaces); +- builder.append(mixins); +- builder.append(subclasses); +- return builder.toHashCode(); +- } +- +- public JsonObject toJson() { +- JsonObject jsonObject = new JsonObject(); +- jsonObject.add("classElement", classElement.toJson()); +- if (displayName != null) { +- jsonObject.addProperty("displayName", displayName); +- } +- if (memberElement != null) { +- jsonObject.add("memberElement", memberElement.toJson()); +- } +- if (superclass != null) { +- jsonObject.addProperty("superclass", superclass); +- } +- JsonArray jsonArrayInterfaces = new JsonArray(); +- for (int elt : interfaces) { +- jsonArrayInterfaces.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("interfaces", jsonArrayInterfaces); +- JsonArray jsonArrayMixins = new JsonArray(); +- for (int elt : mixins) { +- jsonArrayMixins.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("mixins", jsonArrayMixins); +- JsonArray jsonArraySubclasses = new JsonArray(); +- for (int elt : subclasses) { +- jsonArraySubclasses.add(new JsonPrimitive(elt)); +- } +- jsonObject.add("subclasses", jsonArraySubclasses); +- return jsonObject; +- } +- +- @Override +- public String toString() { +- StringBuilder builder = new StringBuilder(); +- builder.append("["); +- builder.append("classElement="); +- builder.append(classElement + ", "); +- builder.append("displayName="); +- builder.append(displayName + ", "); +- builder.append("memberElement="); +- builder.append(memberElement + ", "); +- builder.append("superclass="); +- builder.append(superclass + ", "); +- builder.append("interfaces="); +- builder.append(StringUtils.join(interfaces, ", ") + ", "); +- builder.append("mixins="); +- builder.append(StringUtils.join(mixins, ", ") + ", "); +- builder.append("subclasses="); +- builder.append(StringUtils.join(subclasses, ", ")); +- builder.append("]"); +- return builder.toString(); +- } +- +-} +diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart +deleted file mode 100644 +index 49531b7fb01..00000000000 +--- a/pkg/analysis_server/tool/spec/implied_types.dart ++++ /dev/null +@@ -1,89 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code for enumerating the set of types implied by the API. +- */ +-import 'package:analyzer/src/codegen/tools.dart'; +- +-import 'api.dart'; +- +-Map computeImpliedTypes(Api api) { +- _ImpliedTypesVisitor visitor = new _ImpliedTypesVisitor(api); +- visitor.visitApi(); +- return visitor.impliedTypes; +-} +- +-class ImpliedType { +- final String camelName; +- final String humanReadableName; +- final TypeDecl type; +- +- /** +- * Kind of implied type this is. One of: +- * - 'requestParams' +- * - 'requestResult' +- * - 'notificationParams' +- * - 'refactoringFeedback' +- * - 'refactoringOptions' +- * - 'typeDefinition' +- */ +- final String kind; +- +- /** +- * API node from which this type was inferred. +- */ +- final ApiNode apiNode; +- +- ImpliedType(this.camelName, this.humanReadableName, this.type, this.kind, +- this.apiNode); +-} +- +-class _ImpliedTypesVisitor extends HierarchicalApiVisitor { +- Map impliedTypes = {}; +- +- _ImpliedTypesVisitor(Api api) : super(api); +- +- void storeType(String name, String nameSuffix, TypeDecl type, String kind, +- ApiNode apiNode) { +- String humanReadableName = name; +- List camelNameParts = name.split('.'); +- if (nameSuffix != null) { +- humanReadableName += ' $nameSuffix'; +- camelNameParts.add(nameSuffix); +- } +- String camelName = camelJoin(camelNameParts); +- impliedTypes[camelName] = +- new ImpliedType(camelName, humanReadableName, type, kind, apiNode); +- } +- +- @override +- visitNotification(Notification notification) { +- storeType(notification.longEvent, 'params', notification.params, +- 'notificationParams', notification); +- } +- +- @override +- visitRefactoring(Refactoring refactoring) { +- String camelKind = camelJoin(refactoring.kind.toLowerCase().split('_')); +- storeType(camelKind, 'feedback', refactoring.feedback, +- 'refactoringFeedback', refactoring); +- storeType(camelKind, 'options', refactoring.options, 'refactoringOptions', +- refactoring); +- } +- +- @override +- visitRequest(Request request) { +- storeType( +- request.longMethod, 'params', request.params, 'requestParams', request); +- storeType( +- request.longMethod, 'result', request.result, 'requestResult', request); +- } +- +- @override +- visitTypeDefinition(TypeDefinition typeDefinition) { +- storeType(typeDefinition.name, null, typeDefinition.type, 'typeDefinition', +- typeDefinition); +- } +-} +diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html +deleted file mode 100644 +index 29b17e6ddf0..00000000000 +--- a/pkg/analysis_server/tool/spec/spec_input.html ++++ /dev/null +@@ -1,3975 +0,0 @@ +- +- +- +- +- Analysis Server API Specification +- +- +-

    Analysis Server API Specification

    +-

    Version +- 1.18.4 +-

    +-

    +- This document contains a specification of the API provided by the +- analysis server. The API in this document is currently under +- development. Changes to the API will be accompanied by an update to the +- protocol version number according to the principles of semantic +- versioning (semver.org). +-

    +-

    Overview

    +-

    +- The analysis server API is a bi-directional client-server +- API. The API is independent of the transport mechanism used, but +- is heavily influenced by a model in which sockets or character +- streams are used to transport JSON-RPC encoded information. +-

    +-

    Transport Mechanism

    +-

    +- The characters passed to the server are expected to be encoded +- using UTF-8. +-

    +-

    +- When character streams are used as the transport, messages are +- delineated by newlines. This means, in particular, that the JSON +- encoding process must not introduce newlines within a +- message. Note however that newlines are used in this document +- for readability. +-

    +-

    +- It is the client's responsibility to read output from the server to +- avoid its blocking. +-

    +-

    +- To ease interoperability with Lisp-based clients (which may not +- be able to easily distinguish between empty lists, empty maps, +- and null), client-to-server communication is allowed to replace +- any instance of "{}" or "[]" with null. The +- server will always properly represent empty lists as +- "[]" and empty maps as "{}". +-

    +-

    Communication Structure

    +-

    +- Clients can make a request of the server and the server will +- provide a response for each request that it receives. While many +- of the requests that can be made by a client are informational +- in nature, we have chosen to always return a response so that +- clients can know whether the request was received and was +- correct. +-

    +-

    +- There is no guarantee concerning the order in which responses +- will be returned, but there is a guarantee that the server will +- process requests in the order in which they are sent as long as +- the transport mechanism also makes this guarantee. Responses can +- be returned in an order that is different from the order in +- which the requests were received because some requests take +- longer to process than others. +-

    +-

    +- Every request is required to have two fields and may have two +- additional optional fields. The first required field is the ‘id’ +- field, which is only used by the server to associate a response +- with the request that generated the response. The second +- required field is the ‘method’ field, which is used to determine +- what the server is being requested to do. One optional field is +- the ‘params’ field, whose structure is dependent on the method +- being requested. The structure of this field is described with +- each request for which it is required. The other optional field +- is the 'clientRequestTime' field, which is a number indicating +- the time at which the client made the request (milliseconds +- since epoch). Providing clientRequestTime helps us track +- how responsive analysis server is to client requests +- and better address any issues that occur. +-

    +-

    +- Every response has up to three fields. The first field is the +- ‘id’ field, which is always present and whose value is the +- identifier that was passed to the request that generated the +- response. The second field is the ‘error’ field, which is only +- present if an error was encountered while processing the +- request. The third field is the ‘result’ field, whose structure +- is dependent on the method being responded to, and is described +- with each request that will produce it. +-

    +-

    +- The server can also communicate to the clients by sending a +- notification. The purpose of these notifications is to provide +- information to clients as it becomes available rather than to +- require that clients poll for it. Unless explicitly stated, all +- notifications are designed to return the complete information +- available at the time the notification is sent; clients are not +- required to update previously communicated +- results. Consequently, the server can and should return partial +- results before all results are available. For example, the +- syntactic errors for a file can be returned as soon as the +- syntactic analysis is complete, and both syntactic and semantic +- errors can be returned together at a later time. +-

    +-

    +- Each notification has two fields. The first field is the ‘event’ +- field, which identifies the kind of notification. The second +- field is the ‘params’ field, whose structure is dependent on the +- kind of notification being sent. The structure of this field is +- described with each notification. +-

    +-

    +- In order to be backward compatible, clients should ignore fields that were +- not specified in the version of the API on which they were based. Clients +- should also use the server.getVersion request to test that the version of +- the server supports an API before using it. +-

    +-

    Eventual Consistency

    +-

    +- The analysis server satisfies requests under the principle of +- eventual +- consistency. +- That is, in some cases it may return responses with the currently available +- results while it's catching up with unprocessed changes. +-

    +-

    Domains

    +-

    +- For convenience, the API is divided into domains. Each domain is specified +- in a separate section below. The specifications of the API’s refer to data +- structures beyond the standard JSON primitives. These data structures are +- documented in the section titled Types. +-

    +- +-

    Command-line Arguments

    +-

    +- The command-line arguments that can be passed to the server. +-

    +-

    Options

    +-
    +-
    +-
    --client-id
    +-
    +-

    +- Specifies an identifier associated with the client. Used when +- generating error reports. +-

    +-

    +- Clients are strongly encouraged to provide this information in +- order to improve the quality of information that can be provided +- to them. +-

    +-
    +-
    +-
    +-
    --client-version
    +-
    +-

    +- Specifies the version of the client that is communicating with +- the server. Used when generating error reports. +-

    +-

    +- Clients are strongly encouraged to provide this information in +- order to improve the quality of information that can be provided +- to them. +-

    +-
    +-
    +-
    +-
    --no-error-notification
    +-
    +-

    Deprecated: clients should no longer pass this option in

    +- Disable notifications about errors (see analysis.error). If this +- flag is not specified then notifications will be sent for all +- errors produced for all files in the actual analysis roots. +-
    +-
    +-
    +-
    --no-index
    +-
    +-

    Deprecated: clients should no longer pass this option in

    +- This flag used to disable the server from generating an index, but now +- it has no effect. +-
    +-
    +-
    +-
    --file-read-mode
    +-
    +-

    Deprecated: clients should no longer pass this option in

    +- An enumeration of the ways files can be read from disk. Some clients +- normalize end of line characters which would make the file offset and +- range information incorrect. The default option is as-is, but +- can also be set to normalize-eol-always. The default option +- (as-is) reads files as they are on disk. The +- normalize-eol-always option does the following: +-
      +-
    • '\r\n' is converted to '\n';
    • +-
    • '\r' by itself is converted to '\n';
    • +-
    • this happens regardless of the OS editor is running on.
    • +-
    +-
    +-
    +-
    +- +- +-

    +- The server domain contains API’s related to the execution of +- the server. +-

    +- +-

    Return the version number of the analysis server.

    +- +- +- String +-

    The version number of the analysis server.

    +-
    +-
    +-
    +- +-

    +- Cleanly shutdown the analysis server. Requests that are +- received after this request will not be processed. Requests +- that were received before this request, but for which a +- response has not yet been sent, will not be responded to. No +- further responses or notifications will be sent after the +- response to this request has been sent. +-

    +-
    +- +-

    +- Subscribe for services. All previous subscriptions are +- replaced by the given set of services. +-

    +-

    +- It is an error if any of the elements in the list are not +- valid services. If there is an error, then the current +- subscriptions will remain unchanged. +-

    +- +- +- +- ServerService +- +-

    A list of the services being subscribed to.

    +-
    +-
    +-
    +- +-

    +- Reports that the server is running. This notification is +- issued once after the server has started running but before +- any requests are processed to let the client know that it +- started correctly. +-

    +-

    +- It is not possible to subscribe to or unsubscribe from this +- notification. +-

    +- +- +- String +-

    The version number of the analysis server.

    +-
    +- +- int +-

    The process id of the analysis server process.

    +-
    +- +- String +-

    The session id for this session.

    +-
    +-
    +-
    +- +-

    +- Reports that an unexpected error has occurred while +- executing the server. This notification is not used for +- problems with specific requests (which are returned as part +- of the response) but is used for exceptions that occur while +- performing other tasks, such as analysis or preparing +- notifications. +-

    +-

    +- It is not possible to subscribe to or unsubscribe from this +- notification. +-

    +- +- +- bool +-

    +- True if the error is a fatal error, meaning that the +- server will shutdown automatically after sending this +- notification. +-

    +-
    +- +- String +-

    +- The error message indicating what kind of error was +- encountered. +-

    +-
    +- +- String +-

    +- The stack trace associated with the generation of the +- error, used for debugging the server. +-

    +-
    +-
    +-
    +- +-

    +- Reports the current status of the server. Parameters are +- omitted if there has been no change in the status +- represented by that parameter. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "STATUS" in +- the list of services passed in a server.setSubscriptions +- request. +-

    +- +- +- AnalysisStatus +-

    +- The current status of analysis, including whether +- analysis is being performed and if so what is being +- analyzed. +-

    +-
    +- +- PubStatus +-

    +- The current status of pub execution, indicating whether we are +- currently running pub. +-

    +-
    +-
    +-
    +-
    +- +-

    +- The analysis domain contains API’s related to the analysis of +- files. +-

    +- +-

    +- Return the errors associated with the given file. If the +- errors for the given file have not yet been computed, or the +- most recently computed errors for the given file are out of +- date, then the response for this request will be delayed +- until they have been computed. If some or all of the errors +- for the file cannot be computed, then the subset of the +- errors that can be computed will be returned and the +- response will contain an error to indicate why the errors +- could not be computed. If the content of the file changes after this +- request was received but before a response could be sent, then an +- error of type CONTENT_MODIFIED will be generated. +-

    +-

    +- This request is intended to be used by clients that cannot +- asynchronously apply updated error information. Clients that +- can apply error information as it becomes available +- should use the information provided by the 'analysis.errors' +- notification. +-

    +-

    +- If a request is made for a file which does not exist, or +- which is not currently subject to analysis (e.g. because it +- is not associated with any analysis root specified to +- analysis.setAnalysisRoots), an error of type +- GET_ERRORS_INVALID_FILE will be generated. +-

    +- +- +- FilePath +-

    +- The file for which errors are being requested. +-

    +-
    +-
    +- +- +- +- AnalysisError +- +-

    +- The errors associated with the file. +-

    +-
    +-
    +-
    +- +-

    +- Return the hover information associate with the given +- location. If some or all of the hover information is not +- available at the time this request is processed the +- information will be omitted from the response. +-

    +- +- +- FilePath +-

    +- The file in which hover information is being requested. +-

    +-
    +- +- int +-

    +- The offset for which hover information is being requested. +-

    +-
    +-
    +- +- +- +- HoverInformation +- +-

    +- The hover information associated with the +- location. The list will be empty if no information +- could be determined for the location. The list can +- contain multiple items if the file is being analyzed +- in multiple contexts in conflicting ways (such as a +- part that is included in multiple libraries). +-

    +-
    +-
    +-
    +- +-

    +- Return a description of all of the elements referenced in a given region +- of a given file that come from imported libraries. +-

    +-

    +- If a request is made for a file that does not exist, or that is not +- currently subject to analysis (e.g. because it is not associated with any +- analysis root specified via analysis.setAnalysisRoots), an error of type +- GET_IMPORTED_ELEMENTS_INVALID_FILE will be generated. +-

    +- +- +- FilePath +-

    +- The file in which import information is being requested. +-

    +-
    +- +- int +-

    +- The offset of the region for which import information is being +- requested. +-

    +-
    +- +- int +-

    +- The length of the region for which import information is being +- requested. +-

    +-
    +-
    +- +- +- +- ImportedElements +- +-

    +- The information about the elements that are referenced in the +- specified region of the specified file that come from imported +- libraries. +-

    +-
    +-
    +-
    +- +-

    +- Return library dependency information for use in client-side indexing +- and package URI resolution. +-

    +-

    +- Clients that are only using the libraries field should consider using the +- analyzedFiles notification instead. +-

    +- +- +- +- FilePath +- +-

    +- A list of the paths of library elements referenced by +- files in existing analysis roots. +-

    +-
    +- +- +- +- String +- +- +- +- +- String +- +- +- +- FilePath +- +- +- +- +- +-

    +- A mapping from context source roots to package maps which map +- package names to source directories for use in client-side +- package URI resolution. +-

    +-
    +-
    +-
    +- +-

    +- Return the navigation information associated with the given region of +- the given file. If the navigation information for the given file has +- not yet been computed, or the most recently computed navigation +- information for the given file is out of date, then the response for +- this request will be delayed until it has been computed. If the +- content of the file changes after this request was received but before +- a response could be sent, then an error of type +- CONTENT_MODIFIED will be generated. +-

    +-

    +- If a navigation region overlaps (but extends either before or after) +- the given region of the file it will be included in the result. This +- means that it is theoretically possible to get the same navigation +- region in response to multiple requests. Clients can avoid this by +- always choosing a region that starts at the beginning of a line and +- ends at the end of a (possibly different) line in the file. +-

    +-

    +- If a request is made for a file which does not exist, or +- which is not currently subject to analysis (e.g. because it +- is not associated with any analysis root specified to +- analysis.setAnalysisRoots), an error of type +- GET_NAVIGATION_INVALID_FILE will be generated. +-

    +- +- +- FilePath +-

    +- The file in which navigation information is being requested. +-

    +-
    +- +- int +-

    +- The offset of the region for which navigation information is being +- requested. +-

    +-
    +- +- int +-

    +- The length of the region for which navigation information is being +- requested. +-

    +-
    +-
    +- +- +- +- FilePath +- +-

    +- A list of the paths of files that are referenced by the navigation +- targets. +-

    +-
    +- +- +- NavigationTarget +- +-

    +- A list of the navigation targets that are referenced by the +- navigation regions. +-

    +-
    +- +- +- NavigationRegion +- +-

    +- A list of the navigation regions within the requested region of +- the file. +-

    +-
    +-
    +-
    +- +-

    +- Return the transitive closure of reachable sources for a given file. +-

    +-

    +- If a request is made for a file which does not exist, or +- which is not currently subject to analysis (e.g. because it +- is not associated with any analysis root specified to +- analysis.setAnalysisRoots), an error of type +- GET_REACHABLE_SOURCES_INVALID_FILE will be generated. +-

    +- +- +- FilePath +-

    +- The file for which reachable source information is being requested. +-

    +-
    +-
    +- +- +- +- +- String +- +- +- +- String +- +- +- +-

    +- A mapping from source URIs to directly reachable source URIs. For +- example, +- a file "foo.dart" that imports "bar.dart" would have the corresponding +- mapping +- { "file:///foo.dart" : ["file:///bar.dart"] }. If "bar.dart" has +- further imports +- (or exports) there will be a mapping from the URI "file:///bar.dart" +- to them. +- To check if a specific URI is reachable from a given file, clients can +- check +- for its presence in the resulting key set. +-

    +-
    +-
    +-
    +- +-

    +- Force the re-analysis of everything contained in the specified +- analysis roots. This will cause all previously computed analysis +- results to be discarded and recomputed, and will cause all subscribed +- notifications to be re-sent. +-

    +-

    +- If no analysis roots are provided, then all current analysis roots +- will be re-analyzed. If an empty list of analysis roots is provided, +- then nothing will be re-analyzed. If the list contains one or more +- paths that are not currently analysis roots, then an error of type +- INVALID_ANALYSIS_ROOT will be generated. +-

    +- +- +- +- FilePath +- +-

    +- A list of the analysis roots that are to be re-analyzed. +-

    +-
    +-
    +-
    +- +-

    +- Sets the root paths used to determine which files to analyze. The set +- of files to be analyzed are all of the files in one of the root paths +- that are not either explicitly or implicitly excluded. A file is +- explicitly excluded if it is in one of the excluded paths. A file is +- implicitly excluded if it is in a subdirectory of one of the root +- paths where the name of the subdirectory starts with a period (that +- is, a hidden directory). +-

    +-

    +- Note that this request determines the set of requested +- analysis roots. The actual set of analysis roots at any +- given time is the intersection of this set with the set of +- files and directories actually present on the +- filesystem. When the filesystem changes, the actual set of +- analysis roots is automatically updated, but the set of +- requested analysis roots is unchanged. This means that if +- the client sets an analysis root before the root becomes +- visible to server in the filesystem, there is no error; once +- the server sees the root in the filesystem it will start +- analyzing it. Similarly, server will stop analyzing files +- that are removed from the file system but they will remain +- in the set of requested roots. +-

    +-

    +- If an included path represents a file, then server will look +- in the directory containing the file for a pubspec.yaml +- file. If none is found, then the parents of the directory +- will be searched until such a file is found or the root of +- the file system is reached. If such a file is found, it will +- be used to resolve package: URI’s within the file. +-

    +- +- +- +- FilePath +- +-

    +- A list of the files and directories that should be +- analyzed. +-

    +-
    +- +- +- FilePath +- +-

    +- A list of the files and directories within the +- included directories that should not be analyzed. +-

    +-
    +- +- +- +- FilePath +- +- +- FilePath +- +- +-

    +- A mapping from source directories to package roots +- that should override the normal package: URI resolution +- mechanism. +-

    +-

    +- If a package root is a directory, then +- the analyzer will behave as though the associated +- source directory in the map contains a special +- pubspec.yaml file which resolves any package: URI to the +- corresponding path within that package root directory. The +- effect is the same as specifying the package root directory as +- a "--package_root" parameter to the Dart VM when +- executing any Dart file inside the source directory. +-

    +-

    +- If a package root is a file, then the analyzer +- will behave as though that file is a ".packages" file in the +- source directory. The effect is the same as specifying the file +- as a "--packages" parameter to the Dart VM when +- executing any Dart file inside the source directory. +-

    +-

    +- Files in any directories that are not overridden by this +- mapping have their package: URI's resolved using the +- normal pubspec.yaml mechanism. If this field is absent, +- or the empty map is specified, that indicates that the +- normal pubspec.yaml mechanism should always be used. +-

    +-
    +-
    +-
    +- +-

    +- Subscribe for general services (that is, services that are not +- specific to individual files). All previous subscriptions are replaced +- by the given set of services. +-

    +-

    +- It is an error if any of the elements in the list are not valid +- services. If there is an error, then the current subscriptions will +- remain unchanged. +-

    +- +- +- +- GeneralAnalysisService +- +-

    A list of the services being subscribed to.

    +-
    +-
    +-
    +- +-

    +- Set the priority files to the files in the given list. A +- priority file is a file that is given priority when +- scheduling which analysis work to do first. The list +- typically contains those files that are visible to the user +- and those for which analysis results will have the biggest +- impact on the user experience. The order of the files within +- the list is significant: the first file will be given higher +- priority than the second, the second higher priority than +- the third, and so on. +-

    +-

    +- Note that this request determines the set of requested +- priority files. The actual set of priority files is the +- intersection of the requested set of priority files with the +- set of files currently subject to analysis. (See +- analysis.setSubscriptions for a description of files that +- are subject to analysis.) +-

    +-

    +- If a requested priority file is a directory it is ignored, +- but remains in the set of requested priority files so that +- if it later becomes a file it can be included in the set of +- actual priority files. +-

    +- +- +- +- FilePath +- +-

    +- The files that are to be a priority for analysis. +-

    +-
    +-
    +-
    +- +-

    +- Subscribe for services that are specific to individual files. +- All previous subscriptions are replaced by the current set of +- subscriptions. If a given service is not included as a key in the map +- then no files will be subscribed to the service, exactly as if the +- service had been included in the map with an explicit empty list of +- files. +-

    +-

    +- Note that this request determines the set of requested +- subscriptions. The actual set of subscriptions at any given +- time is the intersection of this set with the set of files +- currently subject to analysis. The files currently subject +- to analysis are the set of files contained within an actual +- analysis root but not excluded, plus all of the files +- transitively reachable from those files via import, export +- and part directives. (See analysis.setAnalysisRoots for an +- explanation of how the actual analysis roots are +- determined.) When the actual analysis roots change, the +- actual set of subscriptions is automatically updated, but +- the set of requested subscriptions is unchanged. +-

    +-

    +- If a requested subscription is a directory it is ignored, +- but remains in the set of requested subscriptions so that if +- it later becomes a file it can be included in the set of +- actual subscriptions. +-

    +-

    +- It is an error if any of the keys in the map are not valid +- services. If there is an error, then the existing +- subscriptions will remain unchanged. +-

    +- +- +- +- +- AnalysisService +- +- +- +- FilePath +- +- +- +-

    +- A table mapping services to a list of the files being +- subscribed to the service. +-

    +-
    +-
    +-
    +- +-

    +- Update the content of one or more files. Files that were +- previously updated but not included in this update remain +- unchanged. This effectively represents an overlay of the +- filesystem. The files whose content is overridden are +- therefore seen by server as being files with the given +- content, even if the files do not exist on the filesystem or +- if the file path represents the path to a directory on the +- filesystem. +-

    +- +- +- +- +- FilePath +- +- +- +- AddContentOverlay +- ChangeContentOverlay +- RemoveContentOverlay +- +- +- +-

    +- A table mapping the files whose content has changed to a +- description of the content change. +-

    +-
    +-
    +- +- +-
    +- +-

    Deprecated: all of the options can be set by users in +- an analysis options file.

    +-

    +- Update the options controlling analysis based on the given +- set of options. Any options that are not included in the +- analysis options will not be changed. If there are options +- in the analysis options that are not valid, they will be +- silently ignored. +-

    +- +- +- AnalysisOptions +-

    +- The options that are to be used to control analysis. +-

    +-
    +-
    +-
    +- +-

    +- Reports the paths of the files that are being analyzed. +-

    +-

    +- This notification is not subscribed to by default. Clients can +- subscribe by including the value "ANALYZED_FILES" in the list +- of services passed in an analysis.setGeneralSubscriptions request. +-

    +- +- +- +- FilePath +- +-

    +- A list of the paths of the files that are being analyzed. +-

    +-
    +-
    +-
    +- +-

    +- Reports closing labels relevant to a given file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "CLOSING_LABELS" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

    +- +- +- FilePath +-

    +- The file the closing labels relate to. +-

    +-
    +- +- +- ClosingLabel +- +-

    +- Closing labels relevant to the file. Each item +- represents a useful label associated with some range +- with may be useful to display to the user within the editor +- at the end of the range to indicate what construct is closed +- at that location. Closing labels include constructor/method +- calls and List arguments that span multiple lines. +- Note that the ranges that are returned can overlap +- each other because they may be associated with +- constructs that can be nested. +-

    +-
    +-
    +-
    +- +-

    +- Reports the errors associated with a given file. The set of +- errors included in the notification is always a complete +- list that supersedes any previously reported errors. +-

    +- +- +- FilePath +-

    +- The file containing the errors. +-

    +-
    +- +- +- AnalysisError +- +-

    +- The errors contained in the file. +-

    +-
    +-
    +-
    +- +-

    +- Reports that any analysis results that were previously +- associated with the given files should be considered to be +- invalid because those files are no longer being analyzed, +- either because the analysis root that contained it is no +- longer being analyzed or because the file no longer exists. +-

    +-

    +- If a file is included in this notification and at some later +- time a notification with results for the file is received, +- clients should assume that the file is once again being +- analyzed and the information should be processed. +-

    +-

    +- It is not possible to subscribe to or unsubscribe from this +- notification. +-

    +- +- +- +- FilePath +- +-

    +- The files that are no longer being analyzed. +-

    +-
    +-
    +-
    +- +-

    +- Reports the folding regions associated with a given +- file. Folding regions can be nested, but will not be +- overlapping. Nesting occurs when a foldable element, such as +- a method, is nested inside another foldable element such as +- a class. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "FOLDING" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

    +- +- +- FilePath +-

    +- The file containing the folding regions. +-

    +-
    +- +- +- FoldingRegion +- +-

    +- The folding regions contained in the file. +-

    +-
    +-
    +-
    +- +-

    +- Reports the highlight regions associated with a given file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "HIGHLIGHTS" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

    +- +- +- FilePath +-

    +- The file containing the highlight regions. +-

    +-
    +- +- +- HighlightRegion +- +-

    +- The highlight regions contained in the file. Each +- highlight region represents a particular syntactic or +- semantic meaning associated with some range. Note that +- the highlight regions that are returned can overlap +- other highlight regions if there is more than one +- meaning associated with a particular region. +-

    +-
    +-
    +-
    +- +-

    +- Reports the classes that are implemented or extended and +- class members that are implemented or overridden in a file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "IMPLEMENTED" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

    +- +- +- FilePath +-

    +- The file with which the implementations are associated. +-

    +-
    +- +- +- ImplementedClass +- +-

    +- The classes defined in the file that are implemented or extended. +-

    +-
    +- +- +- ImplementedMember +- +-

    +- The member defined in the file that are implemented or overridden. +-

    +-
    +-
    +-
    +- +-

    +- Reports that the navigation information associated with a region of a +- single file has become invalid and should be re-requested. +-

    +-

    +- This notification is not subscribed to by default. Clients can +- subscribe by including the value "INVALIDATE" in the list of +- services passed in an analysis.setSubscriptions request. +-

    +- +- +- FilePath +-

    +- The file whose information has been invalidated. +-

    +-
    +- +- int +-

    +- The offset of the invalidated region. +-

    +-
    +- +- int +-

    +- The length of the invalidated region. +-

    +-
    +- +- int +-

    +- The delta to be applied to the offsets in information that follows +- the invalidated region in order to update it so that it doesn't +- need to be re-requested. +-

    +-
    +-
    +-
    +- +-

    +- Reports the navigation targets associated with a given file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "NAVIGATION" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

    +- +- +- FilePath +-

    +- The file containing the navigation regions. +-

    +-
    +- +- +- NavigationRegion +- +-

    +- The navigation regions contained in the file. +- The regions are sorted by their offsets. +- Each navigation region represents a list of targets +- associated with some range. The lists will usually +- contain a single target, but can contain more in the +- case of a part that is included in multiple libraries +- or in Dart code that is compiled against multiple +- versions of a package. Note that the navigation +- regions that are returned do not overlap other +- navigation regions. +-

    +-
    +- +- +- NavigationTarget +- +-

    +- The navigation targets referenced in the file. +- They are referenced by NavigationRegions by their +- index in this array. +-

    +-
    +- +- +- FilePath +- +-

    +- The files containing navigation targets referenced in the file. +- They are referenced by NavigationTargets by their +- index in this array. +-

    +-
    +-
    +-
    +- +-

    +- Reports the occurrences of references to elements within a +- single file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "OCCURRENCES" +- in the list of services passed in an +- analysis.setSubscriptions request. +-

    +- +- +- FilePath +-

    +- The file in which the references occur. +-

    +-
    +- +- +- Occurrences +- +-

    +- The occurrences of references to elements within the +- file. +-

    +-
    +-
    +-
    +- +-

    +- Reports the outline associated with a single file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "OUTLINE" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

    +- +- +- FilePath +-

    +- The file with which the outline is associated. +-

    +-
    +- +- FileKind +-

    +- The kind of the file. +-

    +-
    +- +- String +-

    +- The name of the library defined by the file using a "library" +- directive, or referenced by a "part of" directive. If both +- "library" and "part of" directives are present, then the +- "library" directive takes precedence. +- This field will be omitted if the file has neither "library" +- nor "part of" directives. +-

    +-
    +- +- Outline +-

    +- The outline associated with the file. +-

    +-
    +-
    +-
    +- +-

    +- Reports the overriding members in a file. +-

    +-

    +- This notification is not subscribed to by default. Clients +- can subscribe by including the value "OVERRIDES" in +- the list of services passed in an analysis.setSubscriptions +- request. +-

    +- +- +- FilePath +-

    +- The file with which the overrides are associated. +-

    +-
    +- +- +- Override +- +-

    +- The overrides associated with the file. +-

    +-
    +-
    +-
    +-
    +- +-

    +- The code completion domain contains commands related to +- getting code completion suggestions. +-

    +- +-

    +- Request that completion suggestions for the given offset in +- the given file be returned. +-

    +- +- +- FilePath +-

    +- The file containing the point at which suggestions are +- to be made. +-

    +-
    +- +- int +-

    +- The offset within the file at which suggestions are to +- be made. +-

    +-
    +-
    +- +- +- CompletionId +-

    +- The identifier used to associate results with this +- completion request. +-

    +-
    +-
    +-
    +- +-

    +- Reports the completion suggestions that should be presented +- to the user. The set of suggestions included in the +- notification is always a complete list that supersedes any +- previously reported suggestions. +-

    +- +- +- CompletionId +-

    +- The id associated with the completion. +-

    +-
    +- +- int +-

    +- The offset of the start of the text to be +- replaced. This will be different than the offset used +- to request the completion suggestions if there was a +- portion of an identifier before the original +- offset. In particular, the replacementOffset will be +- the offset of the beginning of said identifier. +-

    +-
    +- +- int +-

    +- The length of the text to be replaced if the remainder +- of the identifier containing the cursor is to be +- replaced when the suggestion is applied (that is, the +- number of characters in the existing identifier). +-

    +-
    +- +- +- CompletionSuggestion +- +-

    +- The completion suggestions being reported. The +- notification contains all possible completions at the +- requested cursor position, even those that do not match +- the characters the user has already typed. This allows +- the client to respond to further keystrokes from the +- user without having to make additional requests. +-

    +-
    +- +- bool +-

    +- True if this is that last set of results that will be +- returned for the indicated completion. +-

    +-
    +-
    +-
    +-
    +- +-

    +- The search domain contains commands related to searches that +- can be performed against the code base. +-

    +- +-

    +- Perform a search for references to the element defined or +- referenced at the given offset in the given file. +-

    +-

    +- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

    +- +- +- FilePath +-

    +- The file containing the declaration of or reference to +- the element used to define the search. +-

    +-
    +- +- int +-

    +- The offset within the file of the declaration of or +- reference to the element. +-

    +-
    +- +- bool +-

    +- True if potential matches are to be included in the +- results. +-

    +-
    +-
    +- +- +- SearchId +-

    +- The identifier used to associate results with this +- search request. +-

    +-

    +- If no element was found at the given location, this +- field will be absent, and no results will be reported +- via the search.results notification. +-

    +-
    +- +- Element +-

    +- The element referenced or defined at the given offset +- and whose references will be returned in the search +- results. +-

    +-

    +- If no element was found at the given location, this +- field will be absent. +-

    +-
    +-
    +-
    +- +-

    +- Perform a search for declarations of members whose name is +- equal to the given name. +-

    +-

    +- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

    +- +- +- String +-

    +- The name of the declarations to be found. +-

    +-
    +-
    +- +- +- SearchId +-

    +- The identifier used to associate results with this +- search request. +-

    +-
    +-
    +-
    +- +-

    +- Perform a search for references to members whose name is +- equal to the given name. This search does not check to see +- that there is a member defined with the given name, so it is +- able to find references to undefined members as well. +-

    +-

    +- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

    +- +- +- String +-

    +- The name of the references to be found. +-

    +-
    +-
    +- +- +- SearchId +-

    +- The identifier used to associate results with this +- search request. +-

    +-
    +-
    +-
    +- +-

    +- Perform a search for declarations of top-level elements +- (classes, typedefs, getters, setters, functions and fields) +- whose name matches the given pattern. +-

    +-

    +- An identifier is returned immediately, and individual +- results will be returned via the search.results notification +- as they become available. +-

    +- +- +- String +-

    +- The regular expression used to match the names of the +- declarations to be found. +-

    +-
    +-
    +- +- +- SearchId +-

    +- The identifier used to associate results with this +- search request. +-

    +-
    +-
    +-
    +- +-

    +- Return the type hierarchy of the class declared or +- referenced at the given location. +-

    +- +- +- FilePath +-

    +- The file containing the declaration or reference to the +- type for which a hierarchy is being requested. +-

    +-
    +- +- int +-

    +- The offset of the name of the type within the file. +-

    +-
    +- +- bool +-

    +- True if the client is only requesting superclasses and +- interfaces hierarchy. +-

    +-
    +-
    +- +- +- +- TypeHierarchyItem +- +-

    +- A list of the types in the requested hierarchy. The +- first element of the list is the item representing the +- type for which the hierarchy was requested. The index of +- other elements of the list is unspecified, but +- correspond to the integers used to reference supertype +- and subtype items within the items. +-

    +-

    +- This field will be absent if the code at the given file +- and offset does not represent a type, or if the file has +- not been sufficiently analyzed to allow a type hierarchy +- to be produced. +-

    +-
    +-
    +-
    +- +-

    +- Reports some or all of the results of performing a requested +- search. Unlike other notifications, this notification +- contains search results that should be added to any +- previously received search results associated with the same +- search id. +-

    +- +- +- SearchId +-

    +- The id associated with the search. +-

    +-
    +- +- +- SearchResult +- +-

    +- The search results being reported. +-

    +-
    +- +- bool +-

    +- True if this is that last set of results that will be +- returned for the indicated search. +-

    +-
    +-
    +-
    +-
    +- +-

    +- The edit domain contains commands related to edits that can be +- applied to the code. +-

    +- +-

    +- Format the contents of a single file. The currently selected region of +- text is passed in so that the selection can be preserved across the +- formatting operation. The updated selection will be as close to +- matching the original as possible, but whitespace at the beginning or +- end of the selected region will be ignored. If preserving selection +- information is not required, zero (0) can be specified for both the +- selection offset and selection length. +-

    +-

    +- If a request is made for a file which does not exist, or which is not +- currently subject to analysis (e.g. because it is not associated with +- any analysis root specified to analysis.setAnalysisRoots), an error of +- type FORMAT_INVALID_FILE will be generated. If the source +- contains syntax errors, an error of type FORMAT_WITH_ERRORS +- will be generated. +-

    +- +- +- FilePath +-

    +- The file containing the code to be formatted. +-

    +-
    +- +- int +-

    +- The offset of the current selection in the file. +-

    +-
    +- +- int +-

    +- The length of the current selection in the file. +-

    +-
    +- +- +- int +-

    +- The line length to be used by the formatter. +-

    +-
    +-
    +- +- +- +- SourceEdit +- +-

    +- The edit(s) to be applied in order to format the code. The list +- will be empty if the code was already formatted (there are no +- changes). +-

    +-
    +- +- int +-

    +- The offset of the selection after formatting the code. +-

    +-
    +- +- int +-

    +- The length of the selection after formatting the code. +-

    +-
    +-
    +-
    +- +-

    +- Return the set of assists that are available at the given +- location. An assist is distinguished from a refactoring +- primarily by the fact that it affects a single file and does +- not require user input in order to be performed. +-

    +- +- +- FilePath +-

    +- The file containing the code for which assists are being +- requested. +-

    +-
    +- +- int +-

    +- The offset of the code for which assists are being +- requested. +-

    +-
    +- +- int +-

    +- The length of the code for which assists are being +- requested. +-

    +-
    +-
    +- +- +- +- SourceChange +- +-

    +- The assists that are available at the given location. +-

    +-
    +-
    +-
    +- +-

    +- Get a list of the kinds of refactorings that are valid for +- the given selection in the given file. +-

    +- +- +- FilePath +-

    +- The file containing the code on which the refactoring +- would be based. +-

    +-
    +- +- int +-

    +- The offset of the code on which the refactoring would be +- based. +-

    +-
    +- +- int +-

    +- The length of the code on which the refactoring would be +- based. +-

    +-
    +-
    +- +- +- +- RefactoringKind +- +-

    +- The kinds of refactorings that are valid for the given +- selection. +-

    +-
    +-
    +-
    +- +-

    +- Return the set of fixes that are available for the errors at +- a given offset in a given file. +-

    +- +- +- FilePath +-

    +- The file containing the errors for which fixes are being +- requested. +-

    +-
    +- +- int +-

    +- The offset used to select the errors for which fixes +- will be returned. +-

    +-
    +-
    +- +- +- +- AnalysisErrorFixes +- +-

    +- The fixes that are available for the errors at the given offset. +-

    +-
    +-
    +-
    +- +-

    +- Get the changes required to convert the postfix template at the given +- location into the template's expanded form. +-

    +- +- +- FilePath +-

    +- The file containing the postfix template to be expanded. +-

    +-
    +- +- String +-

    +- The unique name that identifies the template in use. +-

    +-
    +- +- int +-

    +- The offset used to identify the code to which the template will be +- applied. +-

    +-
    +-
    +- +- +- SourceChange +-

    +- The change to be applied in order to complete the statement. +-

    +-
    +-
    +-
    +- +-

    +- Get the changes required to perform a refactoring. +-

    +-

    +- If another refactoring request is received during the processing +- of this one, an error of type REFACTORING_REQUEST_CANCELLED +- will be generated. +-

    +- +- +- RefactoringKind +-

    +- The kind of refactoring to be performed. +-

    +-
    +- +- FilePath +-

    +- The file containing the code involved in the +- refactoring. +-

    +-
    +- +- int +-

    +- The offset of the region involved in the refactoring. +-

    +-
    +- +- int +-

    +- The length of the region involved in the refactoring. +-

    +-
    +- +- bool +-

    +- True if the client is only requesting that the values of +- the options be validated and no change be generated. +-

    +-
    +- +- RefactoringOptions +-

    +- Data used to provide values provided by the user. The +- structure of the data is dependent on the kind of +- refactoring being performed. The data that is expected is +- documented in the section titled Refactorings, labeled as +- "Options". This field can be omitted if the refactoring +- does not require any options or if the values of those +- options are not known. +-

    +-
    +-
    +- +- +- +- RefactoringProblem +- +-

    +- The initial status of the refactoring, i.e. problems related to +- the context in which the refactoring is requested. +- The array will be empty if there are no known problems. +-

    +-
    +- +- +- RefactoringProblem +- +-

    +- The options validation status, i.e. problems in the given options, +- such as light-weight validation of a new name, flags +- compatibility, etc. +- The array will be empty if there are no known problems. +-

    +-
    +- +- +- RefactoringProblem +- +-

    +- The final status of the refactoring, i.e. problems identified in +- the result of a full, potentially expensive validation and / or +- change creation. +- The array will be empty if there are no known problems. +-

    +-
    +- +- RefactoringFeedback +-

    +- Data used to provide feedback to the user. The structure +- of the data is dependent on the kind of refactoring +- being created. The data that is returned is documented +- in the section titled Refactorings, labeled as +- "Feedback". +-

    +-
    +- +- SourceChange +-

    +- The changes that are to be applied to affect the +- refactoring. This field will be omitted if there are +- problems that prevent a set of changes from being +- computed, such as having no options specified for a +- refactoring that requires them, or if only validation +- was requested. +-

    +-
    +- +- +- String +- +-

    +- The ids of source edits that are not known to be valid. An edit is +- not known to be valid if there was insufficient type information +- for the server to be able to determine whether or not the code +- needs to be modified, such as when a member is being renamed and +- there is a reference to a member from an unknown type. This field +- will be omitted if the change field is omitted or if there are no +- potential edits for the refactoring. +-

    +-
    +-
    +-
    +- +-

    +- Get the changes required to convert the partial statement at the given +- location into a syntactically valid statement. If the current statement +- is already valid the change will insert a newline plus appropriate +- indentation at the end of the line containing the offset. +- If a change that makes the statement valid cannot be determined (perhaps +- because it has not yet been implemented) the statement will be considered +- already valid and the appropriate change returned. +-

    +- +- +- FilePath +-

    +- The file containing the statement to be completed. +-

    +-
    +- +- int +-

    +- The offset used to identify the statement to be completed. +-

    +-
    +-
    +- +- +- SourceChange +-

    +- The change to be applied in order to complete the statement. +-

    +-
    +- +- bool +-

    +- Will be true if the change contains nothing but whitespace +- characters, or is empty. +-

    +-
    +-
    +-
    +- +-

    +- Determine if the request postfix completion template is applicable at +- the given location in the given file. +-

    +- +- +- FilePath +-

    +- The file containing the postfix template to be expanded. +-

    +-
    +- +- String +-

    +- The unique name that identifies the template in use. +-

    +-
    +- +- int +-

    +- The offset used to identify the code to which the template will be +- applied. +-

    +-
    +-
    +- +- +- bool +-

    +- True if the template can be expanded at the given location. +-

    +-
    +-
    +-
    +- +-

    +- Return a list of all postfix templates currently available. +-

    +- +- +- +- PostfixTemplateDescriptor +- +-

    +- The list of available templates. +-

    +-
    +-
    +-
    +- +-

    +- Return a list of edits that would need to be applied in order to ensure +- that all of the elements in the specified list of imported elements are +- accessible within the library. +-

    +-

    +- If a request is made for a file that does not exist, or that is not +- currently subject to analysis (e.g. because it is not associated with any +- analysis root specified via analysis.setAnalysisRoots), an error of type +- IMPORT_ELEMENTS_INVALID_FILE will be generated. +-

    +- +- +- FilePath +-

    +- The file in which the specified elements are to be made accessible. +-

    +-
    +- +- +- ImportedElements +- +-

    +- The elements to be made accessible in the specified file. +-

    +-
    +-
    +- +- +- SourceFileEdit +-

    +- The edits to be applied in order to make the specified elements +- accessible. The file to be edited will be the defining compilation +- unit of the library containing the file specified in the request, +- which can be different than the file specified in the request if the +- specified file is a part file. +-

    +-
    +-
    +-
    +- +-

    +- Sort all of the directives, unit and class members +- of the given Dart file. +-

    +-

    +- If a request is made for a file that does not exist, does not belong +- to an analysis root or is not a Dart file, +- SORT_MEMBERS_INVALID_FILE will be generated. +-

    +-

    +- If the Dart file has scan or parse errors, +- SORT_MEMBERS_PARSE_ERRORS will be generated. +-

    +- +- +- FilePath +-

    +- The Dart file to sort. +-

    +-
    +-
    +- +- +- SourceFileEdit +-

    +- The file edit that is to be applied to the given file to effect +- the sorting. +-

    +-
    +-
    +-
    +- +-

    +- Organizes all of the directives - removes unused imports and sorts +- directives of the given Dart file according to the +- Dart Style +- Guide. +-

    +-

    +- If a request is made for a file that does not exist, does not belong +- to an analysis root or is not a Dart file, +- FILE_NOT_ANALYZED will be generated. +-

    +-

    +- If directives of the Dart file cannot be organized, for example +- because it has scan or parse errors, or by other reasons, +- ORGANIZE_DIRECTIVES_ERROR will be generated. The message +- will provide details about the reason. +-

    +- +- +- FilePath +-

    +- The Dart file to organize directives in. +-

    +-
    +-
    +- +- +- SourceFileEdit +-

    +- The file edit that is to be applied to the given file to effect +- the organizing. +-

    +-
    +-
    +-
    +-
    +- +-

    +- The execution domain contains commands related to providing an execution +- or debugging experience. +-

    +- +-

    +- Create an execution context for the executable file with the given +- path. The context that is created will persist until +- execution.deleteContext is used to delete it. Clients, therefore, are +- responsible for managing the lifetime of execution contexts. +-

    +- +- +- FilePath +-

    +- The path of the Dart or HTML file that will be launched, or the +- path of the directory containing the file. +-

    +-
    +-
    +- +- +- ExecutionContextId +-

    +- The identifier used to refer to the execution context that was +- created. +-

    +-
    +-
    +-
    +- +-

    +- Delete the execution context with the given identifier. The context id +- is no longer valid after this command. The server is allowed to re-use +- ids when they are no longer valid. +-

    +- +- +- ExecutionContextId +-

    +- The identifier of the execution context that is to be deleted. +-

    +-
    +-
    +-
    +- +-

    +- Map a URI from the execution context to the file that it corresponds +- to, or map a file to the URI that it corresponds to in the execution +- context. +-

    +-

    +- Exactly one of the file and uri fields must be provided. If both +- fields are provided, then an error of type INVALID_PARAMETER +- will be generated. Similarly, if neither field is provided, then an +- error of type INVALID_PARAMETER will be generated. +-

    +-

    +- If the file field is provided and the value is not the path of a file +- (either the file does not exist or the path references something other +- than a file), then an error of type INVALID_PARAMETER will +- be generated. +-

    +-

    +- If the uri field is provided and the value is not a valid URI or if +- the URI references something that is not a file (either a file that +- does not exist or something other than a file), then an error of type +- INVALID_PARAMETER will be generated. +-

    +-

    +- If the contextRoot used to create the execution context does not +- exist, then an error of type INVALID_EXECUTION_CONTEXT will +- be generated. +-

    +- +- +- ExecutionContextId +-

    +- The identifier of the execution context in which the URI is to be +- mapped. +-

    +-
    +- +- FilePath +-

    +- The path of the file to be mapped into a URI. +-

    +-
    +- +- String +-

    +- The URI to be mapped into a file path. +-

    +-
    +-
    +- +- +- FilePath +-

    +- The file to which the URI was mapped. This field is omitted if the +- uri field was not given in the request. +-

    +-
    +- +- String +-

    +- The URI to which the file path was mapped. This field is omitted +- if the file field was not given in the request. +-

    +-
    +-
    +-
    +- +-

    +- Deprecated: the analysis server no longer fires +- LAUNCH_DATA events. +-

    +-

    +- Subscribe for services. All previous subscriptions are replaced by the +- given set of services. +-

    +-

    +- It is an error if any of the elements in the list are not valid +- services. If there is an error, then the current subscriptions will +- remain unchanged. +-

    +- +- +- +- ExecutionService +- +-

    +- A list of the services being subscribed to. +-

    +-
    +-
    +-
    +- +-

    +- Reports information needed to allow a single file to be launched. +-

    +-

    +- This notification is not subscribed to by default. Clients can +- subscribe by including the value "LAUNCH_DATA" in the list of services +- passed in an execution.setSubscriptions request. +-

    +- +- +- FilePath +-

    +- The file for which launch data is being provided. This will either +- be a Dart library or an HTML file. +-

    +-
    +- +- ExecutableKind +-

    +- The kind of the executable file. This field is omitted if the file +- is not a Dart file. +-

    +-
    +- +- +- FilePath +- +-

    +- A list of the Dart files that are referenced by the file. This +- field is omitted if the file is not an HTML file. +-

    +-
    +-
    +-
    +-
    +- +-

    +- The diagnostic domain contains server diagnostics APIs. +-

    +- +-

    Return server diagnostics.

    +- +- +- +- ContextData +- +-

    The list of analysis contexts.

    +-
    +-
    +-
    +- +-

    +- Return the port of the diagnostic web server. If the server is not running +- this call will start the server. If unable to start the diagnostic web +- server, +- this call will return an error of DEBUG_PORT_COULD_NOT_BE_OPENED. +-

    +- +- +- int +-

    The diagnostic server port.

    +-
    +-
    +-
    +-
    +- +-

    +- The analytics domain contains APIs related to reporting analytics. +-

    +-

    +- This API allows clients to expose a UI option to enable and disable the +- analysis server's reporting of analytics. This value is shared with other +- tools and can change outside of this API; because of this, clients should +- use the analysis server's flag as the system of record. Clients can choose +- to send in additional analytics (see sendEvent and +- sendTiming) if they so choose. Dart command-line tools provide a +- disclaimer similar to: +- +- Dart SDK tools anonymously report feature usage statistics and basic crash +- reports to help improve Dart tools over time. See Google's privacy policy: +- https://www.google.com/intl/en/policies/privacy/. +- +-

    +-

    +- The analysis server will send it's own analytics data (for example, +- operations performed, operating system type, SDK version). No data (from the +- analysis server or from clients) will be sent if analytics is disabled. +-

    +- +-

    Query whether analytics is enabled.

    +-

    +- This flag controls whether the analysis server sends any analytics data to +- the cloud. If disabled, the analysis server does not send any analytics +- data, and any data sent to it by clients (from sendEvent and +- sendTiming) will be ignored. +-

    +-

    +- The value of this flag can be changed by other tools outside of the +- analysis server's process. When you query the flag, you get the value of +- the flag at a given moment. Clients should not use the value returned to +- decide whether or not to send the sendEvent and +- sendTiming requests. Those requests should be used +- unconditionally and server will determine whether or not it is appropriate +- to forward the information to the cloud at the time each request is +- received. +-

    +- +- +- bool +-

    Whether sending analytics is enabled or not.

    +-
    +-
    +-
    +- +-

    +- Enable or disable the sending of analytics data. Note that there are other +- ways for users to change this setting, so clients cannot assume that they +- have complete control over this setting. In particular, there is no +- guarantee that the result returned by the isEnabled request will +- match the last value set via this request. +-

    +- +- +- bool +-

    Enable or disable analytics.

    +-
    +-
    +-
    +- +-

    Send information about client events.

    +-

    +- Ask the analysis server to include the fact that an action was performed +- in the client as part of the analytics data being sent. The data will only +- be included if the sending of analytics data is enabled at the time the +- request is processed. The action that was performed is indicated by the +- value of the action field. +-

    +-

    +- The value of the action field should not include the identity of the +- client. The analytics data sent by server will include the client id +- passed in using the --client-id command-line argument. The +- request will be ignored if the client id was not provided when server was +- started. +-

    +- +- +- String +-

    The value used to indicate which action was performed.

    +-
    +-
    +-
    +- +-

    Send timing information for client events (e.g. code completions).

    +-

    +- Ask the analysis server to include the fact that a timed event occurred as +- part of the analytics data being sent. The data will only be included if +- the sending of analytics data is enabled at the time the request is +- processed. +-

    +-

    +- The value of the event field should not include the identity of the +- client. The analytics data sent by server will include the client id +- passed in using the --client-id command-line argument. The +- request will be ignored if the client id was not provided when server was +- started. +-

    +- +- +- String +-

    The name of the event.

    +-
    +- +- int +-

    The duration of the event in milliseconds.

    +-
    +-
    +-
    +-
    +- +-

    +- The kythe domain contains APIs related to generating Dart content in the +- Kythe format. +-

    +- +-

    +- Return the list of KytheEntry objects for some file, given the +- current state of the file system populated by "analysis.updateContent". +-

    +-

    +- If a request is made for a file that does not exist, or that is not +- currently subject to analysis (e.g. because it is not associated with any +- analysis root specified to analysis.setAnalysisRoots), an error of type +- GET_KYTHE_ENTRIES_INVALID_FILE will be generated. +-

    +- +- +- FilePath +-

    +- The file containing the code for which the Kythe Entry objects are +- being requested. +-

    +-
    +-
    +- +- +- +- KytheEntry +- +-

    +- The list of KytheEntry objects for the queried file. +-

    +-
    +- +- +- FilePath +- +-

    +- The set of files paths that were required, but not in the file system, +- to give a complete and accurate Kythe graph for the file. This could +- be due to a referenced file that does not exist or generated files not +- being generated or passed before the call to "getKytheEntries". +-

    +-
    +-
    +-
    +-
    +- +-

    Types

    +-

    +- This section contains descriptions of the data types referenced +- in the API’s of the various domains. +-

    +- +- +-

    +- A list of fixes associated with a specific error. +-

    +- +- +- AnalysisError +-

    +- The error with which the fixes are associated. +-

    +-
    +- +- +- SourceChange +- +-

    +- The fixes associated with the error. +-

    +-
    +-
    +-
    +- +-

    Deprecated: the only reference to this type has been +- deprecated.

    +-

    +- A set of options controlling what kind of analysis is to be +- performed. If the value of a field is omitted the value of the +- option will not be changed. +-

    +- +- +- bool +-

    Deprecated: this feature is always enabled.

    +-

    +- True if the client wants to enable support for the +- proposed async feature. +-

    +-
    +- +- bool +-

    Deprecated: this feature is always enabled.

    +-

    +- True if the client wants to enable support for the +- proposed deferred loading feature. +-

    +-
    +- +- bool +-

    Deprecated: this feature is always enabled.

    +-

    +- True if the client wants to enable support for the +- proposed enum feature. +-

    +-
    +- +- bool +-

    Deprecated: this feature is always enabled.

    +-

    +- True if the client wants to enable support for the +- proposed "null aware operators" feature. +-

    +-
    +- +- bool +-

    +- True if the client wants to enable support for the +- proposed "less restricted mixins" proposal (DEP 34). +-

    +-
    +- +- bool +-

    +- True if hints that are specific to dart2js should be +- generated. This option is ignored if generateHints is false. +-

    +-
    +- +- bool +-

    +- True if hints should be generated as part of generating +- errors and warnings. +-

    +-
    +- +- bool +-

    +- True if lints should be generated as part of generating +- errors and warnings. +-

    +-
    +-
    +-
    +- +-

    +- An enumeration of the services provided by the analysis domain that +- are related to a specific list of files. +-

    +- +- CLOSING_LABELS +- FOLDING +- HIGHLIGHTS +- IMPLEMENTED +- +- INVALIDATE +-

    +- This service is not currently implemented and will become a +- GeneralAnalysisService in a future release. +-

    +-
    +- NAVIGATION +- OCCURRENCES +- OUTLINE +- OVERRIDES +-
    +-
    +- +-

    +- An indication of the current state of analysis. +-

    +- +- +- bool +-

    True if analysis is currently being performed.

    +-
    +- +- String +-

    +- The name of the current target of analysis. This field is +- omitted if analyzing is false. +-

    +-
    +-
    +-
    +- +-

    +- A label that is associated with a range of code that may be useful to +- render at the end of the range to aid code readability. For example, a +- constructor call that spans multiple lines may result in a closing label +- to allow the constructor type/name to be rendered alongside the closing +- parenthesis. +-

    +- +- +- int +-

    +- The offset of the construct being labelled. +-

    +-
    +- +- int +-

    +- The length of the whole construct to be labelled. +-

    +-
    +- +- String +-

    +- The label associated with this range that should be displayed to the +- user. +-

    +-
    +-
    +-
    +- +- String +-

    +- An identifier used to associate completion results with a +- completion request. +-

    +-
    +- +-

    +- Information about an analysis context. +-

    +- +- +- String +-

    +- The name of the context. +-

    +-
    +- +- int +-

    +- Explicitly analyzed files. +-

    +-
    +- +- int +-

    +- Implicitly analyzed files. +-

    +-
    +- +- int +-

    +- The number of work items in the queue. +-

    +-
    +- +- +- String +- +-

    +- Exceptions associated with cache entries. +-

    +-
    +-
    +-
    +- +-

    +- A description of an executable file. +-

    +- +- +- FilePath +-

    +- The path of the executable file. +-

    +-
    +- +- ExecutableKind +-

    +- The kind of the executable file. +-

    +-
    +-
    +-
    +- +-

    +- An enumeration of the kinds of executable files. +-

    +- +- CLIENT +- EITHER +- NOT_EXECUTABLE +- SERVER +- +-
    +- +- String +-

    +- The identifier for a execution context. +-

    +-
    +- +-

    +- An enumeration of the services provided by the execution +- domain. +-

    +- +- LAUNCH_DATA +- +-
    +- +-

    +- An enumeration of the kinds of files. +-

    +- +- LIBRARY +- PART +- +-
    +- +-

    +- An enumeration of the services provided by the analysis domain that are +- general in nature (that is, are not specific to some list of files). +-

    +- +- ANALYZED_FILES +- +-
    +- +-

    +- The hover information associated with a specific location. +-

    +- +- +- int +-

    +- The offset of the range of characters that encompasses the +- cursor position and has the same hover information as the +- cursor position. +-

    +-
    +- +- int +-

    +- The length of the range of characters that encompasses the +- cursor position and has the same hover information as the +- cursor position. +-

    +-
    +- +- String +-

    +- The path to the defining compilation unit of the library +- in which the referenced element is declared. This data is +- omitted if there is no referenced element, or if the +- element is declared inside an HTML file. +-

    +-
    +- +- String +-

    +- The name of the library in which the referenced element is +- declared. This data is omitted if there is no referenced +- element, or if the element is declared inside an HTML +- file. +-

    +-
    +- +- String +-

    +- A human-readable description of the class declaring the element +- being referenced. This data is omitted if there is no referenced +- element, or if the element is not a class member. +-

    +-
    +- +- String +-

    +- The dartdoc associated with the referenced element. Other +- than the removal of the comment delimiters, including +- leading asterisks in the case of a block comment, the +- dartdoc is unprocessed markdown. This data is omitted if +- there is no referenced element, or if the element has no +- dartdoc. +-

    +-
    +- +- String +-

    +- A human-readable description of the element being +- referenced. This data is omitted if there is no referenced +- element. +-

    +-
    +- +- String +-

    +- A human-readable description of the kind of element being +- referenced (such as "class" or "function type +- alias"). This data is omitted if there is no referenced +- element. +-

    +-
    +- +- bool +-

    +- True if the referenced element is deprecated. +-

    +-
    +- +- String +-

    +- A human-readable description of the parameter +- corresponding to the expression being hovered over. This +- data is omitted if the location is not in an argument to a +- function. +-

    +-
    +- +- String +-

    +- The name of the propagated type of the expression. This +- data is omitted if the location does not correspond to an +- expression or if there is no propagated type information. +-

    +-
    +- +- String +-

    +- The name of the static type of the expression. This data +- is omitted if the location does not correspond to an +- expression. +-

    +-
    +-
    +-
    +- +-

    +- A description of a class that is implemented or extended. +-

    +- +- +- int +-

    +- The offset of the name of the implemented class. +-

    +-
    +- +- int +-

    +- The length of the name of the implemented class. +-

    +-
    +-
    +-
    +- +-

    +- A description of a class member that is implemented or overridden. +-

    +- +- +- int +-

    +- The offset of the name of the implemented member. +-

    +-
    +- +- int +-

    +- The length of the name of the implemented member. +-

    +-
    +-
    +-
    +- +-

    +- A description of the elements that are referenced in a region of a file +- that come from a single imported library. +-

    +- +- +- FilePath +-

    +- The absolute and normalized path of the file containing the library. +-

    +-
    +- +- String +-

    +- The prefix that was used when importing the library into the original +- source. +-

    +-
    +- +- +- String +- +-

    +- The names of the elements imported from the library. +-

    +-
    +-
    +-
    +- +-

    +- A description of a member that overrides an inherited member. +-

    +- +- +- int +-

    +- The offset of the name of the overriding member. +-

    +-
    +- +- int +-

    +- The length of the name of the overriding member. +-

    +-
    +- +- OverriddenMember +-

    +- The member inherited from a superclass that is overridden +- by the overriding member. The field is omitted if there is +- no superclass member, in which case there must be at least +- one interface member. +-

    +-
    +- +- +- OverriddenMember +- +-

    +- The members inherited from interfaces that are overridden +- by the overriding member. The field is omitted if there +- are no interface members, in which case there must be a +- superclass member. +-

    +-
    +-
    +-
    +- +-

    +- A description of a member that is being overridden. +-

    +- +- +- Element +-

    +- The element that is being overridden. +-

    +-
    +- +- String +-

    +- The name of the class in which the member is defined. +-

    +-
    +-
    +-
    +- +-

    +- The description of a postfix completion template. +-

    +- +- +- String +-

    +- The template name, shown in the UI. +-

    +-
    +- +- String +-

    +- The unique template key, not shown in the UI. +-

    +-
    +- +- String +-

    +- A short example of the transformation performed when the template is +- applied. +-

    +-
    +-
    +-
    +- +-

    +- An indication of the current state of pub execution. +-

    +- +- +- bool +-

    +- True if the server is currently running pub to produce a list of +- package directories. +-

    +-
    +-
    +-
    +- +-

    +- An abstract superclass of all refactoring feedbacks. +-

    +- +- +-
    +- +-

    +- An abstract superclass of all refactoring options. +-

    +- +- +-
    +- +-

    +- An indication of a problem with the execution of the server, +- typically in response to a request. +-

    +- +- +- RequestErrorCode +-

    +- A code that uniquely identifies the error that occurred. +-

    +-
    +- +- String +-

    +- A short description of the error. +-

    +-
    +- +- String +-

    +- The stack trace associated with processing the request, +- used for debugging the server. +-

    +-
    +-
    +-
    +- +-

    +- An enumeration of the types of errors that can occur in the +- execution of the server. +-

    +- +- +- CONTENT_MODIFIED +-

    +- An "analysis.getErrors" or "analysis.getNavigation" request could +- not be satisfied because the content of the file changed before +- the requested results could be computed. +-

    +-
    +- +- DEBUG_PORT_COULD_NOT_BE_OPENED +-

    +- The server was unable to open a port for the diagnostic server. +-

    +-
    +- +- FILE_NOT_ANALYZED +-

    +- A request specified a FilePath which does not match a file in +- an analysis root, or the requested operation is not available +- for the file. +-

    +-
    +- +- FORMAT_INVALID_FILE +-

    +- An "edit.format" request specified a FilePath +- which does not match a Dart file in an analysis root. +-

    +-
    +- +- FORMAT_WITH_ERRORS +-

    +- An "edit.format" request specified a file that contains syntax +- errors. +-

    +-
    +- +- GET_ERRORS_INVALID_FILE +-

    +- An "analysis.getErrors" request specified a FilePath +- which does not match a file currently subject to +- analysis. +-

    +-
    +- +- GET_IMPORTED_ELEMENTS_INVALID_FILE +-

    +- An "analysis.getImportedElements" request specified a FilePath that +- does not match a file currently subject to analysis. +-

    +-
    +- +- GET_KYTHE_ENTRIES_INVALID_FILE +-

    +- An "analysis.getKytheEntries" request specified a FilePath that does +- not match a file that is currently subject to analysis. +-

    +-
    +- +- GET_NAVIGATION_INVALID_FILE +-

    +- An "analysis.getNavigation" request specified a FilePath +- which does not match a file currently subject to +- analysis. +-

    +-
    +- +- GET_REACHABLE_SOURCES_INVALID_FILE +-

    +- An "analysis.getReachableSources" request specified a FilePath +- which does not match a file currently subject to +- analysis. +-

    +-
    +- +- IMPORT_ELEMENTS_INVALID_FILE +-

    +- An "edit.importElements" request specified a FilePath that does not +- match a file currently subject to analysis. +-

    +-
    +- +- INVALID_ANALYSIS_ROOT +-

    +- A path passed as an argument to a request (such as +- analysis.reanalyze) is required to be an analysis root, but isn't. +-

    +-
    +- +- INVALID_EXECUTION_CONTEXT +-

    +- The context root used to create an execution context does not +- exist. +-

    +-
    +- +- INVALID_FILE_PATH_FORMAT +-

    +- The format of the given file path is invalid, e.g. is not +- absolute and normalized. +-

    +-
    +- +- INVALID_OVERLAY_CHANGE +-

    +- An "analysis.updateContent" request contained a +- ChangeContentOverlay object which can't be applied, due +- to an edit having an offset or length that is out of +- range. +-

    +-
    +- +- INVALID_PARAMETER +-

    +- One of the method parameters was invalid. +-

    +-
    +- +- INVALID_REQUEST +-

    +- A malformed request was received. +-

    +-
    +- +- ORGANIZE_DIRECTIVES_ERROR +-

    +- An "edit.organizeDirectives" request specified a Dart file that +- cannot be analyzed. The reason is described in the message. +-

    +-
    +- +- REFACTORING_REQUEST_CANCELLED +-

    +- Another refactoring request was received during processing of +- this one. +-

    +-
    +- +- SERVER_ALREADY_STARTED +-

    +- The analysis server has already been started (and hence +- won't accept new connections). +-

    +-

    +- This error is included for future expansion; at present +- the analysis server can only speak to one client at a +- time so this error will never occur. +-

    +-
    +- +- SERVER_ERROR +-

    +- An internal error occurred in the analysis server. +- Also see the server.error notification. +-

    +-
    +- +- SORT_MEMBERS_INVALID_FILE +-

    +- An "edit.sortMembers" request specified a FilePath +- which does not match a Dart file in an analysis root. +-

    +-
    +- +- SORT_MEMBERS_PARSE_ERRORS +-

    +- An "edit.sortMembers" request specified a Dart file that has +- scan or parse errors. +-

    +-
    +- +- UNANALYZED_PRIORITY_FILES +-

    +- An "analysis.setPriorityFiles" request includes one or +- more files that are not being analyzed. +-

    +-

    +- This is a legacy error; it will be removed before the +- API reaches version 1.0. +-

    +- +-
    +- +- UNKNOWN_REQUEST +-

    +- A request was received which the analysis server does +- not recognize, or cannot handle in its current +- configuration. +-

    +-
    +- +- UNKNOWN_SOURCE +-

    +- The analysis server was requested to perform an action +- on a source that does not exist. +-

    +-
    +- +- UNSUPPORTED_FEATURE +-

    +- The analysis server was requested to perform an action +- which is not supported. +-

    +-

    +- This is a legacy error; it will be removed before the +- API reaches version 1.0. +-

    +- +-
    +-
    +-
    +- +- String +-

    +- An identifier used to associate search results with a search +- request. +-

    +-
    +- +-

    +- A single result from a search request. +-

    +- +- +- Location +-

    +- The location of the code that matched the search criteria. +-

    +-
    +- +- SearchResultKind +-

    +- The kind of element that was found or the kind of +- reference that was found. +-

    +-
    +- +- bool +-

    +- True if the result is a potential match but cannot be +- confirmed to be a match. For example, if all references to +- a method m defined in some class were requested, and a +- reference to a method m from an unknown class were found, +- it would be marked as being a potential match. +-

    +-
    +- +- +- Element +- +-

    +- The elements that contain the result, starting with the +- most immediately enclosing ancestor and ending with the +- library. +-

    +-
    +-
    +-
    +- +-

    +- An enumeration of the kinds of search results returned by the +- search domain. +-

    +- +- +- DECLARATION +-

    +- The declaration of an element. +-

    +-
    +- +- INVOCATION +-

    +- The invocation of a function or method. +-

    +-
    +- +- READ +-

    +- A reference to a field, parameter or variable where it is being read. +-

    +-
    +- +- READ_WRITE +-

    +- A reference to a field, parameter or variable where it is being read +- and written. +-

    +-
    +- +- REFERENCE +-

    +- A reference to an element. +-

    +-
    +- +- UNKNOWN +-

    +- Some other kind of search result. +-

    +-
    +- +- WRITE +-

    +- A reference to a field, parameter or variable where it is being +- written. +-

    +-
    +-
    +-
    +- +-

    +- An enumeration of the services provided by the server domain. +-

    +- +- STATUS +- +-
    +- +-

    +- A representation of a class in a type hierarchy. +-

    +- +- +- Element +-

    +- The class element represented by this item. +-

    +-
    +- +- String +-

    +- The name to be displayed for the class. This field will be +- omitted if the display name is the same as the name of the +- element. The display name is different if there is +- additional type information to be displayed, such as type +- arguments. +-

    +-
    +- +- Element +-

    +- The member in the class corresponding to the member on +- which the hierarchy was requested. This field will be +- omitted if the hierarchy was not requested for a member or +- if the class does not have a corresponding member. +-

    +-
    +- +- int +-

    +- The index of the item representing the superclass of +- this class. This field will be omitted if this item +- represents the class Object. +-

    +-
    +- +- +- int +- +-

    +- The indexes of the items representing the interfaces +- implemented by this class. The list will be empty if +- there are no implemented interfaces. +-

    +-
    +- +- +- int +- +-

    +- The indexes of the items representing the mixins +- referenced by this class. The list will be empty if +- there are no classes mixed in to this class. +-

    +-
    +- +- +- int +- +-

    +- The indexes of the items representing the subtypes of +- this class. The list will be empty if there are no +- subtypes or if this item represents a supertype of the +- pivot type. +-

    +-
    +-
    +-
    +-
    +- +-

    Refactorings

    +-

    +- This section contains additional information for each kind of +- refactoring. In addition to a brief description of the +- refactoring, there is a specification of the feedback that is +- provided when a refactoring is requested using the +- edit.getRefactoring request (designed to improve the UX) +- and the options that may be provided to edit.getRefactoring. +-

    +- +-

    +- Convert a getter into a method by removing the keyword get +- and adding an empty parameter list. +-

    +-

    +- It is an error if the range contains anything other than all +- or part of the name of a single getter. +-

    +-
    +- +-

    +- Convert a method into a getter by adding the keyword get and +- removing the parameter list. +-

    +-

    +- It is an error if the range contains anything other than all +- or part of the name of a single method or if the method has +- a non-empty parameter list. +-

    +-
    +- +-

    +- Create a local variable initialized by the expression that covers +- the specified selection. +-

    +-

    +- It is an error if the selection range is not covered by a +- complete expression. +-

    +- +- +- +- int +- +-

    +- The offsets of the expressions that cover the specified +- selection, from the down most to the up most. +-

    +-
    +- +- +- int +- +-

    +- The lengths of the expressions that cover the specified +- selection, from the down most to the up most. +-

    +-
    +- +- +- String +- +-

    +- The proposed names for the local variable. +-

    +-
    +- +- +- int +- +-

    +- The offsets of the expressions that would be replaced by +- a reference to the variable. +-

    +-
    +- +- +- int +- +-

    +- The lengths of the expressions that would be replaced by +- a reference to the variable. The lengths correspond to +- the offsets. In other words, for a given expression, if +- the offset of that expression is offsets[i], then +- the length of that expression is lengths[i]. +-

    +-
    +-
    +- +- +- String +-

    +- The name that the local variable should be given. +-

    +-
    +- +- bool +-

    +- True if all occurrences of the expression within the +- scope in which the variable will be defined should be +- replaced by a reference to the local variable. The +- expression used to initiate the refactoring will always +- be replaced. +-

    +-
    +-
    +-
    +- +-

    +- Create a method whose body is the specified expression or +- list of statements, possibly augmented with a return +- statement. +-

    +-

    +- It is an error if the range contains anything other than a +- complete expression (no partial expressions are allowed) or +- a complete sequence of statements. +-

    +- +- +- int +-

    +- The offset to the beginning of the expression or +- statements that will be extracted. +-

    +-
    +- +- int +-

    +- The length of the expression or statements that will be +- extracted. +-

    +-
    +- +- String +-

    +- The proposed return type for the method. +- If the returned element does not have a declared return type, +- this field will contain an empty string. +-

    +-
    +- +- +- String +- +-

    +- The proposed names for the method. +-

    +-
    +- +- bool +-

    +- True if a getter could be created rather than a method. +-

    +-
    +- +- +- RefactoringMethodParameter +- +-

    +- The proposed parameters for the method. +-

    +-
    +- +- +- int +- +-

    +- The offsets of the expressions or statements that would +- be replaced by an invocation of the method. +-

    +-
    +- +- +- int +- +-

    +- The lengths of the expressions or statements that would +- be replaced by an invocation of the method. The lengths +- correspond to the offsets. In other words, for a given +- expression (or block of statements), if the offset of +- that expression is offsets[i], then the length +- of that expression is lengths[i]. +-

    +-
    +-
    +- +- +- String +-

    +- The return type that should be defined for the method. +-

    +-
    +- +- bool +-

    +- True if a getter should be created rather than a +- method. It is an error if this field is true and the +- list of parameters is non-empty. +-

    +-
    +- +- String +-

    +- The name that the method should be given. +-

    +-
    +- +- +- RefactoringMethodParameter +- +-

    +- The parameters that should be defined for the method. +-

    +-

    +- It is an error if a REQUIRED or NAMED parameter follows a +- POSITIONAL parameter. +- It is an error if a REQUIRED or POSITIONAL parameter follows a +- NAMED parameter. +-

    +-
      +-
    • +- To change the order and/or update proposed parameters, add +- parameters with the same identifiers as proposed. +-
    • +-
    • To add new parameters, omit their identifier.
    • +-
    • To remove some parameters, omit them in this list.
    • +-
    +-
    +- +- bool +-

    +- True if all occurrences of the expression or statements +- should be replaced by an invocation of the method. The +- expression or statements used to initiate the +- refactoring will always be replaced. +-

    +-
    +-
    +-
    +- +-

    +- Inline the initializer expression of a local variable in +- place of any references to that variable. +-

    +-

    +- It is an error if the range contains anything other than all +- or part of the name of a single local variable. +-

    +- +- +- String +-

    +- The name of the variable being inlined. +-

    +-
    +- +- int +-

    +- The number of times the variable occurs. +-

    +-
    +-
    +-
    +- +-

    +- Inline a method in place of one or all references to that +- method. +-

    +-

    +- It is an error if the range contains anything other than all +- or part of the name of a single method. +-

    +- +- +- String +-

    +- The name of the class enclosing the method being inlined. +- If not a class member is being inlined, this field will be absent. +-

    +-
    +- +- String +-

    +- The name of the method (or function) being inlined. +-

    +-
    +- +- bool +-

    +- True if the declaration of the method is selected. +- So all references should be inlined. +-

    +-
    +-
    +- +- +- bool +-

    +- True if the method being inlined should be removed. +- It is an error if this field is true and inlineAll is false. +-

    +-
    +- +- bool +-

    +- True if all invocations of the method should be inlined, +- or false if only the invocation site used to create this +- refactoring should be inlined. +-

    +-
    +-
    +-
    +- +-

    +- Move the given file and update all of the references to that file +- and from it. The move operation is supported in general case - for +- renaming a file in the same folder, moving it to a different folder +- or both. +-

    +-

    +- The refactoring must be activated before an actual file moving +- operation is performed. +-

    +-

    +- The "offset" and "length" fields from the request are ignored, but the +- file specified in the request specifies the file to be moved. +-

    +- +- +- FilePath +-

    +- The new file path to which the given file is being moved. +-

    +-
    +-
    +-
    +- +-

    +- Rename a given element and all of the references to that +- element. +-

    +-

    +- It is an error if the range contains anything other than all +- or part of the name of a single function (including methods, +- getters and setters), variable (including fields, parameters +- and local variables), class or function type. +-

    +- +- +- int +-

    +- The offset to the beginning of the name selected to be +- renamed. +-

    +-
    +- +- int +-

    +- The length of the name selected to be renamed. +-

    +-
    +- +- String +-

    +- The human-readable description of the kind of element being +- renamed (such as "class" or "function type +- alias"). +-

    +-
    +- +- String +-

    +- The old name of the element before the refactoring. +-

    +-
    +-
    +- +- +- String +-

    +- The name that the element should have after the +- refactoring. +-

    +-
    +-
    +-
    +-
    +-

    Errors

    +-

    +- This section contains a list of all of the errors that are +- produced by the server and the data that is returned with each. +-

    +-

    +- TODO: TBD +-

    +-

    Index

    +- +- +- +diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart +deleted file mode 100644 +index 82a93c753e9..00000000000 +--- a/pkg/analysis_server/tool/spec/to_html.dart ++++ /dev/null +@@ -1,831 +0,0 @@ +-// Copyright (c) 2014, 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. +- +-/** +- * Code for displaying the API as HTML. This is used both for generating a +- * full description of the API as a web page, and for generating doc comments +- * in generated code. +- */ +-import 'dart:convert'; +- +-import 'package:analyzer/src/codegen/html.dart'; +-import 'package:analyzer/src/codegen/tools.dart'; +-import 'package:front_end/src/codegen/tools.dart'; +-import 'package:html/dom.dart' as dom; +- +-import 'api.dart'; +-import 'from_html.dart'; +- +-/** +- * Embedded stylesheet +- */ +-final String stylesheet = ''' +-body { +- font-family: 'Roboto', sans-serif; +- max-width: 800px; +- margin: 0 auto; +- padding: 0 16px; +- font-size: 16px; +- line-height: 1.5; +- color: #111; +- background-color: #fdfdfd; +- font-weight: 300; +- -webkit-font-smoothing: auto; +-} +- +-h2, h3, h4, h5 { +- margin-bottom: 0; +-} +- +-h2.domain { +- border-bottom: 1px solid rgb(200, 200, 200); +- margin-bottom: 0.5em; +-} +- +-h4 { +- font-size: 18px; +-} +- +-h5 { +- font-size: 16px; +-} +- +-p { +- margin-top: 0; +-} +- +-pre { +- margin: 0; +- font-family: 'Source Code Pro', monospace; +- font-size: 15px; +-} +- +-div.box { +- background-color: rgb(240, 245, 240); +- border-radius: 4px; +- padding: 4px 12px; +- margin: 16px 0; +-} +- +-div.hangingIndent { +- padding-left: 3em; +- text-indent: -3em; +-} +- +-dl dt { +- font-weight: bold; +-} +- +-dl dd { +- margin-left: 16px; +-} +- +-dt { +- margin-top: 1em; +-} +- +-dt.notification { +- font-weight: bold; +-} +- +-dt.refactoring { +- font-weight: bold; +-} +- +-dt.request { +- font-weight: bold; +-} +- +-dt.typeDefinition { +- font-weight: bold; +-} +- +-a { +- text-decoration: none; +-} +- +-a:focus, a:hover { +- text-decoration: underline; +-} +- +-.deprecated { +- text-decoration: line-through; +-} +- +-/* Styles for index */ +- +-.subindex ul { +- padding-left: 0; +- margin-left: 0; +- +- -webkit-margin-before: 0; +- -webkit-margin-start: 0; +- -webkit-padding-start: 0; +- +- list-style-type: none; +-} +-''' +- .trim(); +- +-final GeneratedFile target = +- new GeneratedFile('doc/api.html', (String pkgPath) async { +- ToHtmlVisitor visitor = new ToHtmlVisitor(readApi(pkgPath)); +- dom.Document document = new dom.Document(); +- document.append(new dom.DocumentType('html', null, null)); +- for (dom.Node node in visitor.collectHtml(visitor.visitApi)) { +- document.append(node); +- } +- return document.outerHtml; +-}); +- +-String _toTitleCase(String str) { +- if (str.isEmpty) return str; +- return str.substring(0, 1).toUpperCase() + str.substring(1); +-} +- +-/** +- * Visitor that records the mapping from HTML elements to various kinds of API +- * nodes. +- */ +-class ApiMappings extends HierarchicalApiVisitor { +- Map domains = {}; +- +- ApiMappings(Api api) : super(api); +- +- @override +- void visitDomain(Domain domain) { +- domains[domain.html] = domain; +- } +-} +- +-/** +- * Helper methods for creating HTML elements. +- */ +-abstract class HtmlMixin { +- void anchor(String id, void callback()) { +- element('a', {'name': id}, callback); +- } +- +- void b(void callback()) => element('b', {}, callback); +- void body(void callback()) => element('body', {}, callback); +- void box(void callback()) { +- element('div', {'class': 'box'}, callback); +- } +- +- void br() => element('br', {}); +- void dd(void callback()) => element('dd', {}, callback); +- void dl(void callback()) => element('dl', {}, callback); +- void dt(String cls, void callback()) => +- element('dt', {'class': cls}, callback); +- void element(String name, Map attributes, [void callback()]); +- void gray(void callback()) => +- element('span', {'style': 'color:#999999'}, callback); +- void h1(void callback()) => element('h1', {}, callback); +- void h2(String cls, void callback()) { +- if (cls == null) { +- return element('h2', {}, callback); +- } +- return element('h2', {'class': cls}, callback); +- } +- +- void h3(void callback()) => element('h3', {}, callback); +- void h4(void callback()) => element('h4', {}, callback); +- void h5(void callback()) => element('h5', {}, callback); +- void hangingIndent(void callback()) => +- element('div', {'class': 'hangingIndent'}, callback); +- void head(void callback()) => element('head', {}, callback); +- void html(void callback()) => element('html', {}, callback); +- void i(void callback()) => element('i', {}, callback); +- void li(void callback()) => element('li', {}, callback); +- void link(String id, void callback(), [Map attributes]) { +- attributes ??= {}; +- attributes['href'] = '#$id'; +- element('a', attributes, callback); +- } +- +- void p(void callback()) => element('p', {}, callback); +- void pre(void callback()) => element('pre', {}, callback); +- void span(String cls, void callback()) => +- element('span', {'class': cls}, callback); +- void title(void callback()) => element('title', {}, callback); +- void tt(void callback()) => element('tt', {}, callback); +- void ul(void callback()) => element('ul', {}, callback); +-} +- +-/** +- * Visitor that generates HTML documentation of the API. +- */ +-class ToHtmlVisitor extends HierarchicalApiVisitor +- with HtmlMixin, HtmlGenerator { +- /** +- * Set of types defined in the API. +- */ +- Set definedTypes = new Set(); +- +- /** +- * Mappings from HTML elements to API nodes. +- */ +- ApiMappings apiMappings; +- +- ToHtmlVisitor(Api api) +- : apiMappings = new ApiMappings(api), +- super(api) { +- apiMappings.visitApi(); +- } +- +- /** +- * Describe the payload of request, response, notification, refactoring +- * feedback, or refactoring options. +- * +- * If [force] is true, then a section is inserted even if the payload is +- * null. +- */ +- void describePayload(TypeObject subType, String name, {bool force: false}) { +- if (force || subType != null) { +- h4(() { +- write(name); +- }); +- if (subType == null) { +- p(() { +- write('none'); +- }); +- } else { +- visitTypeDecl(subType); +- } +- } +- } +- +- void generateDomainIndex(Domain domain) { +- h4(() { +- write(domain.name); +- write(' ('); +- link('domain_${domain.name}', () => write('\u2191')); +- write(')'); +- }); +- if (domain.requests.length > 0) { +- element('div', {'class': 'subindex'}, () { +- generateRequestsIndex(domain.requests); +- if (domain.notifications.length > 0) { +- generateNotificationsIndex(domain.notifications); +- } +- }); +- } else if (domain.notifications.length > 0) { +- element('div', {'class': 'subindex'}, () { +- generateNotificationsIndex(domain.notifications); +- }); +- } +- } +- +- void generateDomainsHeader() { +- h1(() { +- write('Domains'); +- }); +- } +- +- void generateIndex() { +- h3(() => write('Domains')); +- for (var domain in api.domains) { +- if (domain.experimental || +- (domain.requests.length == 0 && domain.notifications == 0)) { +- continue; +- } +- generateDomainIndex(domain); +- } +- +- generateTypesIndex(definedTypes); +- generateRefactoringsIndex(api.refactorings); +- } +- +- void generateNotificationsIndex(Iterable notifications) { +- h5(() => write("Notifications")); +- element('div', {'class': 'subindex'}, () { +- element('ul', {}, () { +- for (var notification in notifications) { +- element( +- 'li', +- {}, +- () => link('notification_${notification.longEvent}', +- () => write(notification.event))); +- } +- }); +- }); +- } +- +- void generateRefactoringsIndex(Iterable refactorings) { +- if (refactorings == null) { +- return; +- } +- h3(() { +- write("Refactorings"); +- write(' ('); +- link('refactorings', () => write('\u2191')); +- write(')'); +- }); +- // TODO: Individual refactorings are not yet hyperlinked. +- element('div', {'class': 'subindex'}, () { +- element('ul', {}, () { +- for (var refactoring in refactorings) { +- element( +- 'li', +- {}, +- () => link('refactoring_${refactoring.kind}', +- () => write(refactoring.kind))); +- } +- }); +- }); +- } +- +- void generateRequestsIndex(Iterable requests) { +- h5(() => write("Requests")); +- element('ul', {}, () { +- for (var request in requests) { +- if (!request.experimental) { +- element( +- 'li', +- {}, +- () => link('request_${request.longMethod}', +- () => write(request.method))); +- } +- } +- }); +- } +- +- void generateTableOfContents() { +- for (var domain in api.domains.where((domain) => !domain.experimental)) { +- if (domain.experimental) continue; +- +- writeln(); +- +- p(() { +- link('domain_${domain.name}', () { +- write(_toTitleCase(domain.name)); +- }); +- }); +- +- ul(() { +- for (Request request in domain.requests) { +- if (request.experimental) continue; +- +- li(() { +- link('request_${request.longMethod}', () { +- write(request.longMethod); +- }, request.deprecated ? {'class': 'deprecated'} : null); +- }); +- writeln(); +- } +- }); +- +- writeln(); +- } +- } +- +- void generateTypesIndex(Set types) { +- h3(() { +- write("Types"); +- write(' ('); +- link('types', () => write('\u2191')); +- write(')'); +- }); +- List sortedTypes = types.toList(); +- sortedTypes.sort(); +- element('div', {'class': 'subindex'}, () { +- element('ul', {}, () { +- for (var type in sortedTypes) { +- element('li', {}, () => link('type_$type', () => write(type))); +- } +- }); +- }); +- } +- +- void javadocParams(TypeObject typeObject) { +- if (typeObject != null) { +- for (TypeObjectField field in typeObject.fields) { +- hangingIndent(() { +- write('@param ${field.name} '); +- translateHtml(field.html, squashParagraphs: true); +- }); +- } +- } +- } +- +- /** +- * Generate a description of [type] using [TypeVisitor]. +- * +- * If [shortDesc] is non-null, the output is prefixed with this string +- * and a colon. +- * +- * If [typeForBolding] is supplied, then fields in this type are shown in +- * boldface. +- */ +- void showType(String shortDesc, TypeDecl type, [TypeObject typeForBolding]) { +- Set fieldsToBold = new Set(); +- if (typeForBolding != null) { +- for (TypeObjectField field in typeForBolding.fields) { +- fieldsToBold.add(field.name); +- } +- } +- pre(() { +- if (shortDesc != null) { +- write('$shortDesc: '); +- } +- TypeVisitor typeVisitor = +- new TypeVisitor(api, fieldsToBold: fieldsToBold); +- addAll(typeVisitor.collectHtml(() { +- typeVisitor.visitTypeDecl(type); +- })); +- }); +- } +- +- /** +- * Copy the contents of the given HTML element, translating the special +- * elements that define the API appropriately. +- */ +- void translateHtml(dom.Element html, {bool squashParagraphs: false}) { +- for (dom.Node node in html.nodes) { +- if (node is dom.Element) { +- if (squashParagraphs && node.localName == 'p') { +- translateHtml(node, squashParagraphs: squashParagraphs); +- continue; +- } +- switch (node.localName) { +- case 'domains': +- generateDomainsHeader(); +- break; +- case 'domain': +- visitDomain(apiMappings.domains[node]); +- break; +- case 'head': +- head(() { +- translateHtml(node, squashParagraphs: squashParagraphs); +- element('link', { +- 'rel': 'stylesheet', +- 'href': +- 'https://fonts.googleapis.com/css?family=Source+Code+Pro|Roboto:500,400italic,300,400', +- 'type': 'text/css' +- }); +- element('style', {}, () { +- writeln(stylesheet); +- }); +- }); +- break; +- case 'refactorings': +- visitRefactorings(api.refactorings); +- break; +- case 'types': +- visitTypes(api.types); +- break; +- case 'version': +- translateHtml(node, squashParagraphs: squashParagraphs); +- break; +- case 'toc': +- generateTableOfContents(); +- break; +- case 'index': +- generateIndex(); +- break; +- default: +- if (!ApiReader.specialElements.contains(node.localName)) { +- element(node.localName, node.attributes, () { +- translateHtml(node, squashParagraphs: squashParagraphs); +- }); +- } +- } +- } else if (node is dom.Text) { +- String text = node.text; +- write(text); +- } +- } +- } +- +- @override +- void visitApi() { +- Iterable apiTypes = +- api.types.where((TypeDefinition td) => !td.experimental); +- definedTypes = apiTypes.map((TypeDefinition td) => td.name).toSet(); +- +- html(() { +- translateHtml(api.html); +- }); +- } +- +- @override +- void visitDomain(Domain domain) { +- if (domain.experimental) { +- return; +- } +- h2('domain', () { +- anchor('domain_${domain.name}', () { +- write('${domain.name} domain'); +- }); +- }); +- translateHtml(domain.html); +- if (domain.requests.isNotEmpty) { +- h3(() { +- write('Requests'); +- }); +- dl(() { +- domain.requests.forEach(visitRequest); +- }); +- } +- if (domain.notifications.isNotEmpty) { +- h3(() { +- write('Notifications'); +- }); +- dl(() { +- domain.notifications.forEach(visitNotification); +- }); +- } +- } +- +- @override +- void visitNotification(Notification notification) { +- if (notification.experimental) { +- return; +- } +- dt('notification', () { +- anchor('notification_${notification.longEvent}', () { +- write(notification.longEvent); +- }); +- }); +- dd(() { +- box(() { +- showType( +- 'notification', notification.notificationType, notification.params); +- }); +- translateHtml(notification.html); +- describePayload(notification.params, 'parameters:'); +- }); +- } +- +- @override +- visitRefactoring(Refactoring refactoring) { +- dt('refactoring', () { +- write(refactoring.kind); +- }); +- dd(() { +- translateHtml(refactoring.html); +- describePayload(refactoring.feedback, 'Feedback:', force: true); +- describePayload(refactoring.options, 'Options:', force: true); +- }); +- } +- +- @override +- void visitRefactorings(Refactorings refactorings) { +- translateHtml(refactorings.html); +- dl(() { +- super.visitRefactorings(refactorings); +- }); +- } +- +- @override +- void visitRequest(Request request) { +- if (request.experimental) { +- return; +- } +- dt(request.deprecated ? 'request deprecated' : 'request', () { +- anchor('request_${request.longMethod}', () { +- write(request.longMethod); +- }); +- }); +- dd(() { +- box(() { +- showType('request', request.requestType, request.params); +- br(); +- showType('response', request.responseType, request.result); +- }); +- translateHtml(request.html); +- describePayload(request.params, 'parameters:'); +- describePayload(request.result, 'returns:'); +- }); +- } +- +- @override +- void visitTypeDefinition(TypeDefinition typeDefinition) { +- if (typeDefinition.experimental) { +- return; +- } +- dt( +- typeDefinition.deprecated +- ? 'typeDefinition deprecated' +- : 'typeDefinition', () { +- anchor('type_${typeDefinition.name}', () { +- write('${typeDefinition.name}: '); +- TypeVisitor typeVisitor = new TypeVisitor(api, short: true); +- addAll(typeVisitor.collectHtml(() { +- typeVisitor.visitTypeDecl(typeDefinition.type); +- })); +- }); +- }); +- dd(() { +- translateHtml(typeDefinition.html); +- visitTypeDecl(typeDefinition.type); +- }); +- } +- +- @override +- void visitTypeEnum(TypeEnum typeEnum) { +- dl(() { +- super.visitTypeEnum(typeEnum); +- }); +- } +- +- @override +- void visitTypeEnumValue(TypeEnumValue typeEnumValue) { +- bool isDocumented = false; +- for (dom.Node node in typeEnumValue.html.nodes) { +- if ((node is dom.Element && node.localName != 'code') || +- (node is dom.Text && node.text.trim().isNotEmpty)) { +- isDocumented = true; +- break; +- } +- } +- dt(typeEnumValue.deprecated ? 'value deprecated' : 'value', () { +- write(typeEnumValue.value); +- }); +- if (isDocumented) { +- dd(() { +- translateHtml(typeEnumValue.html); +- }); +- } +- } +- +- @override +- void visitTypeList(TypeList typeList) { +- visitTypeDecl(typeList.itemType); +- } +- +- @override +- void visitTypeMap(TypeMap typeMap) { +- visitTypeDecl(typeMap.valueType); +- } +- +- @override +- void visitTypeObject(TypeObject typeObject) { +- dl(() { +- super.visitTypeObject(typeObject); +- }); +- } +- +- @override +- void visitTypeObjectField(TypeObjectField typeObjectField) { +- dt('field', () { +- b(() { +- if (typeObjectField.deprecated) { +- span('deprecated', () { +- write(typeObjectField.name); +- }); +- } else { +- write(typeObjectField.name); +- } +- if (typeObjectField.value != null) { +- write(' = ${JSON.encode(typeObjectField.value)}'); +- } else { +- write(': '); +- TypeVisitor typeVisitor = new TypeVisitor(api, short: true); +- addAll(typeVisitor.collectHtml(() { +- typeVisitor.visitTypeDecl(typeObjectField.type); +- })); +- if (typeObjectField.optional) { +- gray(() => write(' (optional)')); +- } +- } +- }); +- }); +- dd(() { +- translateHtml(typeObjectField.html); +- }); +- } +- +- @override +- void visitTypeReference(TypeReference typeReference) {} +- +- @override +- void visitTypes(Types types) { +- translateHtml(types.html); +- dl(() { +- List sortedTypes = types.toList(); +- sortedTypes.sort((TypeDefinition first, TypeDefinition second) => +- first.name.compareTo(second.name)); +- sortedTypes.forEach(visitTypeDefinition); +- }); +- } +-} +- +-/** +- * Visitor that generates a compact representation of a type, such as: +- * +- * { +- * "id": String +- * "error": optional Error +- * "result": { +- * "version": String +- * } +- * } +- */ +-class TypeVisitor extends HierarchicalApiVisitor +- with HtmlMixin, HtmlCodeGenerator { +- /** +- * Set of fields which should be shown in boldface, or null if no field +- * should be shown in boldface. +- */ +- final Set fieldsToBold; +- +- /** +- * True if a short description should be generated. In a short description, +- * objects are shown as simply "object", and enums are shown as "String". +- */ +- final bool short; +- +- TypeVisitor(Api api, {this.fieldsToBold, this.short: false}) : super(api); +- +- @override +- void visitTypeEnum(TypeEnum typeEnum) { +- if (short) { +- write('String'); +- return; +- } +- writeln('enum {'); +- indent(() { +- for (TypeEnumValue value in typeEnum.values) { +- writeln(value.value); +- } +- }); +- write('}'); +- } +- +- @override +- void visitTypeList(TypeList typeList) { +- write('List<'); +- visitTypeDecl(typeList.itemType); +- write('>'); +- } +- +- @override +- void visitTypeMap(TypeMap typeMap) { +- write('Map<'); +- visitTypeDecl(typeMap.keyType); +- write(', '); +- visitTypeDecl(typeMap.valueType); +- write('>'); +- } +- +- @override +- void visitTypeObject(TypeObject typeObject) { +- if (short) { +- write('object'); +- return; +- } +- writeln('{'); +- indent(() { +- for (TypeObjectField field in typeObject.fields) { +- write('"'); +- if (fieldsToBold != null && fieldsToBold.contains(field.name)) { +- b(() { +- write(field.name); +- }); +- } else { +- write(field.name); +- } +- write('": '); +- if (field.value != null) { +- write(JSON.encode(field.value)); +- } else { +- if (field.optional) { +- gray(() { +- write('optional'); +- }); +- write(' '); +- } +- visitTypeDecl(field.type); +- } +- writeln(); +- } +- }); +- write('}'); +- } +- +- @override +- void visitTypeReference(TypeReference typeReference) { +- String displayName = typeReference.typeName; +- if (api.types.containsKey(typeReference.typeName)) { +- link('type_${typeReference.typeName}', () { +- write(displayName); +- }); +- } else { +- write(displayName); +- } +- } +- +- @override +- void visitTypeUnion(TypeUnion typeUnion) { +- bool verticalBarNeeded = false; +- for (TypeDecl choice in typeUnion.choices) { +- if (verticalBarNeeded) { +- write(' | '); +- } +- visitTypeDecl(choice); +- verticalBarNeeded = true; +- } +- } +-} +diff --git a/pkg/analysis_server_client/CHANGELOG.md b/pkg/analysis_server_client/CHANGELOG.md +deleted file mode 100644 +index 14d2f07d088..00000000000 +--- a/pkg/analysis_server_client/CHANGELOG.md ++++ /dev/null +@@ -1,5 +0,0 @@ +-#1.0.1 +-* Update path on homepage +- +-#1.0.0 +-* Initial version +\ No newline at end of file +diff --git a/pkg/analysis_server_client/LICENSE b/pkg/analysis_server_client/LICENSE +deleted file mode 100644 +index 076334f7ab7..00000000000 +--- a/pkg/analysis_server_client/LICENSE ++++ /dev/null +@@ -1,26 +0,0 @@ +-Copyright 2017, the Dart project authors. All rights reserved. +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions are +-met: +- +- * Redistributions of source code must retain the above copyright +- notice, this list of conditions and the following disclaimer. +- * Redistributions in binary form must reproduce the above +- copyright notice, this list of conditions and the following +- disclaimer in the documentation and/or other materials provided +- with the distribution. +- * Neither the name of Google Inc. nor the names of its +- contributors may be used to endorse or promote products derived +- from this software without specific prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\ No newline at end of file +diff --git a/pkg/analysis_server_client/README.md b/pkg/analysis_server_client/README.md +deleted file mode 100644 +index 3351705598b..00000000000 +--- a/pkg/analysis_server_client/README.md ++++ /dev/null +@@ -1,13 +0,0 @@ +-# Analysis Server Client +- +-A client wrapper over Analysis Server. Instances of this client manages +-connection to Analysis Server and process and faciliates JSON protocol +-communication to and from the server. +- +-Current implementation has no knowledge of the Analysis Server library yet. +-Future updates will allow for full class-access of Analysis Server protocol +-objects. +- +-Analysis Server process must be instantiated separately and loaded into +-Analysis Server Client. To learn how to generate an Analysis Server Process, +-refer to the [Analysis Server page.](https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server) +diff --git a/pkg/analysis_server_client/lib/analysis_server_client.dart b/pkg/analysis_server_client/lib/analysis_server_client.dart +deleted file mode 100644 +index 96286e40dd9..00000000000 +--- a/pkg/analysis_server_client/lib/analysis_server_client.dart ++++ /dev/null +@@ -1,101 +0,0 @@ +-// 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:convert'; +-import 'dart:io'; +- +-/// Type of callbacks used to process notification. +-typedef void NotificationProcessor(String event, Map params); +- +-/// Instances of the class [AnalysisServerClient] manage a connection to an +-/// [AnalysisServer] process, and facilitate communication to and from the +-/// client/user. +-class AnalysisServerClient { +- /// AnalysisServer process object, or null if the server has been shut down. +- final Process _process; +- +- /// Commands that have been sent to the server but not yet acknowledged, +- /// and the [Completer] objects which should be completed when +- /// acknowledgement is received. +- final Map _pendingCommands = {}; +- +- /// Number which should be used to compute the 'id' to send to the next +- /// command sent to the server. +- int _nextId = 0; +- +- AnalysisServerClient(this._process); +- +- /// Return a future that will complete when all commands that have been +- /// sent to the server so far have been flushed to the OS buffer. +- Future flushCommands() { +- return _process.stdin.flush(); +- } +- +- void listenToOutput({NotificationProcessor notificationProcessor}) { +- _process.stdout +- .transform((new Utf8Codec()).decoder) +- .transform(new LineSplitter()) +- .listen((String line) { +- String trimmedLine = line.trim(); +- if (trimmedLine.startsWith('Observatory listening on ')) { +- return; +- } +- final result = JSON.decoder.convert(trimmedLine) as Map; +- if (result.containsKey('id')) { +- final id = result['id'] as String; +- final completer = _pendingCommands.remove(id); +- +- if (result.containsKey('error')) { +- completer.completeError(new ServerErrorMessage(result['error'])); +- } else { +- completer.complete(result['result']); +- } +- } else if (notificationProcessor != null && result.containsKey('event')) { +- // Message is a notification. It should have an event and possibly +- // params. +- notificationProcessor(result['event'], result['params']); +- } +- }); +- } +- +- /// Sends a command to the server. An 'id' will be automatically assigned. +- /// The returned [Future] will be completed when the server acknowledges +- /// the command with a response. If the server acknowledges the command +- /// with a normal (non-error) response, the future will be completed +- /// with the 'result' field from the response. If the server acknowledges +- /// the command with an error response, the future will be completed with an +- /// error. +- Future send(String method, Map params) { +- String id = '${_nextId++}'; +- Map command = { +- 'id': id, +- 'method': method +- }; +- if (params != null) { +- command['params'] = params; +- } +- Completer completer = new Completer(); +- _pendingCommands[id] = completer; +- String commandAsJson = JSON.encode(command); +- _process.stdin.add(UTF8.encoder.convert('$commandAsJson\n')); +- return completer.future; +- } +- +- /// Force kill the server. Returns exit code future. +- Future kill() { +- _process.kill(); +- return _process.exitCode; +- } +-} +- +-class ServerErrorMessage { +- final Map errorJson; +- +- ServerErrorMessage(this.errorJson); +- +- String get code => errorJson['code'].toString(); +- String get message => errorJson['message']; +- String get stackTrace => errorJson['stackTrace']; +-} +diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml +deleted file mode 100644 +index 25ea57e87a0..00000000000 +--- a/pkg/analysis_server_client/pubspec.yaml ++++ /dev/null +@@ -1,13 +0,0 @@ +-name: analysis_server_client +-version: 1.0.1 +-author: Dart Team +-description: +- A client wrapper over analysis_server. Instances of this client +- manage a connection to the analysis_server process and +- facilitates communication to and from the server. +-homepage: http://github.com/dart-lang/sdk/pkg/analysis_server_client +-dev_dependencies: +- test: ">=0.12.0 <0.13.0" +- mockito: ^2.0.2 +-environment: +- sdk: ">=1.0.0 < 2.0.0-dev.infinity" +diff --git a/pkg/analysis_server_client/test/analysis_server_client_test.dart b/pkg/analysis_server_client/test/analysis_server_client_test.dart +deleted file mode 100644 +index 900bd52b0b0..00000000000 +--- a/pkg/analysis_server_client/test/analysis_server_client_test.dart ++++ /dev/null +@@ -1,97 +0,0 @@ +-// 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:convert'; +-import 'dart:io'; +- +-import 'package:analysis_server_client/analysis_server_client.dart'; +-import 'package:mockito/mockito.dart'; +-import 'package:test/test.dart'; +- +-void main() { +- Process _process; +- AnalysisServerClient serverWrapper; +- +- setUp(() async { +- _process = new MockProcess(); +- final _mockStdin = new MockStdin(); +- serverWrapper = new AnalysisServerClient(_process); +- when(_process.stdin).thenReturn(_mockStdin); +- when(_mockStdin.add).thenReturn(null); +- }); +- +- test('test_listenToOutput_good', () async { +- when(_process.stdout).thenReturn(_goodMessage()); +- +- final future = serverWrapper.send('blahMethod', null); +- serverWrapper.listenToOutput(); +- +- final response = await future; +- expect(response, new isInstanceOf()); +- final responseAsMap = response as Map; +- expect(responseAsMap['foo'], 'bar'); +- }); +- +- test('test_listenToOutput_error', () async { +- when(_process.stdout).thenReturn(_badMessage()); +- final future = serverWrapper.send('blahMethod', null); +- future.catchError((e) { +- expect(e, new isInstanceOf()); +- final e2 = e as ServerErrorMessage; +- expect(e2.code, 'someErrorCode'); +- expect(e2.message, 'something went wrong'); +- expect(e2.stackTrace, 'some long stack trace'); +- }); +- serverWrapper.listenToOutput(); +- }); +- +- test('test_listenToOutput_event', () async { +- when(_process.stdout).thenReturn(_eventMessage()); +- +- void eventHandler(String event, Map params) { +- expect(event, 'fooEvent'); +- expect(params.length, 2); +- expect(params['foo'] as String, 'bar'); +- expect(params['baz'] as String, 'bang'); +- } +- +- serverWrapper.send('blahMethod', null); +- serverWrapper.listenToOutput(notificationProcessor: eventHandler); +- }); +-} +- +-Stream> _goodMessage() async* { +- yield UTF8.encoder.convert('Observatory listening on foo bar\n'); +- final sampleJson = { +- 'id': '0', +- 'result': {'foo': 'bar'} +- }; +- yield UTF8.encoder.convert(JSON.encode(sampleJson)); +-} +- +-final _badErrorMessage = { +- 'code': 'someErrorCode', +- 'message': 'something went wrong', +- 'stackTrace': 'some long stack trace' +-}; +- +-Stream> _badMessage() async* { +- yield UTF8.encoder.convert('Observatory listening on foo bar\n'); +- final sampleJson = {'id': '0', 'error': _badErrorMessage}; +- yield UTF8.encoder.convert(JSON.encode(sampleJson)); +-} +- +-Stream> _eventMessage() async* { +- yield UTF8.encoder.convert('Observatory listening on foo bar\n'); +- final sampleJson = { +- 'event': 'fooEvent', +- 'params': {'foo': 'bar', 'baz': 'bang'} +- }; +- yield UTF8.encoder.convert(JSON.encode(sampleJson)); +-} +- +-class MockProcess extends Mock implements Process {} +- +-class MockStdin extends Mock implements List {} +diff --git a/pkg/analyzer/README.md b/pkg/analyzer/README.md +index fe5289fd810..bb8841d809b 100644 +--- a/pkg/analyzer/README.md ++++ b/pkg/analyzer/README.md +@@ -102,7 +102,6 @@ this causes for our clients, but some pain is inevitable. + + See the [LICENSE] file. + +-[serverapi]: https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/master/pkg/analysis_server/doc/api.html + [analyzercli]: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli + [list]: https://groups.google.com/a/dartlang.org/forum/#!forum/analyzer-discuss + [lintrules]: http://dart-lang.github.io/linter/lints/ +@@ -111,4 +110,3 @@ See the [LICENSE] file. + [LICENSE]: https://github.com/dart-lang/sdk/blob/master/pkg/analyzer/LICENSE + [dartfmt]: https://github.com/dart-lang/dart_style + [dartdoc]: https://github.com/dart-lang/dartdoc +-[analysis_sever]: https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server +diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart +index a12ac3541dd..5b01e589c85 100644 +--- a/pkg/analyzer/lib/src/codegen/tools.dart ++++ b/pkg/analyzer/lib/src/codegen/tools.dart +@@ -158,7 +158,6 @@ class CodeGenerator { + * the License. + * + * This file has been automatically generated. Please do not edit it manually. +- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files". + */'''; + } else if (codeGeneratorSettings.languageName == 'python') { + header = ''' +@@ -168,7 +167,6 @@ class CodeGenerator { + # + # This file has been automatically generated. Please do not edit it manually. + # To regenerate the file, use the script +-# "pkg/analysis_server/tool/spec/generate_files". + '''; + } else { + header = ''' +diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart +index cace64a389e..00387e52ace 100644 +--- a/pkg/analyzer_cli/lib/src/driver.dart ++++ b/pkg/analyzer_cli/lib/src/driver.dart +@@ -50,12 +50,8 @@ import 'package:package_config/src/packages_impl.dart' show MapPackages; + import 'package:path/path.dart' as path; + import 'package:plugin/manager.dart'; + import 'package:plugin/plugin.dart'; +-import 'package:telemetry/crash_reporting.dart'; +-import 'package:telemetry/telemetry.dart' as telemetry; + import 'package:yaml/yaml.dart'; + +-const _analyticsID = 'UA-26406144-28'; +- + /// Shared IO sink for standard error reporting. + @visibleForTesting + StringSink errorSink = io.stderr; +@@ -64,30 +60,12 @@ StringSink errorSink = io.stderr; + @visibleForTesting + StringSink outSink = io.stdout; + +-telemetry.Analytics _analytics; +- +-/// The analytics instance for analyzer-cli. +-telemetry.Analytics get analytics => (_analytics ??= +- telemetry.createAnalyticsInstance(_analyticsID, 'analyzer-cli')); +- + /// Test this option map to see if it specifies lint rules. + bool containsLintRuleEntry(Map options) { + var linterNode = options['linter']; + return linterNode is YamlMap && linterNode.containsKey('rules'); + } + +-/// Make sure that we create an analytics instance that doesn't send for this +-/// session. +-void disableAnalyticsForSession() { +- _analytics = telemetry.createAnalyticsInstance(_analyticsID, 'analyzer-cli', +- disableForSession: true); +-} +- +-@visibleForTesting +-void setAnalytics(telemetry.Analytics replacementAnalytics) { +- _analytics = replacementAnalytics; +-} +- + class Driver implements CommandLineStarter { + static final PerformanceTag _analyzeAllTag = + new PerformanceTag("Driver._analyzeAll"); +@@ -130,26 +108,15 @@ class Driver implements CommandLineStarter { + /// Collected analysis statistics. + final AnalysisStats stats = new AnalysisStats(); + +- CrashReportSender _crashReportSender; +- + /// Create a new Driver instance. + /// + /// [isTesting] is true if we're running in a test environment. +- Driver({bool isTesting: false}) { +- if (isTesting) { +- disableAnalyticsForSession(); +- } +- } ++ Driver({bool isTesting: false}) { } + + /// This Driver's current analysis context. + @visibleForTesting + AnalysisContext get context => _context; + +- /// The crash reporting instance for analyzer-cli. +- /// TODO(devoncarew): Replace with the real crash product ID. +- CrashReportSender get crashReportSender => (_crashReportSender ??= +- new CrashReportSender('Dart_analyzer_cli', analytics)); +- + @override + void set userDefinedPlugins(List plugins) { + _userDefinedPlugins = plugins ?? []; +@@ -169,15 +136,6 @@ class Driver implements CommandLineStarter { + // Parse commandline options. + CommandLineOptions options = CommandLineOptions.parse(args); + +- if (options.batchMode || options.buildMode) { +- disableAnalyticsForSession(); +- } +- +- // Ping analytics with our initial call. +- analytics.sendScreenView('home'); +- +- var timer = analytics.startTimer('analyze'); +- + // Do analysis. + if (options.buildMode) { + ErrorSeverity severity = await _buildModeAnalyze(options); +@@ -202,22 +160,11 @@ class Driver implements CommandLineStarter { + if (_context != null) { + _analyzedFileCount += _context.sources.length; + } +- +- // Send how long analysis took. +- timer.finish(); +- +- // Send how many files were analyzed. +- analytics.sendEvent('analyze', 'fileCount', value: _analyzedFileCount); +- + if (options.perfReport != null) { + String json = makePerfReport( + startTime, currentTimeMillis, options, _analyzedFileCount, stats); + new io.File(options.perfReport).writeAsStringSync(json); + } +- +- // Wait a brief time for any analytics calls to finish. +- await analytics.waitForLastPing(timeout: new Duration(milliseconds: 200)); +- analytics.close(); + } + + Future _analyzeAll(CommandLineOptions options) async { +@@ -225,9 +172,6 @@ class Driver implements CommandLineStarter { + try { + return await _analyzeAllImpl(options); + } catch (e, st) { +- // Catch and ignore any exceptions when reporting exceptions (network +- // errors or other). +- crashReportSender.sendReport(e, stackTrace: st).catchError((_) {}); + rethrow; + } finally { + previous.makeCurrent(); +diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart +index 1ab9c6464ba..64bc54386e0 100644 +--- a/pkg/analyzer_cli/lib/src/options.dart ++++ b/pkg/analyzer_cli/lib/src/options.dart +@@ -11,7 +11,6 @@ import 'package:analyzer/src/util/sdk.dart'; + import 'package:analyzer_cli/src/ansi.dart' as ansi; + import 'package:analyzer_cli/src/driver.dart'; + import 'package:args/args.dart'; +-import 'package:telemetry/telemetry.dart' as telemetry; + + const _binaryName = 'dartanalyzer'; + +@@ -366,11 +365,6 @@ class CommandLineOptions { + help: 'Verbose output.', + negatable: false); + +- if (telemetry.SHOW_ANALYTICS_UI) { +- parser.addFlag('analytics', +- help: 'Enable or disable sending analytics information to Google.'); +- } +- + // Build mode options. + if (!hide) { + parser.addSeparator('Build mode flags:'); +@@ -543,27 +537,16 @@ class CommandLineOptions { + + // Help requests. + if (results['help']) { +- _showUsage(parser, analytics, fromHelp: true); ++ _showUsage(parser, fromHelp: true); + exitHandler(0); + return null; // Only reachable in testing. + } + +- // Enable / disable analytics. +- if (telemetry.SHOW_ANALYTICS_UI) { +- if (results.wasParsed('analytics')) { +- analytics.enabled = results['analytics']; +- outSink.writeln( +- telemetry.createAnalyticsStatusMessage(analytics.enabled)); +- exitHandler(0); +- return null; // Only reachable in testing. +- } +- } +- + // Batch mode and input files. + if (results['batch']) { + if (results.rest.isNotEmpty) { + errorSink.writeln('No source files expected in the batch mode.'); +- _showUsage(parser, analytics); ++ _showUsage(parser); + exitHandler(15); + return null; // Only reachable in testing. + } +@@ -571,7 +554,7 @@ class CommandLineOptions { + if (results.rest.isNotEmpty) { + errorSink.writeln( + 'No source files expected in the persistent worker mode.'); +- _showUsage(parser, analytics); ++ _showUsage(parser); + exitHandler(15); + return null; // Only reachable in testing. + } +@@ -581,7 +564,7 @@ class CommandLineOptions { + return null; // Only reachable in testing. + } else { + if (results.rest.isEmpty && !results['build-mode']) { +- _showUsage(parser, analytics, fromHelp: true); ++ _showUsage(parser, fromHelp: true); + exitHandler(15); + return null; // Only reachable in testing. + } +@@ -595,41 +578,15 @@ class CommandLineOptions { + } + } + +- static _showUsage(ArgParser parser, telemetry.Analytics analytics, ++ static _showUsage(ArgParser parser, + {bool fromHelp: false}) { +- void printAnalyticsInfo() { +- if (!telemetry.SHOW_ANALYTICS_UI) { +- return; +- } +- +- if (fromHelp) { +- errorSink.writeln(''); +- errorSink.writeln(telemetry.analyticsNotice); +- } +- +- if (analytics != null) { +- errorSink.writeln(''); +- errorSink.writeln(telemetry.createAnalyticsStatusMessage( +- analytics.enabled, +- command: 'analytics')); +- } +- } + +- errorSink.writeln( ++ errorSink.writeln( + 'Usage: $_binaryName [options...] '); + +- // If it's our first run, we display the analytics info more prominently. +- if (analytics != null && analytics.firstRun) { +- printAnalyticsInfo(); +- } +- + errorSink.writeln(''); + errorSink.writeln(parser.usage); + +- if (analytics != null && !analytics.firstRun) { +- printAnalyticsInfo(); +- } +- + errorSink.writeln(''); + errorSink.writeln(''' + Run "dartanalyzer -h -v" for verbose help output, including less commonly used options. +diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml +index baf4e6f650f..aa0a1c908d9 100644 +--- a/pkg/analyzer_cli/pubspec.yaml ++++ b/pkg/analyzer_cli/pubspec.yaml +@@ -15,7 +15,6 @@ dependencies: + package_config: '>=0.1.5 <2.0.0' + plugin: '>=0.1.0 <0.3.0' + protobuf: ^0.5.0 +- telemetry: ^0.0.1 + yaml: ^2.1.2 + dev_dependencies: + test_reflective_loader: ^0.1.0 +diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart +index acfac627f1f..4af39838e2c 100644 +--- a/pkg/analyzer_cli/test/options_test.dart ++++ b/pkg/analyzer_cli/test/options_test.dart +@@ -8,7 +8,6 @@ import 'dart:io'; + + import 'package:analyzer_cli/src/driver.dart'; + import 'package:analyzer_cli/src/options.dart'; +-import 'package:telemetry/telemetry.dart' as telemetry; + import 'package:test/test.dart'; + import 'package:test_reflective_loader/test_reflective_loader.dart'; + import 'package:usage/usage.dart'; +@@ -229,28 +228,6 @@ main() { + expect(failureMessage, equals('Invalid Dart SDK path: &&&&&')); + }); + +- if (telemetry.SHOW_ANALYTICS_UI) { +- test('--analytics', () { +- AnalyticsMock mock = new AnalyticsMock()..enabled = false; +- setAnalytics(mock); +- CommandLineOptions.parse(['--analytics']); +- expect(mock.enabled, true); +- expect(lastExitHandlerCode, 0); +- expect( +- outStringBuffer.toString(), contains('Analytics are currently')); +- }); +- +- test('--no-analytics', () { +- AnalyticsMock mock = new AnalyticsMock()..enabled = false; +- setAnalytics(mock); +- CommandLineOptions.parse(['--no-analytics']); +- expect(mock.enabled, false); +- expect(lastExitHandlerCode, 0); +- expect( +- outStringBuffer.toString(), contains('Analytics are currently')); +- }); +- } +- + test('preview FE', () { + CommandLineOptions options = + CommandLineOptions.parse(['--preview-dart-2', 'foo.dart']); +diff --git a/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart b/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart +deleted file mode 100644 +index 58bf8dd8cba..00000000000 +--- a/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart ++++ /dev/null +@@ -1,815 +0,0 @@ +-// 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. +-// +-// This file has been automatically generated. Please do not edit it manually. +-// To regenerate the file, use the script +-// "pkg/analysis_server/tool/spec/generate_files". +- +-/** +- * Convenience methods for running integration tests +- */ +-import 'dart:async'; +- +-import 'package:analyzer_plugin/protocol/protocol_generated.dart'; +-import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'; +-import 'package:test/test.dart'; +- +-import 'integration_tests.dart'; +-import 'protocol_matchers.dart'; +-import 'package:analyzer_plugin/protocol/protocol_common.dart'; +- +-/** +- * Convenience methods for running integration tests +- */ +-abstract class IntegrationTestMixin { +- Server get server; +- +- /** +- * Used to request that the plugin perform a version check to confirm that it +- * works with the version of the analysis server that is executing it. +- * +- * Parameters +- * +- * byteStorePath: FilePath +- * +- * The path to the directory containing the on-disk byte store that is to +- * be used by any analysis drivers that are created. +- * +- * sdkPath: FilePath +- * +- * The path to the directory containing the SDK that is to be used by any +- * analysis drivers that are created. +- * +- * version: String +- * +- * The version number of the plugin spec supported by the analysis server +- * that is executing the plugin. +- * +- * Returns +- * +- * isCompatible: bool +- * +- * A flag indicating whether the plugin supports the same version of the +- * plugin spec as the analysis server. If the value is false, then the +- * plugin is expected to shutdown after returning the response. +- * +- * name: String +- * +- * The name of the plugin. This value is only used when the server needs to +- * identify the plugin, either to the user or for debugging purposes. +- * +- * version: String +- * +- * The version of the plugin. This value is only used when the server needs +- * to identify the plugin, either to the user or for debugging purposes. +- * +- * contactInfo: String (optional) +- * +- * Information that the user can use to use to contact the maintainers of +- * the plugin when there is a problem. +- * +- * interestingFiles: List +- * +- * The glob patterns of the files for which the plugin will provide +- * information. This value is ignored if the isCompatible field is false. +- * Otherwise, it will be used to identify the files for which the plugin +- * should be notified of changes. +- */ +- Future sendPluginVersionCheck( +- String byteStorePath, String sdkPath, String version) async { +- var params = +- new PluginVersionCheckParams(byteStorePath, sdkPath, version).toJson(); +- var result = await server.send("plugin.versionCheck", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new PluginVersionCheckResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Used to request that the plugin exit. The server will not send any other +- * requests after this request. The plugin should not send any responses or +- * notifications after sending the response to this request. +- */ +- Future sendPluginShutdown() async { +- var result = await server.send("plugin.shutdown", null); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Used to report that an unexpected error has occurred while executing the +- * plugin. This notification is not used for problems with specific requests +- * (which should be returned as part of the response) but is used for +- * exceptions that occur while performing other tasks, such as analysis or +- * preparing notifications. +- * +- * Parameters +- * +- * isFatal: bool +- * +- * A flag indicating whether the error is a fatal error, meaning that the +- * plugin will shutdown automatically after sending this notification. If +- * true, the server will not expect any other responses or notifications +- * from the plugin. +- * +- * message: String +- * +- * The error message indicating what kind of error was encountered. +- * +- * stackTrace: String +- * +- * The stack trace associated with the generation of the error, used for +- * debugging the plugin. +- */ +- Stream onPluginError; +- +- /** +- * Stream controller for [onPluginError]. +- */ +- StreamController _onPluginError; +- +- /** +- * Return the navigation information associated with the given region of the +- * given file. If the navigation information for the given file has not yet +- * been computed, or the most recently computed navigation information for +- * the given file is out of date, then the response for this request will be +- * delayed until it has been computed. If the content of the file changes +- * after this request was received but before a response could be sent, then +- * an error of type CONTENT_MODIFIED will be generated. +- * +- * If a navigation region overlaps (but extends either before or after) the +- * given region of the file it will be included in the result. This means +- * that it is theoretically possible to get the same navigation region in +- * response to multiple requests. Clients can avoid this by always choosing a +- * region that starts at the beginning of a line and ends at the end of a +- * (possibly different) line in the file. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which navigation information is being requested. +- * +- * offset: int +- * +- * The offset of the region for which navigation information is being +- * requested. +- * +- * length: int +- * +- * The length of the region for which navigation information is being +- * requested. +- * +- * Returns +- * +- * files: List +- * +- * A list of the paths of files that are referenced by the navigation +- * targets. +- * +- * targets: List +- * +- * A list of the navigation targets that are referenced by the navigation +- * regions. +- * +- * regions: List +- * +- * A list of the navigation regions within the requested region of the +- * file. +- */ +- Future sendAnalysisGetNavigation( +- String file, int offset, int length) async { +- var params = new AnalysisGetNavigationParams(file, offset, length).toJson(); +- var result = await server.send("analysis.getNavigation", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new AnalysisGetNavigationResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Used to inform the plugin of changes to files in the file system. Only +- * events associated with files that match the interestingFiles glob patterns +- * will be forwarded to the plugin. +- * +- * Parameters +- * +- * events: List +- * +- * The watch events that the plugin should handle. +- */ +- Future sendAnalysisHandleWatchEvents(List events) async { +- var params = new AnalysisHandleWatchEventsParams(events).toJson(); +- var result = await server.send("analysis.handleWatchEvents", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Set the list of context roots that should be analyzed. +- * +- * Parameters +- * +- * roots: List +- * +- * A list of the context roots that should be analyzed. +- */ +- Future sendAnalysisSetContextRoots(List roots) async { +- var params = new AnalysisSetContextRootsParams(roots).toJson(); +- var result = await server.send("analysis.setContextRoots", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Used to set the priority files to the files in the given list. A priority +- * file is a file that should be given priority when scheduling which +- * analysis work to do first. The list typically contains those files that +- * are visible to the user and those for which analysis results will have the +- * biggest impact on the user experience. The order of the files within the +- * list is significant: the first file will be given higher priority than the +- * second, the second higher priority than the third, and so on. +- * +- * Parameters +- * +- * files: List +- * +- * The files that are to be a priority for analysis. +- */ +- Future sendAnalysisSetPriorityFiles(List files) async { +- var params = new AnalysisSetPriorityFilesParams(files).toJson(); +- var result = await server.send("analysis.setPriorityFiles", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Used to subscribe for services that are specific to individual files. All +- * previous subscriptions should be replaced by the current set of +- * subscriptions. If a given service is not included as a key in the map then +- * no files should be subscribed to the service, exactly as if the service +- * had been included in the map with an explicit empty list of files. +- * +- * Parameters +- * +- * subscriptions: Map> +- * +- * A table mapping services to a list of the files being subscribed to the +- * service. +- */ +- Future sendAnalysisSetSubscriptions( +- Map> subscriptions) async { +- var params = new AnalysisSetSubscriptionsParams(subscriptions).toJson(); +- var result = await server.send("analysis.setSubscriptions", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Used to update the content of one or more files. Files that were +- * previously updated but not included in this update remain unchanged. This +- * effectively represents an overlay of the filesystem. The files whose +- * content is overridden are therefore seen by the plugin as being files with +- * the given content, even if the files do not exist on the filesystem or if +- * the file path represents the path to a directory on the filesystem. +- * +- * Parameters +- * +- * files: Map +- * +- * A table mapping the files whose content has changed to a description of +- * the content change. +- */ +- Future sendAnalysisUpdateContent(Map files) async { +- var params = new AnalysisUpdateContentParams(files).toJson(); +- var result = await server.send("analysis.updateContent", params); +- outOfTestExpect(result, isNull); +- return null; +- } +- +- /** +- * Used to report the errors associated with a given file. The set of errors +- * included in the notification is always a complete list that supersedes any +- * previously reported errors. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the errors. +- * +- * errors: List +- * +- * The errors contained in the file. +- */ +- Stream onAnalysisErrors; +- +- /** +- * Stream controller for [onAnalysisErrors]. +- */ +- StreamController _onAnalysisErrors; +- +- /** +- * Used to report the folding regions associated with a given file. Folding +- * regions can be nested, but cannot be overlapping. Nesting occurs when a +- * foldable element, such as a method, is nested inside another foldable +- * element such as a class. +- * +- * Folding regions that overlap a folding region computed by the server, or +- * by one of the other plugins that are currently running, might be dropped +- * by the server in order to present a consistent view to the client. +- * +- * This notification should only be sent if the server has subscribed to it +- * by including the value "FOLDING" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the folding regions. +- * +- * regions: List +- * +- * The folding regions contained in the file. +- */ +- Stream onAnalysisFolding; +- +- /** +- * Stream controller for [onAnalysisFolding]. +- */ +- StreamController _onAnalysisFolding; +- +- /** +- * Used to report the highlight regions associated with a given file. Each +- * highlight region represents a particular syntactic or semantic meaning +- * associated with some range. Note that the highlight regions that are +- * returned can overlap other highlight regions if there is more than one +- * meaning associated with a particular region. +- * +- * This notification should only be sent if the server has subscribed to it +- * by including the value "HIGHLIGHTS" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the highlight regions. +- * +- * regions: List +- * +- * The highlight regions contained in the file. +- */ +- Stream onAnalysisHighlights; +- +- /** +- * Stream controller for [onAnalysisHighlights]. +- */ +- StreamController _onAnalysisHighlights; +- +- /** +- * Used to report the navigation regions associated with a given file. Each +- * navigation region represents a list of targets associated with some range. +- * The lists will usually contain a single target, but can contain more in +- * the case of a part that is included in multiple libraries or in Dart code +- * that is compiled against multiple versions of a package. Note that the +- * navigation regions that are returned should not overlap other navigation +- * regions. +- * +- * Navigation regions that overlap a navigation region computed by the +- * server, or by one of the other plugins that are currently running, might +- * be dropped or modified by the server in order to present a consistent view +- * to the client. +- * +- * This notification should only be sent if the server has subscribed to it +- * by including the value "NAVIGATION" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the navigation regions. +- * +- * regions: List +- * +- * The navigation regions contained in the file. +- * +- * targets: List +- * +- * The navigation targets referenced in the file. They are referenced by +- * NavigationRegions by their index in this array. +- * +- * files: List +- * +- * The files containing navigation targets referenced in the file. They are +- * referenced by NavigationTargets by their index in this array. +- */ +- Stream onAnalysisNavigation; +- +- /** +- * Stream controller for [onAnalysisNavigation]. +- */ +- StreamController _onAnalysisNavigation; +- +- /** +- * Used to report the occurrences of references to elements within a single +- * file. None of the occurrence regions should overlap. +- * +- * Occurrence regions that overlap an occurrence region computed by the +- * server, or by one of the other plugins that are currently running, might +- * be dropped or modified by the server in order to present a consistent view +- * to the client. +- * +- * This notification should only be sent if the server has subscribed to it +- * by including the value "OCCURRENCES" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file in which the references occur. +- * +- * occurrences: List +- * +- * The occurrences of references to elements within the file. +- */ +- Stream onAnalysisOccurrences; +- +- /** +- * Stream controller for [onAnalysisOccurrences]. +- */ +- StreamController _onAnalysisOccurrences; +- +- /** +- * Used to report the outline fragments associated with a single file. +- * +- * The outline fragments will be merged with any outline produced by the +- * server and with any fragments produced by other plugins. If the server +- * cannot create a coherent outline, some fragments might be dropped. +- * +- * This notification should only be sent if the server has subscribed to it +- * by including the value "OUTLINE" in the list of services passed in an +- * analysis.setSubscriptions request. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file with which the outline is associated. +- * +- * outline: List +- * +- * The outline fragments associated with the file. +- */ +- Stream onAnalysisOutline; +- +- /** +- * Stream controller for [onAnalysisOutline]. +- */ +- StreamController _onAnalysisOutline; +- +- /** +- * Used to request that completion suggestions for the given offset in the +- * given file be returned. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the point at which suggestions are to be made. +- * +- * offset: int +- * +- * The offset within the file at which suggestions are to be made. +- * +- * Returns +- * +- * replacementOffset: int +- * +- * The offset of the start of the text to be replaced. This will be +- * different than the offset used to request the completion suggestions if +- * there was a portion of an identifier before the original offset. In +- * particular, the replacementOffset will be the offset of the beginning of +- * said identifier. +- * +- * replacementLength: int +- * +- * The length of the text to be replaced if the remainder of the identifier +- * containing the cursor is to be replaced when the suggestion is applied +- * (that is, the number of characters in the existing identifier). +- * +- * results: List +- * +- * The completion suggestions being reported. The notification contains all +- * possible completions at the requested cursor position, even those that +- * do not match the characters the user has already typed. This allows the +- * client to respond to further keystrokes from the user without having to +- * make additional requests. +- */ +- Future sendCompletionGetSuggestions( +- String file, int offset) async { +- var params = new CompletionGetSuggestionsParams(file, offset).toJson(); +- var result = await server.send("completion.getSuggestions", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new CompletionGetSuggestionsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Used to request the set of assists that are available at the given +- * location. An assist is distinguished from a refactoring primarily by the +- * fact that it affects a single file and does not require user input in +- * order to be performed. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code for which assists are being requested. +- * +- * offset: int +- * +- * The offset of the code for which assists are being requested. +- * +- * length: int +- * +- * The length of the code for which assists are being requested. +- * +- * Returns +- * +- * assists: List +- * +- * The assists that are available at the given location. +- */ +- Future sendEditGetAssists( +- String file, int offset, int length) async { +- var params = new EditGetAssistsParams(file, offset, length).toJson(); +- var result = await server.send("edit.getAssists", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetAssistsResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Used to request a list of the kinds of refactorings that are valid for the +- * given selection in the given file. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code on which the refactoring would be based. +- * +- * offset: int +- * +- * The offset of the code on which the refactoring would be based. +- * +- * length: int +- * +- * The length of the code on which the refactoring would be based. +- * +- * Returns +- * +- * kinds: List +- * +- * The kinds of refactorings that are valid for the given selection. +- * +- * The list of refactoring kinds is currently limited to those defined by +- * the server API, preventing plugins from adding their own refactorings. +- * However, plugins can support pre-defined refactorings, such as a rename +- * refactoring, at locations not supported by server. +- */ +- Future sendEditGetAvailableRefactorings( +- String file, int offset, int length) async { +- var params = +- new EditGetAvailableRefactoringsParams(file, offset, length).toJson(); +- var result = await server.send("edit.getAvailableRefactorings", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetAvailableRefactoringsResult.fromJson( +- decoder, 'result', result); +- } +- +- /** +- * Used to request the set of fixes that are available for the errors at a +- * given offset in a given file. +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the errors for which fixes are being requested. +- * +- * offset: int +- * +- * The offset used to select the errors for which fixes will be returned. +- * +- * Returns +- * +- * fixes: List +- * +- * The fixes that are available for the errors at the given offset. +- */ +- Future sendEditGetFixes(String file, int offset) async { +- var params = new EditGetFixesParams(file, offset).toJson(); +- var result = await server.send("edit.getFixes", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new EditGetFixesResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Used to request the changes required to perform a refactoring. +- * +- * Parameters +- * +- * kind: RefactoringKind +- * +- * The kind of refactoring to be performed. +- * +- * file: FilePath +- * +- * The file containing the code involved in the refactoring. +- * +- * offset: int +- * +- * The offset of the region involved in the refactoring. +- * +- * length: int +- * +- * The length of the region involved in the refactoring. +- * +- * validateOnly: bool +- * +- * True if the client is only requesting that the values of the options be +- * validated and no change be generated. +- * +- * options: RefactoringOptions (optional) +- * +- * Data used to provide values provided by the user. The structure of the +- * data is dependent on the kind of refactoring being performed. The data +- * that is expected is documented in the section titled Refactorings, +- * labeled as "Options". This field can be omitted if the refactoring does +- * not require any options or if the values of those options are not known. +- * +- * Returns +- * +- * initialProblems: List +- * +- * The initial status of the refactoring, that is, problems related to the +- * context in which the refactoring is requested. The list should be empty +- * if there are no known problems. +- * +- * optionsProblems: List +- * +- * The options validation status, that is, problems in the given options, +- * such as light-weight validation of a new name, flags compatibility, etc. +- * The list should be empty if there are no known problems. +- * +- * finalProblems: List +- * +- * The final status of the refactoring, that is, problems identified in the +- * result of a full, potentially expensive validation and / or change +- * creation. The list should be empty if there are no known problems. +- * +- * feedback: RefactoringFeedback (optional) +- * +- * Data used to provide feedback to the user. The structure of the data is +- * dependent on the kind of refactoring being created. The data that is +- * returned is documented in the section titled Refactorings, labeled as +- * "Feedback". +- * +- * change: SourceChange (optional) +- * +- * The changes that are to be applied to affect the refactoring. This field +- * can be omitted if there are problems that prevent a set of changes from +- * being computed, such as having no options specified for a refactoring +- * that requires them, or if only validation was requested. +- * +- * potentialEdits: List (optional) +- * +- * The ids of source edits that are not known to be valid. An edit is not +- * known to be valid if there was insufficient type information for the +- * plugin to be able to determine whether or not the code needs to be +- * modified, such as when a member is being renamed and there is a +- * reference to a member from an unknown type. This field can be omitted if +- * the change field is omitted or if there are no potential edits for the +- * refactoring. +- */ +- Future sendEditGetRefactoring(RefactoringKind kind, +- String file, int offset, int length, bool validateOnly, +- {RefactoringOptions options}) async { +- var params = new EditGetRefactoringParams( +- kind, file, offset, length, validateOnly, +- options: options) +- .toJson(); +- var result = await server.send("edit.getRefactoring", params); +- ResponseDecoder decoder = new ResponseDecoder(kind); +- return new EditGetRefactoringResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Return the list of KytheEntry objects for some file, given the current +- * state of the file system populated by "analysis.updateContent". +- * +- * Parameters +- * +- * file: FilePath +- * +- * The file containing the code for which the Kythe Entry objects are being +- * requested. +- * +- * Returns +- * +- * entries: List +- * +- * The list of KytheEntry objects for the queried file. +- * +- * files: List +- * +- * The set of files paths that were required, but not in the file system, +- * to give a complete and accurate Kythe graph for the file. This could be +- * due to a referenced file that does not exist or generated files not +- * being generated or passed before the call to "getKytheEntries". +- */ +- Future sendKytheGetKytheEntries( +- String file) async { +- var params = new KytheGetKytheEntriesParams(file).toJson(); +- var result = await server.send("kythe.getKytheEntries", params); +- ResponseDecoder decoder = new ResponseDecoder(null); +- return new KytheGetKytheEntriesResult.fromJson(decoder, 'result', result); +- } +- +- /** +- * Initialize the fields in InttestMixin, and ensure that notifications will +- * be handled. +- */ +- void initializeInttestMixin() { +- _onPluginError = new StreamController(sync: true); +- onPluginError = _onPluginError.stream.asBroadcastStream(); +- _onAnalysisErrors = new StreamController(sync: true); +- onAnalysisErrors = _onAnalysisErrors.stream.asBroadcastStream(); +- _onAnalysisFolding = +- new StreamController(sync: true); +- onAnalysisFolding = _onAnalysisFolding.stream.asBroadcastStream(); +- _onAnalysisHighlights = +- new StreamController(sync: true); +- onAnalysisHighlights = _onAnalysisHighlights.stream.asBroadcastStream(); +- _onAnalysisNavigation = +- new StreamController(sync: true); +- onAnalysisNavigation = _onAnalysisNavigation.stream.asBroadcastStream(); +- _onAnalysisOccurrences = +- new StreamController(sync: true); +- onAnalysisOccurrences = _onAnalysisOccurrences.stream.asBroadcastStream(); +- _onAnalysisOutline = +- new StreamController(sync: true); +- onAnalysisOutline = _onAnalysisOutline.stream.asBroadcastStream(); +- } +- +- /** +- * Dispatch the notification named [event], and containing parameters +- * [params], to the appropriate stream. +- */ +- void dispatchNotification(String event, params) { +- ResponseDecoder decoder = new ResponseDecoder(null); +- switch (event) { +- case "plugin.error": +- outOfTestExpect(params, isPluginErrorParams); +- _onPluginError +- .add(new PluginErrorParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.errors": +- outOfTestExpect(params, isAnalysisErrorsParams); +- _onAnalysisErrors +- .add(new AnalysisErrorsParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.folding": +- outOfTestExpect(params, isAnalysisFoldingParams); +- _onAnalysisFolding +- .add(new AnalysisFoldingParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.highlights": +- outOfTestExpect(params, isAnalysisHighlightsParams); +- _onAnalysisHighlights.add( +- new AnalysisHighlightsParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.navigation": +- outOfTestExpect(params, isAnalysisNavigationParams); +- _onAnalysisNavigation.add( +- new AnalysisNavigationParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.occurrences": +- outOfTestExpect(params, isAnalysisOccurrencesParams); +- _onAnalysisOccurrences.add( +- new AnalysisOccurrencesParams.fromJson(decoder, 'params', params)); +- break; +- case "analysis.outline": +- outOfTestExpect(params, isAnalysisOutlineParams); +- _onAnalysisOutline +- .add(new AnalysisOutlineParams.fromJson(decoder, 'params', params)); +- break; +- default: +- fail('Unexpected notification: $event'); +- break; +- } +- } +-} +diff --git a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart +index 3f6a1c34839..ff96e461528 100644 +--- a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart ++++ b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart +@@ -492,21 +492,6 @@ class Server { + } + } + +- /** +- * Find the root directory of the analysis_server package by proceeding +- * upward to the 'test' dir, and then going up one more directory. +- */ +- String findRoot(String pathname) { +- while (!['benchmark', 'test'].contains(basename(pathname))) { +- String parent = dirname(pathname); +- if (parent.length >= pathname.length) { +- throw new Exception("Can't find root directory"); +- } +- pathname = parent; +- } +- return dirname(pathname); +- } +- + /** + * Return a future that will complete when all commands that have been sent + * to the server so far have been flushed to the OS buffer. +diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json +index 3272f0d8370..648178c597e 100644 +--- a/pkg/front_end/testing.json ++++ b/pkg/front_end/testing.json +@@ -246,7 +246,6 @@ + }, + + "exclude": [ +- "^pkg/analysis_server/lib/src/analysis_server\\.dart", + "^pkg/dev_compiler/" + ] + } +diff --git a/pkg/microlytics/example/simple.dart b/pkg/microlytics/example/simple.dart +deleted file mode 100644 +index 42b323e2114..00000000000 +--- a/pkg/microlytics/example/simple.dart ++++ /dev/null +@@ -1,26 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-import 'package:microlytics/channels.dart'; +-import 'package:microlytics/io_channels.dart'; +-import 'package:microlytics/microlytics.dart'; +- +-void main(List arguments) { +- // Create the channel that will be used to communicate to analytics. +- var channel = new RateLimitingBufferedChannel(new HttpClientChannel(), +- packetsPerSecond: 1.0); +- +- if (arguments.length != 1) { +- print("usage: dart simple.dart GA-Client-ID"); +- return; +- } +- final String clientID = arguments.single; +- +- // Create the logger. +- var lg = new AnalyticsLogger(channel, "555", clientID, "test", "1.2"); +- +- // Send some messages. +- lg.logAnonymousEvent("hello", "world"); +- lg.logAnonymousTiming("loader", "var", 42); +-} +diff --git a/pkg/microlytics/lib/channels.dart b/pkg/microlytics/lib/channels.dart +deleted file mode 100644 +index 18f233c19f9..00000000000 +--- a/pkg/microlytics/lib/channels.dart ++++ /dev/null +@@ -1,53 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library microlytics.channels; +- +-import 'dart:async'; +- +-const String ANALYTICS_URL = "https://ssl.google-analytics.com/collect"; +- +-abstract class Channel { +- void sendData(String data); +- void shutdown() {} +-} +- +-/// [Channel] that implements a leaky bucket +-/// algorithm to provide rate limiting. +-/// See [http://en.wikipedia.org/wiki/Leaky_bucket]. +-class RateLimitingBufferedChannel extends Channel { +- final List _buffer = []; +- final Channel _innerChannel; +- final int _bufferSizeLimit; +- Timer _timer; +- +- RateLimitingBufferedChannel(this._innerChannel, +- {int bufferSizeLimit: 10, double packetsPerSecond: 1.0}) +- : this._bufferSizeLimit = bufferSizeLimit { +- if (!(packetsPerSecond > 0)) { +- throw new ArgumentError("packetsPerSecond must be larger than zero."); +- } +- +- int transmitDelay = (1000 / packetsPerSecond).floor(); +- _timer = new Timer.periodic( +- new Duration(milliseconds: transmitDelay), _onTimerTick); +- } +- +- void _onTimerTick(_) { +- if (_buffer.length > 0) { +- String item = _buffer.removeLast(); +- _innerChannel.sendData(item); +- } +- } +- +- void sendData(String data) { +- if (_buffer.length >= _bufferSizeLimit) return; +- _buffer.add(data); +- } +- +- void shutdown() { +- _timer.cancel(); +- _innerChannel.shutdown(); +- } +-} +diff --git a/pkg/microlytics/lib/html_channels.dart b/pkg/microlytics/lib/html_channels.dart +deleted file mode 100644 +index b3eef43bbac..00000000000 +--- a/pkg/microlytics/lib/html_channels.dart ++++ /dev/null +@@ -1,14 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library microlytics.html_channels; +- +-import 'dart:html'; +-import 'channels.dart'; +- +-class HttpRequestChannel extends Channel { +- void sendData(String data) { +- HttpRequest.request(ANALYTICS_URL, method: "POST", sendData: data); +- } +-} +diff --git a/pkg/microlytics/lib/io_channels.dart b/pkg/microlytics/lib/io_channels.dart +deleted file mode 100644 +index 044005cef8a..00000000000 +--- a/pkg/microlytics/lib/io_channels.dart ++++ /dev/null +@@ -1,20 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library microlytics.io_channels; +- +-import 'dart:io'; +-import 'channels.dart'; +- +-class HttpClientChannel extends Channel { +- void sendData(String data) { +- HttpClient client = new HttpClient(); +- client.postUrl(Uri.parse(ANALYTICS_URL)).then((HttpClientRequest req) { +- req.write(data); +- return req.close(); +- }).then((HttpClientResponse response) { +- response.drain(); +- }); +- } +-} +diff --git a/pkg/microlytics/lib/microlytics.dart b/pkg/microlytics/lib/microlytics.dart +deleted file mode 100644 +index 509ae26dea7..00000000000 +--- a/pkg/microlytics/lib/microlytics.dart ++++ /dev/null +@@ -1,57 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library microlytics; +- +-import 'channels.dart'; +- +-/// Very limited implementation of an API to report usage to Google Analytics. +-/// No Personally Identifiable Information must ever be passed to this class. +-class AnalyticsLogger { +- final Channel _channel; +- final String _clientID; +- final String _analyticsID; +- final String _appName; +- final String _appVersion; +- final String _messagePrefix; //Computed prefix for analytics messages +- +- /// Create a new logger +- /// [channel] represents how this is going to be sent, this would typically +- /// be a [RateLimitingBufferedChannel] wrapping either a [HttpRequestChannel] +- /// or a [HttpClientChannel]. +- /// [clientID] is a version 4 UUID associated with the site or app. +- /// [appName] is an application name. +- /// [appVersion] is a verion string. +- AnalyticsLogger(Channel channel, String clientID, String analyticsID, +- String appName, String appVersion) +- : this._channel = channel, +- this._clientID = clientID, +- this._analyticsID = analyticsID, +- this._appName = appName, +- this._appVersion = appVersion, +- this._messagePrefix = "v=1" +- "&tid=$analyticsID" +- "&cid=$clientID" +- "&an=$appName" +- "&av=$appVersion"; +- +- void logAnonymousTiming(String category, String variable, int ms) { +- category = Uri.encodeComponent(category); +- variable = Uri.encodeComponent(variable); +- _channel.sendData("${this._messagePrefix}" +- "&t=timing" +- "&utc=$category" +- "&utv=$variable" +- "&utt=$ms"); +- } +- +- void logAnonymousEvent(String category, String event) { +- category = Uri.encodeComponent(category); +- event = Uri.encodeComponent(event); +- _channel.sendData("${this._messagePrefix}" +- "&t=event" +- "&ec=$category" +- "&ea=$event"); +- } +-} +diff --git a/pkg/microlytics/pubspec.yaml b/pkg/microlytics/pubspec.yaml +deleted file mode 100644 +index 620b7cb6f83..00000000000 +--- a/pkg/microlytics/pubspec.yaml ++++ /dev/null +@@ -1,8 +0,0 @@ +-# Copyright (c) 2014, 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. +- +-name: microlytics +-description: A minimal implementation of the Analytics API in pure Dart +-dev_dependencies: +- unittest: any +diff --git a/pkg/microlytics/test/dart_microlytics_test.dart b/pkg/microlytics/test/dart_microlytics_test.dart +deleted file mode 100644 +index ca76b7592f6..00000000000 +--- a/pkg/microlytics/test/dart_microlytics_test.dart ++++ /dev/null +@@ -1,114 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library microlytics.test; +- +-import 'package:expect/expect.dart'; +-import 'package:microlytics/microlytics.dart'; +- +-import 'test_channel.dart'; +- +-void main() { +- testBasicEventRead(); +- testBasicNegativeEventRead(); +- testBasicTimingRead(); +- testBasicTimingMultiread(); +-} +- +-void testBasicEventRead() { +- TestChannel c = new TestChannel(); +- AnalyticsLogger logger = new AnalyticsLogger( +- c, +- "2cfac780-31e2-11e4-8c21-0800200c9a66", +- "UA-53895644-1", +- "TestApp", +- "0.42"); +- logger.logAnonymousEvent("video", "play"); +- Expect.isTrue(c.contains("v=1" +- "&tid=UA-53895644-1" +- "&cid=2cfac780-31e2-11e4-8c21-0800200c9a66" +- "&an=TestApp" +- "&av=0.42" +- "&t=event" +- "&ec=video" +- "&ea=play")); +-} +- +-void testBasicNegativeEventRead() { +- TestChannel c = new TestChannel(); +- AnalyticsLogger logger = new AnalyticsLogger( +- c, +- "2cfac780-31e2-11e4-8c21-0800200c9a66", +- "UA-53895644-1", +- "TestApp", +- "0.42"); +- logger.logAnonymousEvent("video", "play"); +- Expect.isFalse(c.contains("v=1" +- "&tid=UA-53895644-1" +- "&cid=2cfac780-31e2-11e4-8c21-0800200c9a66" +- "&an=TestApp" +- "&av=XXX" +- "&t=event" +- "&ec=video" +- "&ea=play")); +-} +- +-void testBasicTimingRead() { +- TestChannel c = new TestChannel(); +- AnalyticsLogger logger = new AnalyticsLogger( +- c, +- "2cfac780-31e2-11e4-8c21-0800200c9a66", +- "UA-53895644-1", +- "TestApp", +- "0.42"); +- logger.logAnonymousTiming("video", "delay", 157); +- Expect.isTrue(c.contains("v=1" +- "&tid=UA-53895644-1" +- "&cid=2cfac780-31e2-11e4-8c21-0800200c9a66" +- "&an=TestApp" +- "&av=0.42" +- "&t=timing" +- "&utc=video" +- "&utv=delay" +- "&utt=157")); +-} +- +-void testBasicTimingMultiread() { +- TestChannel c = new TestChannel(); +- AnalyticsLogger logger = new AnalyticsLogger( +- c, +- "2cfac780-31e2-11e4-8c21-0800200c9a66", +- "UA-53895644-1", +- "TestApp", +- "0.42"); +- logger.logAnonymousTiming("video", "delay", 159); +- logger.logAnonymousTiming("video", "delay", 152); +- Expect.isTrue(c.contains("v=1" +- "&tid=UA-53895644-1" +- "&cid=2cfac780-31e2-11e4-8c21-0800200c9a66" +- "&an=TestApp" +- "&av=0.42" +- "&t=timing" +- "&utc=video" +- "&utv=delay" +- "&utt=152")); +- Expect.isTrue(c.contains("v=1" +- "&tid=UA-53895644-1" +- "&cid=2cfac780-31e2-11e4-8c21-0800200c9a66" +- "&an=TestApp" +- "&av=0.42" +- "&t=timing" +- "&utc=video" +- "&utv=delay" +- "&utt=159")); +- Expect.isFalse(c.contains("v=1" +- "&tid=UA-53895644-1" +- "&cid=2cfac780-31e2-11e4-8c21-0800200c9a66" +- "&an=TestApp" +- "&av=0.42" +- "&t=timing" +- "&utc=video" +- "&utv=delay" +- "&utt=19")); +-} +diff --git a/pkg/microlytics/test/test_channel.dart b/pkg/microlytics/test/test_channel.dart +deleted file mode 100644 +index a7f9c8bd8b1..00000000000 +--- a/pkg/microlytics/test/test_channel.dart ++++ /dev/null +@@ -1,19 +0,0 @@ +-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +-// for details. All rights reserved. Use of this source code is governed by a +-// BSD-style license that can be found in the LICENSE file. +- +-library microlytics.test_channel; +- +-import 'package:microlytics/channels.dart'; +- +-class TestChannel extends Channel { +- List _channelLog = []; +- +- void sendData(String data) { +- _channelLog.add(data); +- } +- +- bool contains(String data) { +- return _channelLog.contains(data); +- } +-} +diff --git a/pkg/pkg.status b/pkg/pkg.status +index 4c454cfe5e4..f75e2ed9216 100644 +--- a/pkg/pkg.status ++++ b/pkg/pkg.status +@@ -11,7 +11,6 @@ + */*/*/*/packages/*/*: Skip + */*/*/*/*/packages/*/*: Skip + +-analysis_server/tool/spec/check_all_test: Skip # Issue 29133 + analyzer_plugin/tool/spec/check_all_test: Skip # Issue 29133 + + analyzer/test/generated/compile_time_error_code_driver_test: Slow, Pass +@@ -90,13 +89,7 @@ mutation_observer: Skip # Issue 21149 + unittest/*: Skip # Issue 21949 + front_end/*: SkipByDesign + +-[ $runtime == vm && $mode == debug ] +-analysis_server/test/completion_test: Pass, Slow +- + [ $runtime == vm && $checked ] +-analysis_server/test/completion_test: Pass, Slow +-analysis_server/test/services/correction/fix_test: Pass, Slow +-analysis_server/test/socket_server_test: Skip # Pass, Slow + analyzer/test/generated/non_error_resolver_kernel_test: Skip # Timing out even with Pass, Slow: Issue 30796 + analyzer/test/src/summary/resynthesize_ast_test: Pass, Slow + analyzer/test/src/task/strong/front_end_inference_test: Pass, Slow +@@ -124,16 +117,12 @@ front_end/test/summary_generator_test: SkipByDesign # depends on patched_sdk whi + front_end/test/mixin_export_test: SkipByDesign # depends on patched_sdk which is not built into the sdk + + [ $runtime == vm && $system == windows] +-analysis_server/*: Skip # Issue 27557 +-analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180 +-analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796 + analyzer/test/generated/non_error_resolver_kernel_test: RuntimeError # Issue 30785 + kernel/test/baseline_spec_mode_test: RuntimeError # Issue 28243 + kernel/test/baseline_strong_mode_test: RuntimeError # Issue 28243 + analyzer/tool/task_dependency_graph/check_test: Slow, Pass + + [ $compiler == dart2js ] +-analysis_server/test/integration: SkipByDesign # Analysis server integration tests don't make sense to run under dart2js, since the code under test always runs in the Dart vm as a subprocess. + analyzer_cli/test/*: SkipByDesign # Only meant to run on vm + analyzer_plugin/test/*: SkipByDesign # Only meant to run on vm + analyzer_plugin/tool/*: SkipByDesign # Only meant to run on vm +@@ -145,7 +134,6 @@ collection/test/equality_test/05: Fail # Issue 1533 + collection/test/equality_test/none: Pass, Fail # Issue 14348 + compiler/tool/*: SkipByDesign # Only meant to run on vm + front_end/tool/*: SkipByDesign # Only meant to run on vm +-telemetry/test/*: SkipByDesign # Only meant to run on vm + typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List. + front_end/test/incremental_kernel_generator_test: SkipByDesign # Uses dart:io + front_end/test/incremental_resolved_ast_generator_test: SkipByDesign # Uses dart:io +@@ -166,7 +154,6 @@ front_end/test/*: SkipByDesign # Tests written with dart:mirrors. + [ $compiler == dart2js && $builder_tag != dart2js_analyzer ] + analyzer/test/*: Skip # Issue 26813 + analyzer/tool/*: Skip # Issue 26813 +-analysis_server/test/*: Skip # Issue 26813 + + [ $compiler == dart2js && $checked ] + crypto/test/base64_test: Slow, Pass +@@ -202,8 +189,6 @@ crypto/test/sha1_test: Slow, Pass + [ $browser ] + analyzer_cli/*: SkipByDesign # Uses dart:io. + */test/analyzer_test: SkipByDesign # No need to run analysis tests on browser bots +-analysis_server/test/*: SkipByDesign # Uses dart:io. +-analysis_server/tool/spec/check_all_test: SkipByDesign # Uses dart:io. + analyzer/test/*: SkipByDesign # Uses dart:io. + analyzer/tool/task_dependency_graph/check_test: SkipByDesign # Uses dart:io. + analyzer/tool/summary/check_test: SkipByDesign # Uses dart:io. +diff --git a/pkg/telemetry/LICENSE b/pkg/telemetry/LICENSE +deleted file mode 100644 +index 389ce985634..00000000000 +--- a/pkg/telemetry/LICENSE ++++ /dev/null +@@ -1,26 +0,0 @@ +-Copyright 2017, the Dart project authors. All rights reserved. +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions are +-met: +- +- * Redistributions of source code must retain the above copyright +- notice, this list of conditions and the following disclaimer. +- * Redistributions in binary form must reproduce the above +- copyright notice, this list of conditions and the following +- disclaimer in the documentation and/or other materials provided +- with the distribution. +- * Neither the name of Google Inc. nor the names of its +- contributors may be used to endorse or promote products derived +- from this software without specific prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +diff --git a/pkg/telemetry/README.md b/pkg/telemetry/README.md +deleted file mode 100644 +index 26804b04610..00000000000 +--- a/pkg/telemetry/README.md ++++ /dev/null +@@ -1,51 +0,0 @@ +-# telemetry +- +-A library to facilitate reporting analytics and crash reports. +- +-## Analytics +- +-This library is designed to allow all Dart SDK tools to easily send analytics +-information and crash reports. The tools share a common setting to configure +-sending analytics data. To use this library for a specific tool: +- +-``` +-import 'package:telemetry/telemetry.dart'; +-import 'package:usage/usage.dart'; +- +-main() async { +- final String myAppTrackingID = ...; +- final String myAppName = ...; +- +- Analytics analytics = createAnalyticsInstance(myAppTrackingID, myAppName); +- ... +- analytics.sendScreenView('home'); +- ... +- await analytics.waitForLastPing(); +-} +-``` +- +-The analytics object reads from the correct user configuration file +-automatically without any additional configuration. Analytics will not be sent +-if the user has opted-out. +- +-## Crash reporting +- +-To use the crash reporting functionality, import `crash_reporting.dart`, and +-create a new `CrashReportSender` instance: +- +-```dart +-import 'package:telemetry/crash_reporting.dart'; +- +-main() { +- Analytics analytics = ...; +- CrashReportSender sender = new CrashReportSender(analytics); +- try { +- ... +- } catch (e, st) { +- sender.sendReport(e, st); +- } +-} +-``` +- +-Crash reports will only be sent if the cooresponding [Analytics] object is +-configured to send analytics. +diff --git a/pkg/telemetry/analysis_options.yaml b/pkg/telemetry/analysis_options.yaml +deleted file mode 100644 +index 85f01f0a5d4..00000000000 +--- a/pkg/telemetry/analysis_options.yaml ++++ /dev/null +@@ -1,10 +0,0 @@ +-analyzer: +- strong-mode: true +-linter: +- rules: +- - annotate_overrides +- - empty_constructor_bodies +- - empty_statements +- - unawaited_futures +- - unnecessary_brace_in_string_interps +- - valid_regexps +diff --git a/pkg/telemetry/lib/crash_reporting.dart b/pkg/telemetry/lib/crash_reporting.dart +deleted file mode 100644 +index c34766eb0b8..00000000000 +--- a/pkg/telemetry/lib/crash_reporting.dart ++++ /dev/null +@@ -1,94 +0,0 @@ +-// 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:io'; +- +-import 'package:http/http.dart' as http; +-import 'package:stack_trace/stack_trace.dart'; +-import 'package:usage/usage.dart'; +- +-/// Crash backend host. +-const String _crashServerHost = 'clients2.google.com'; +- +-/// Path to the crash servlet. +-const String _crashEndpointPath = '/cr/report'; // or, staging_report +- +-/// The field corresponding to the multipart/form-data file attachment where +-/// crash backend expects to find the Dart stack trace. +-const String _stackTraceFileField = 'DartError'; +- +-/// The name of the file attached as [stackTraceFileField]. +-/// +-/// The precise value is not important. It is ignored by the crash back end, but +-/// it must be supplied in the request. +-const String _stackTraceFilename = 'stacktrace_file'; +- +-/// Sends crash reports to Google. +-/// +-/// Clients shouldn't extend, mixin or implement this class. +-class CrashReportSender { +- static final Uri _baseUri = new Uri( +- scheme: 'https', host: _crashServerHost, path: _crashEndpointPath); +- +- final String crashProductId; +- final Analytics analytics; +- final http.Client _httpClient; +- +- /// Create a new [CrashReportSender], using the data from the given +- /// [Analytics] instance. +- CrashReportSender(this.crashProductId, this.analytics, +- {http.Client httpClient}) +- : _httpClient = httpClient ?? new http.Client(); +- +- /// Sends one crash report. +- /// +- /// The report is populated from data in [error] and [stackTrace]. +- Future sendReport(dynamic error, {StackTrace stackTrace}) async { +- if (!analytics.enabled) { +- return; +- } +- +- try { +- final Uri uri = _baseUri.replace( +- queryParameters: { +- 'product': analytics.trackingId, +- 'version': analytics.applicationVersion, +- }, +- ); +- +- final http.MultipartRequest req = new http.MultipartRequest('POST', uri); +- req.fields['uuid'] = analytics.clientId; +- req.fields['product'] = crashProductId; +- req.fields['version'] = analytics.applicationVersion; +- req.fields['osName'] = Platform.operatingSystem; +- // TODO(devoncarew): Report the operating system version when we're able. +- //req.fields['osVersion'] = Platform.operatingSystemVersion; +- req.fields['type'] = 'DartError'; +- req.fields['error_runtime_type'] = '${error.runtimeType}'; +- +- final Chain chain = new Chain.parse(stackTrace.toString()); +- req.files.add(new http.MultipartFile.fromString( +- _stackTraceFileField, chain.terse.toString(), +- filename: _stackTraceFilename)); +- +- final http.StreamedResponse resp = await _httpClient.send(req); +- +- if (resp.statusCode != 200) { +- throw 'server responded with HTTP status code ${resp.statusCode}'; +- } +- } on SocketException catch (error) { +- throw 'network error while sending crash report: $error'; +- } catch (error, stackTrace) { +- // If the sender itself crashes, just print. +- throw 'exception while sending crash report: $error\n$stackTrace'; +- } +- } +- +- /// Closes the client and cleans up any resources associated with it. This +- /// will close the associated [http.Client]. +- void dispose() { +- _httpClient.close(); +- } +-} +diff --git a/pkg/telemetry/lib/telemetry.dart b/pkg/telemetry/lib/telemetry.dart +deleted file mode 100644 +index 7b05ec13cbe..00000000000 +--- a/pkg/telemetry/lib/telemetry.dart ++++ /dev/null +@@ -1,126 +0,0 @@ +-// 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:io'; +- +-import 'package:path/path.dart' as path; +-import 'package:usage/src/usage_impl.dart'; +-import 'package:usage/src/usage_impl_io.dart'; +-import 'package:usage/src/usage_impl_io.dart' as usage_io show getDartVersion; +-import 'package:usage/usage.dart'; +-import 'package:usage/usage_io.dart'; +- +-export 'package:usage/usage.dart' show Analytics; +- +-// TODO(devoncarew): Hard-coded to off for now. Remove when we're ready to ship. +-final bool _HARD_CODE_OFF = true; +- +-// TODO(devoncarew): Don't show the UI until we're ready to ship. +-final bool SHOW_ANALYTICS_UI = false; +- +-final String _dartDirectoryName = '.dart'; +-final String _settingsFileName = 'analytics.json'; +- +-/// Dart SDK tools with analytics should display this notice. +-/// +-/// In addition, they should support displaying the analytics' status, and have +-/// a flag to toggle analytics. This may look something like: +-/// +-/// `Analytics are currently enabled (and can be disabled with --no-analytics).` +-final String analyticsNotice = +- "Dart SDK tools anonymously report feature usage statistics and basic crash\n" +- "reports to help improve Dart tools over time. See Google's privacy policy:\n" +- "https://www.google.com/intl/en/policies/privacy/."; +- +-/// Return a customized message for command-line tools to display about the +-/// state of analytics, and how users can enabled or disable analytics. +-/// +-/// An example return value might be `'Analytics are currently enabled (and can +-/// be disabled with --no-analytics).'` +-String createAnalyticsStatusMessage(bool enabled, +- {String command: 'analytics'}) { +- String currentState = enabled ? 'enabled' : 'disabled'; +- String toggleState = enabled ? 'disabled' : 'enabled'; +- String commandToggle = enabled ? 'no-$command' : command; +- +- return 'Analytics are currently $currentState ' +- '(and can be $toggleState with --$commandToggle).'; +-} +- +-/// Create an [Analytics] instance with the given trackingID and +-/// applicationName. +-/// +-/// This analytics instance will share a common enablement state with the rest +-/// of the Dart SDK tools. +-Analytics createAnalyticsInstance(String trackingId, String applicationName, +- {bool disableForSession: false}) { +- Directory dir = getDartStorageDirectory(); +- if (!dir.existsSync()) { +- dir.createSync(); +- } +- +- if (_HARD_CODE_OFF) { +- disableForSession = true; +- } +- +- File file = new File(path.join(dir.path, _settingsFileName)); +- return new _TelemetryAnalytics( +- trackingId, applicationName, getDartVersion(), file, disableForSession); +-} +- +-/// The directory used to store the analytics settings file. +-/// +-/// Typically, the directory is `~/.dart/` (and the settings file is +-/// `analytics.json`). +-Directory getDartStorageDirectory() => +- new Directory(path.join(userHomeDir(), _dartDirectoryName)); +- +-/// Return the version of the Dart SDK. +-String getDartVersion() => usage_io.getDartVersion(); +- +-class _TelemetryAnalytics extends AnalyticsImpl { +- final bool disableForSession; +- +- _TelemetryAnalytics( +- String trackingId, +- String applicationName, +- String applicationVersion, +- File file, +- this.disableForSession, +- ) +- : super( +- trackingId, +- new IOPersistentProperties.fromFile(file), +- new IOPostHandler(), +- applicationName: applicationName, +- applicationVersion: applicationVersion, +- ) { +- final String locale = getPlatformLocale(); +- if (locale != null) { +- setSessionValue('ul', locale); +- } +- } +- +- @override +- bool get enabled { +- if (disableForSession || isRunningOnBot()) { +- return false; +- } +- return super.enabled; +- } +-} +- +-bool isRunningOnBot() { +- // - https://docs.travis-ci.com/user/environment-variables/ +- // - https://www.appveyor.com/docs/environment-variables/ +- // - CHROME_HEADLESS and BUILDBOT_BUILDERNAME are properties on Chrome infra +- // bots. +- return Platform.environment['TRAVIS'] == 'true' || +- Platform.environment['BOT'] == 'true' || +- Platform.environment['CONTINUOUS_INTEGRATION'] == 'true' || +- Platform.environment['CHROME_HEADLESS'] == '1' || +- Platform.environment.containsKey('BUILDBOT_BUILDERNAME') || +- Platform.environment.containsKey('APPVEYOR') || +- Platform.environment.containsKey('CI'); +-} +diff --git a/pkg/telemetry/pubspec.yaml b/pkg/telemetry/pubspec.yaml +deleted file mode 100644 +index 2da46fb7e37..00000000000 +--- a/pkg/telemetry/pubspec.yaml ++++ /dev/null +@@ -1,16 +0,0 @@ +-name: telemetry +-description: A library to facilitate reporting analytics and crash reports. +-version: 0.0.1 +-author: Dart Team +- +-environment: +- sdk: '>=1.0.0 <2.0.0' +- +-dependencies: +- http: ^0.11.3+12 +- path: ^1.4.0 +- stack_trace: ^1.7.0 +- usage: ^3.2.0+1 +- +-dev_dependencies: +- test: ^0.12.0 +diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart +deleted file mode 100644 +index c4e812d3133..00000000000 +--- a/pkg/telemetry/test/crash_reporting_test.dart ++++ /dev/null +@@ -1,41 +0,0 @@ +-// 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:convert' show UTF8; +- +-import 'package:http/http.dart'; +-import 'package:http/testing.dart'; +-import 'package:telemetry/crash_reporting.dart'; +-import 'package:test/test.dart'; +-import 'package:usage/usage.dart'; +- +-void main() { +- group('crash_reporting', () { +- MockClient mockClient; +- +- Request request; +- +- setUp(() { +- mockClient = new MockClient((Request r) async { +- request = r; +- return new Response('crash-report-001', 200); +- }); +- }); +- +- test('CrashReportSender', () async { +- AnalyticsMock analytics = new AnalyticsMock()..enabled = true; +- CrashReportSender sender = new CrashReportSender( +- analytics.trackingId, analytics, +- httpClient: mockClient); +- +- await sender.sendReport('test-error', stackTrace: StackTrace.current); +- +- String body = UTF8.decode(request.bodyBytes); +- expect(body, contains('String')); // error.runtimeType +- expect(body, contains(analytics.trackingId)); +- expect(body, contains('1.0.0')); +- expect(body, contains(analytics.clientId)); +- }); +- }); +-} +diff --git a/pkg/telemetry/test/telemetry_test.dart b/pkg/telemetry/test/telemetry_test.dart +deleted file mode 100644 +index 7a9b70a4668..00000000000 +--- a/pkg/telemetry/test/telemetry_test.dart ++++ /dev/null +@@ -1,31 +0,0 @@ +-// 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:io'; +- +-import 'package:telemetry/telemetry.dart'; +-import 'package:test/test.dart'; +-import 'package:usage/usage.dart'; +- +-void main() { +- group('telemetry', () { +- test('getDartStorageDirectory', () { +- Directory dir = getDartStorageDirectory(); +- expect(dir, isNotNull); +- }); +- +- test('getDartVersion', () { +- expect(getDartVersion(), isNotNull); +- }); +- +- test('createAnalyticsInstance', () { +- Analytics analytics = createAnalyticsInstance('UA-0', 'test-app'); +- expect(analytics, isNotNull); +- expect(analytics.trackingId, 'UA-0'); +- expect(analytics.getSessionValue('an'), 'test-app'); +- expect(analytics.getSessionValue('av'), isNotNull); +- expect(analytics.clientId, isNotNull); +- }); +- }); +-} +diff --git a/runtime/observatory/lib/app.dart b/runtime/observatory/lib/app.dart +index f096ad88229..34b71d4a6da 100644 +--- a/runtime/observatory/lib/app.dart ++++ b/runtime/observatory/lib/app.dart +@@ -27,5 +27,4 @@ part 'src/app/location_manager.dart'; + part 'src/app/notification.dart'; + part 'src/app/page.dart'; + part 'src/app/settings.dart'; +-part 'src/app/view_model.dart'; +-part 'src/app/analytics.dart'; ++part 'src/app/view_model.dart'; +\ No newline at end of file +diff --git a/runtime/observatory/lib/src/app/analytics.dart b/runtime/observatory/lib/src/app/analytics.dart +deleted file mode 100644 +index 8f09f61c668..00000000000 +--- a/runtime/observatory/lib/src/app/analytics.dart ++++ /dev/null +@@ -1,31 +0,0 @@ +-// Copyright (c) 2015, 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. +- +-part of app; +- +-class Analytics { +- static final _UA = 'UA-26406144-17'; +- static final _name = 'Observatory'; +- static final _version = const String.fromEnvironment('OBS_VER'); +- static final _googleAnalytics = new AnalyticsHtml(_UA, _name, _version); +- +- static initialize() { +- // We only send screen views. This is allowed without user permission. +- // Note, before flipping this to be true we need a UI to allow users to +- // control this. +- _googleAnalytics.optIn = false; +- } +- +- /// Called whenever an Observatory page is viewed. +- static Future reportPageView(Uri uri) { +- // Only report analytics when running in JavaScript. +- if (Utils.runningInJavaScript()) { +- // The screen name is the uri's path. e.g. inspect, profile. +- final screenName = uri.path; +- return _googleAnalytics.sendScreenView(screenName); +- } else { +- return new Future.value(null); +- } +- } +-} +diff --git a/runtime/observatory/observatory_sources.gni b/runtime/observatory/observatory_sources.gni +index 15ddbe526a0..760399f4768 100644 +--- a/runtime/observatory/observatory_sources.gni ++++ b/runtime/observatory/observatory_sources.gni +@@ -22,7 +22,6 @@ observatory_sources = [ + "lib/service_html.dart", + "lib/service_io.dart", + "lib/src/allocation_profile/allocation_profile.dart", +- "lib/src/app/analytics.dart", + "lib/src/app/application.dart", + "lib/src/app/location_manager.dart", + "lib/src/app/notification.dart", +diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn +index 8702969e800..17ef0ab346c 100644 +--- a/sdk/BUILD.gn ++++ b/sdk/BUILD.gn +@@ -36,7 +36,6 @@ declare_args() { + # ......dartdevc + # ......pub + # ......snapshots/ +-# ........analysis_server.dart.snapshot + # ........dart2js.dart.snapshot + # ........dartanalyzer.dart.snapshot + # ........dartdoc.dart.snapshot +@@ -67,7 +66,6 @@ declare_args() { + #.........vm_platform.dill + #.........vm_platform_strong.dill + #.........dev_compiler/ +-# ......analysis_server/ + # ......analyzer/ + # ......async/ + # ......collection/ +@@ -107,10 +105,6 @@ _scripts = [ "dartdoc" ] + + # Snapshots that go under bin/snapshots + _platform_sdk_snapshots = [ +- [ +- "analysis_server", +- "../utils/analysis_server", +- ], + [ + "dartanalyzer", + "../utils/dartanalyzer:generate_dartanalyzer_snapshot", +@@ -130,10 +124,6 @@ _platform_sdk_snapshots = [ + ] + + _full_sdk_snapshots = [ +- [ +- "analysis_server", +- "../utils/analysis_server", +- ], + [ + "dart2js", + "../utils/compiler:dart2js", +@@ -212,7 +202,6 @@ _full_sdk_libraries = [ + # Package sources copied to lib/ + _analyzer_source_dirs = [ + "analyzer", +- "analysis_server", + "front_end", + "kernel", + ] +diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status +index 3abc3f80a2d..3eca5d81337 100644 +--- a/tests/lib/analyzer/analyze_library.status ++++ b/tests/lib/analyzer/analyze_library.status +@@ -5,7 +5,6 @@ + [ $compiler == dart2analyzer && $use_sdk ] + lib/*: Skip # Issue 28620 + lib/analyzer: Skip # Issue 28620 +-lib/analysis_server: Skip # Issue 28620 + lib/dev_compiler: Skip # Issue 28620 + lib/front_end: Skip # Issue 28620 + +diff --git a/tools/bots/dartdoc_footer.html b/tools/bots/dartdoc_footer.html +index 63de697d483..e69de29bb2d 100644 +--- a/tools/bots/dartdoc_footer.html ++++ b/tools/bots/dartdoc_footer.html +@@ -1,13 +0,0 @@ +- +- +- +diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json +index 2cf500eb743..f380acccaf0 100644 +--- a/tools/bots/test_matrix.json ++++ b/tools/bots/test_matrix.json +@@ -1077,16 +1077,6 @@ + "pkg/analyzer" + ] + }, +- { +- "name": "analysis_server unit tests", +- "arguments": [ +- "--compiler=none", +- "--runtime=vm", +- "--checked", +- "--use-sdk", +- "pkg/analysis_server" +- ] +- }, + { + "name": "analysis_cli unit tests", + "arguments": [ +@@ -1134,26 +1124,6 @@ + } + ] + }, +- { +- "builders": ["analyzer-analysis-server-linux"], +- "steps": [ +- { +- "name": "Analyze analysis_server", +- "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer", +- "arguments": ["--no-hints","pkg/analysis_server"] +- }, +- { +- "name": "Analyze analysis_server", +- "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer", +- "arguments": ["--no-hints","pkg/analyzer"] +- }, +- { +- "name": "Analyze analysis_server", +- "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer", +- "arguments": ["--no-hints","pkg/analyzer_plugin"] +- } +- ] +- }, + { + "builders": ["pkg-linux-release","pkg-win-release","pkg-mac-release"], + "meta": { +diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh +index 3932c704c2e..3990f254eed 100755 +--- a/tools/bots/try_benchmarks.sh ++++ b/tools/bots/try_benchmarks.sh +@@ -409,7 +409,6 @@ EOF + out/ReleaseX64/dart pkg/front_end/tool/fasta_perf.dart scan hello.dart + out/ReleaseX64/dart pkg/front_end/tool/perf.dart unlinked_summarize hello.dart + out/ReleaseX64/dart pkg/front_end/tool/perf.dart unlinked_summarize_from_sources hello.dart +- out/ReleaseX64/dart pkg/analysis_server/benchmark/benchmarks.dart run --quick --repeat 1 analysis-server-cold + out/ReleaseX64/dart --print_metrics pkg/analyzer_cli/bin/analyzer.dart --dart-sdk=sdk hello.dart + echo '[{"name":"foo","edits":[["pkg/compiler/lib/src/dart2js.dart","2016","2017"],["pkg/compiler/lib/src/options.dart","2016","2017"]]}]' > appjit_train_edits.json + out/ReleaseX64/dart --background-compilation=false --snapshot-kind=app-jit --snapshot=pkg/front_end/tool/incremental_perf.dart.appjit pkg/front_end/tool/incremental_perf.dart --target=vm --sdk-summary=out/ReleaseX64/vm_platform.dill --sdk-library-specification=sdk/lib/libraries.json pkg/compiler/lib/src/dart2js.dart appjit_train_edits.json +diff --git a/utils/analysis_server/.gitignore b/utils/analysis_server/.gitignore +deleted file mode 100644 +index 010faca1007..00000000000 +--- a/utils/analysis_server/.gitignore ++++ /dev/null +@@ -1,3 +0,0 @@ +-/analysis_server.Makefile +-/analysis_server.target.mk +- +diff --git a/utils/analysis_server/BUILD.gn b/utils/analysis_server/BUILD.gn +deleted file mode 100644 +index 9359e2c6fc5..00000000000 +--- a/utils/analysis_server/BUILD.gn ++++ /dev/null +@@ -1,10 +0,0 @@ +-# Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +-# for details. All rights reserved. Use of this source code is governed by a +-# BSD-style license that can be found in the LICENSE file. +- +-import("../application_snapshot.gni") +- +-application_snapshot("analysis_server") { +- main_dart = "../../pkg/analysis_server/bin/server.dart" +- training_args = [ "--help" ] +-} +-- +2.29.2 + -- 2.29.2