Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(830)

Side by Side Diff: dart/site/try/poi/poi.dart

Issue 394543002: Find token at position and query Dart Mind if identifier or keyword. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r39130. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/tests/try/poi/data/empty_main.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library trydart.poi; 5 library trydart.poi;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future; 8 Completer,
9 Future,
10 Stream;
9 11
10 import 'dart:io' show 12 import 'dart:io' show
11 Platform; 13 HttpClient,
14 HttpClientRequest,
15 HttpClientResponse,
16 Platform,
17 stdout;
18
19 import 'dart:io' as io;
20
21 import 'dart:convert' show
22 LineSplitter,
23 UTF8;
12 24
13 import 'package:dart2js_incremental/dart2js_incremental.dart' show 25 import 'package:dart2js_incremental/dart2js_incremental.dart' show
14 reuseCompiler; 26 reuseCompiler;
15 27
16 import 'package:compiler/implementation/source_file_provider.dart' show 28 import 'package:compiler/implementation/source_file_provider.dart' show
17 FormattingDiagnosticHandler, 29 FormattingDiagnosticHandler,
18 SourceFileProvider; 30 SourceFileProvider;
19 31
20 import 'package:compiler/compiler.dart' as api; 32 import 'package:compiler/compiler.dart' as api;
21 33
22 import 'package:compiler/implementation/dart2jslib.dart' show 34 import 'package:compiler/implementation/dart2jslib.dart' show
23 Compiler, 35 Compiler,
24 Enqueuer, 36 Enqueuer,
25 QueueFilter, 37 QueueFilter,
26 WorkItem; 38 WorkItem;
27 39
28 import 'package:compiler/implementation/elements/visitor.dart' show 40 import 'package:compiler/implementation/elements/visitor.dart' show
29 ElementVisitor; 41 ElementVisitor;
30 42
31 import 'package:compiler/implementation/elements/elements.dart' show 43 import 'package:compiler/implementation/elements/elements.dart' show
32 ClassElement, 44 ClassElement,
33 CompilationUnitElement, 45 CompilationUnitElement,
34 Element, 46 Element,
35 LibraryElement, 47 LibraryElement,
36 ScopeContainerElement; 48 ScopeContainerElement;
37 49
38 import 'package:compiler/implementation/scanner/scannerlib.dart' show 50 import 'package:compiler/implementation/scanner/scannerlib.dart' show
51 EOF_TOKEN,
52 IDENTIFIER_TOKEN,
53 KEYWORD_TOKEN,
39 PartialClassElement, 54 PartialClassElement,
40 PartialElement; 55 PartialElement,
56 Token;
41 57
42 import 'package:compiler/implementation/util/uri_extras.dart' show 58 import 'package:compiler/implementation/util/uri_extras.dart' show
43 relativize; 59 relativize;
44 60
61 /// Controls if this program should be querying Dart Mind. Used by tests.
62 bool enableDartMind = true;
63
64 /// Iterator over lines from standard input (or the argument array).
65 Iterator<String> stdin;
66
67 /// Iterator for reading lines from [io.stdin].
68 class StdinIterator implements Iterator<String> {
69 String current;
70
71 bool moveNext() {
72 current = io.stdin.readLineSync();
73 return true;
74 }
75 }
76
45 main(List<String> arguments) { 77 main(List<String> arguments) {
46 Uri script = Uri.base.resolve(arguments.first);
47 int position = int.parse(arguments[1]);
48
49 FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler(); 78 FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler();
50 handler 79 handler
51 ..verbose = true 80 ..verbose = false
52 ..enableColors = true; 81 ..enableColors = true;
53 api.CompilerInputProvider inputProvider = handler.provider; 82 api.CompilerInputProvider inputProvider = handler.provider;
54 83
84 if (arguments.length == 0) {
85 stdin = new StdinIterator();
86 } else {
87 stdin = arguments.where((String line) {
88 print(line); // Simulates user input in terminal.
89 return true;
90 }).iterator;
91 }
92
93 return prompt('Dart file: ').then((String fileName) {
94 return prompt('Position: ').then((String position) {
95 return parseUserInput(fileName, position, inputProvider, handler);
96 });
97 });
98 }
99
100 Future<String> prompt(message) {
101 stdout.write(message);
102 return stdout.flush().then((_) {
103 stdin.moveNext();
104 return stdin.current;
105 });
106 }
107
108 Future queryDartMind(String prefix, String info) {
109 // TODO(lukechurch): Use [info] for something.
110 if (!enableDartMind) return new Future.value("[]");
111 String encodedArg0 = Uri.encodeComponent('"$prefix"');
112 String mindQuery =
113 'http://dart-mind.appspot.com/rpc'
114 '?action=GetExportingPubCompletions'
115 '&arg0=$encodedArg0';
116 Uri uri = Uri.parse(mindQuery);
117
118 HttpClient client = new HttpClient();
119 return client.getUrl(uri).then((HttpClientRequest request) {
120 return request.close();
121 }).then((HttpClientResponse response) {
122 Completer<String> completer = new Completer<String>();
123 response.transform(UTF8.decoder).listen((contents) {
124 completer.complete(contents);
125 });
126 return completer.future;
127 });
128 }
129
130 Future parseUserInput(
131 String fileName,
132 String positionString,
133 api.CompilerInputProvider inputProvider,
134 api.DiagnosticHandler handler) {
135 Future repeat() {
136 return prompt('Position: ').then((String positionString) {
137 return parseUserInput(fileName, positionString, inputProvider, handler);
138 });
139 }
140
141 Uri script = Uri.base.resolveUri(new Uri.file(fileName));
142 if (positionString == null) return null;
143 int position = int.parse(
144 positionString, onError: (_) => print('Please enter an integer.'));
145 if (position == null) return repeat();
146
55 inputProvider(script); 147 inputProvider(script);
56 handler( 148 handler(
57 script, position, position + 1, 149 script, position, position + 1,
58 'Point of interest.', api.Diagnostic.HINT); 150 'Point of interest. Cursor is immediately before highlighted character.',
151 api.Diagnostic.HINT);
152
153 Stopwatch sw = new Stopwatch()..start();
59 154
60 Future future = runPoi(script, position, inputProvider, handler); 155 Future future = runPoi(script, position, inputProvider, handler);
61 return future.then((Element element) { 156 return future.then((Element element) {
62 print(scopeInformation(element, position)); 157 print('Resolving took ${sw.elapsedMicroseconds}us.');
158 sw.reset();
159 String info = scopeInformation(element, position);
160 print(info);
161 print('Scope information took ${sw.elapsedMicroseconds}us.');
162 sw.reset();
163 Token token = findToken(element, position);
164 String prefix;
165 if (token != null) {
166 if (token.charOffset + token.charCount <= position) {
167 // After the token; in whitespace, or in the beginning of another token.
168 prefix = "";
169 } else if (token.kind == IDENTIFIER_TOKEN ||
170 token.kind == KEYWORD_TOKEN) {
171 prefix = token.value.substring(0, position - token.charOffset);
172 }
173 }
174 print('Find token took ${sw.elapsedMicroseconds}us.');
175 sw.reset();
176 if (prefix != null) {
177 return queryDartMind(prefix, info).then((String dartMindSuggestion) {
178 sw.stop();
179 print('Dart Mind ($prefix): $dartMindSuggestion.');
180 print('Dart Mind took ${sw.elapsedMicroseconds}us.');
181 return repeat();
182 });
183 } else {
184 print("Didn't talk to Dart Mind, no identifier at POI ($token).");
185 return repeat();
186 }
63 }); 187 });
64 } 188 }
65 189
190 /// Find the token corresponding to [position] in [element]. The method only
191 /// works for instances of [PartialElement] or [LibraryElement]. Support for
192 /// [LibraryElement] is currently limited, and works only for named libraries.
193 Token findToken(Element element, int position) {
194 Token beginToken;
195 if (element is PartialElement) {
196 beginToken = element.beginToken;
197 } else if (element is PartialClassElement) {
198 beginToken = element.beginToken;
199 } else if (element.isLibrary) {
200 // TODO(ahe): Generalize support for library elements (and update above
201 // documentation).
202 LibraryElement lib = element;
203 var tag = lib.libraryTag;
204 if (tag != null) {
205 beginToken = tag.libraryKeyword;
206 }
207 } else {
208 beginToken = element.position;
209 }
210 if (beginToken == null) return null;
211 for (Token token = beginToken; token.kind != EOF_TOKEN; token = token.next) {
212 if (token.charOffset < position && position <= token.next.charOffset) {
213 return token;
214 }
215 }
216 return null;
217 }
218
219 Compiler cachedCompiler;
220
66 Future<Element> runPoi( 221 Future<Element> runPoi(
67 Uri script, int position, 222 Uri script, int position,
68 api.CompilerInputProvider inputProvider, 223 api.CompilerInputProvider inputProvider,
69 api.DiagnosticHandler handler) { 224 api.DiagnosticHandler handler) {
70 225
71 Uri libraryRoot = Uri.base.resolve('sdk/'); 226 Uri libraryRoot = Uri.base.resolve('sdk/');
72 Uri packageRoot = Uri.base.resolveUri( 227 Uri packageRoot = Uri.base.resolveUri(
73 new Uri.file('${Platform.packageRoot}/')); 228 new Uri.file('${Platform.packageRoot}/'));
74 229
75 var options = [ 230 var options = [
76 '--analyze-main', 231 '--analyze-main',
77 '--analyze-only', 232 '--analyze-only',
78 '--no-source-maps', 233 '--no-source-maps',
79 '--verbose', 234 '--verbose',
80 '--categories=Client,Server', 235 '--categories=Client,Server',
236 '--incremental-support',
237 '--disable-type-inference',
81 ]; 238 ];
82 239
83 Compiler cachedCompiler = null;
84 cachedCompiler = reuseCompiler( 240 cachedCompiler = reuseCompiler(
85 diagnosticHandler: handler, 241 diagnosticHandler: handler,
86 inputProvider: inputProvider, 242 inputProvider: inputProvider,
87 options: options, 243 options: options,
88 cachedCompiler: cachedCompiler, 244 cachedCompiler: cachedCompiler,
89 libraryRoot: libraryRoot, 245 libraryRoot: libraryRoot,
90 packageRoot: packageRoot, 246 packageRoot: packageRoot,
91 packagesAreImmutable: true); 247 packagesAreImmutable: true);
92 248
93 cachedCompiler.enqueuerFilter = new ScriptOnlyFilter(script); 249 cachedCompiler.enqueuerFilter = new ScriptOnlyFilter(script);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (!omitEnclosing) { 401 if (!omitEnclosing) {
246 buffer.write(',\n'); 402 buffer.write(',\n');
247 indented.write('"enclosing": '); 403 indented.write('"enclosing": ');
248 element.enclosingElement.accept(this); 404 element.enclosingElement.accept(this);
249 } 405 }
250 indentationLevel--; 406 indentationLevel--;
251 buffer.write('\n'); 407 buffer.write('\n');
252 indented.write('}'); 408 indented.write('}');
253 } 409 }
254 } 410 }
OLDNEW
« no previous file with comments | « no previous file | dart/tests/try/poi/data/empty_main.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698