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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | dart/tests/try/poi/data/empty_main.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/site/try/poi/poi.dart
diff --git a/dart/site/try/poi/poi.dart b/dart/site/try/poi/poi.dart
index e93e6c888f61f09039313684003bf06c1d6321a9..d9cdeba2fb3cc6592129f0078894a5af7a97c1f0 100644
--- a/dart/site/try/poi/poi.dart
+++ b/dart/site/try/poi/poi.dart
@@ -5,10 +5,22 @@
library trydart.poi;
import 'dart:async' show
- Future;
+ Completer,
+ Future,
+ Stream;
import 'dart:io' show
- Platform;
+ HttpClient,
+ HttpClientRequest,
+ HttpClientResponse,
+ Platform,
+ stdout;
+
+import 'dart:io' as io;
+
+import 'dart:convert' show
+ LineSplitter,
+ UTF8;
import 'package:dart2js_incremental/dart2js_incremental.dart' show
reuseCompiler;
@@ -36,33 +48,176 @@ import 'package:compiler/implementation/elements/elements.dart' show
ScopeContainerElement;
import 'package:compiler/implementation/scanner/scannerlib.dart' show
+ EOF_TOKEN,
+ IDENTIFIER_TOKEN,
+ KEYWORD_TOKEN,
PartialClassElement,
- PartialElement;
+ PartialElement,
+ Token;
import 'package:compiler/implementation/util/uri_extras.dart' show
relativize;
-main(List<String> arguments) {
- Uri script = Uri.base.resolve(arguments.first);
- int position = int.parse(arguments[1]);
+/// Controls if this program should be querying Dart Mind. Used by tests.
+bool enableDartMind = true;
+
+/// Iterator over lines from standard input (or the argument array).
+Iterator<String> stdin;
+
+/// Iterator for reading lines from [io.stdin].
+class StdinIterator implements Iterator<String> {
+ String current;
+ bool moveNext() {
+ current = io.stdin.readLineSync();
+ return true;
+ }
+}
+
+main(List<String> arguments) {
FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler();
handler
- ..verbose = true
+ ..verbose = false
..enableColors = true;
api.CompilerInputProvider inputProvider = handler.provider;
+ if (arguments.length == 0) {
+ stdin = new StdinIterator();
+ } else {
+ stdin = arguments.where((String line) {
+ print(line); // Simulates user input in terminal.
+ return true;
+ }).iterator;
+ }
+
+ return prompt('Dart file: ').then((String fileName) {
+ return prompt('Position: ').then((String position) {
+ return parseUserInput(fileName, position, inputProvider, handler);
+ });
+ });
+}
+
+Future<String> prompt(message) {
+ stdout.write(message);
+ return stdout.flush().then((_) {
+ stdin.moveNext();
+ return stdin.current;
+ });
+}
+
+Future queryDartMind(String prefix, String info) {
+ // TODO(lukechurch): Use [info] for something.
+ if (!enableDartMind) return new Future.value("[]");
+ String encodedArg0 = Uri.encodeComponent('"$prefix"');
+ String mindQuery =
+ 'http://dart-mind.appspot.com/rpc'
+ '?action=GetExportingPubCompletions'
+ '&arg0=$encodedArg0';
+ Uri uri = Uri.parse(mindQuery);
+
+ HttpClient client = new HttpClient();
+ return client.getUrl(uri).then((HttpClientRequest request) {
+ return request.close();
+ }).then((HttpClientResponse response) {
+ Completer<String> completer = new Completer<String>();
+ response.transform(UTF8.decoder).listen((contents) {
+ completer.complete(contents);
+ });
+ return completer.future;
+ });
+}
+
+Future parseUserInput(
+ String fileName,
+ String positionString,
+ api.CompilerInputProvider inputProvider,
+ api.DiagnosticHandler handler) {
+ Future repeat() {
+ return prompt('Position: ').then((String positionString) {
+ return parseUserInput(fileName, positionString, inputProvider, handler);
+ });
+ }
+
+ Uri script = Uri.base.resolveUri(new Uri.file(fileName));
+ if (positionString == null) return null;
+ int position = int.parse(
+ positionString, onError: (_) => print('Please enter an integer.'));
+ if (position == null) return repeat();
+
inputProvider(script);
handler(
script, position, position + 1,
- 'Point of interest.', api.Diagnostic.HINT);
+ 'Point of interest. Cursor is immediately before highlighted character.',
+ api.Diagnostic.HINT);
+
+ Stopwatch sw = new Stopwatch()..start();
Future future = runPoi(script, position, inputProvider, handler);
return future.then((Element element) {
- print(scopeInformation(element, position));
+ print('Resolving took ${sw.elapsedMicroseconds}us.');
+ sw.reset();
+ String info = scopeInformation(element, position);
+ print(info);
+ print('Scope information took ${sw.elapsedMicroseconds}us.');
+ sw.reset();
+ Token token = findToken(element, position);
+ String prefix;
+ if (token != null) {
+ if (token.charOffset + token.charCount <= position) {
+ // After the token; in whitespace, or in the beginning of another token.
+ prefix = "";
+ } else if (token.kind == IDENTIFIER_TOKEN ||
+ token.kind == KEYWORD_TOKEN) {
+ prefix = token.value.substring(0, position - token.charOffset);
+ }
+ }
+ print('Find token took ${sw.elapsedMicroseconds}us.');
+ sw.reset();
+ if (prefix != null) {
+ return queryDartMind(prefix, info).then((String dartMindSuggestion) {
+ sw.stop();
+ print('Dart Mind ($prefix): $dartMindSuggestion.');
+ print('Dart Mind took ${sw.elapsedMicroseconds}us.');
+ return repeat();
+ });
+ } else {
+ print("Didn't talk to Dart Mind, no identifier at POI ($token).");
+ return repeat();
+ }
});
}
+/// Find the token corresponding to [position] in [element]. The method only
+/// works for instances of [PartialElement] or [LibraryElement]. Support for
+/// [LibraryElement] is currently limited, and works only for named libraries.
+Token findToken(Element element, int position) {
+ Token beginToken;
+ if (element is PartialElement) {
+ beginToken = element.beginToken;
+ } else if (element is PartialClassElement) {
+ beginToken = element.beginToken;
+ } else if (element.isLibrary) {
+ // TODO(ahe): Generalize support for library elements (and update above
+ // documentation).
+ LibraryElement lib = element;
+ var tag = lib.libraryTag;
+ if (tag != null) {
+ beginToken = tag.libraryKeyword;
+ }
+ } else {
+ beginToken = element.position;
+ }
+ if (beginToken == null) return null;
+ for (Token token = beginToken; token.kind != EOF_TOKEN; token = token.next) {
+ if (token.charOffset < position && position <= token.next.charOffset) {
+ return token;
+ }
+ }
+ return null;
+}
+
+Compiler cachedCompiler;
+
Future<Element> runPoi(
Uri script, int position,
api.CompilerInputProvider inputProvider,
@@ -78,9 +233,10 @@ Future<Element> runPoi(
'--no-source-maps',
'--verbose',
'--categories=Client,Server',
+ '--incremental-support',
+ '--disable-type-inference',
];
- Compiler cachedCompiler = null;
cachedCompiler = reuseCompiler(
diagnosticHandler: handler,
inputProvider: inputProvider,
« 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