Chromium Code Reviews| Index: dart/site/try/poi/poi.dart |
| diff --git a/dart/site/try/poi/poi.dart b/dart/site/try/poi/poi.dart |
| index fd06280cd3bd9ede20872ce3f0f23ac862f03d92..9261abeb325d2f80479e355310887f2e2ccd4d1c 100644 |
| --- a/dart/site/try/poi/poi.dart |
| +++ b/dart/site/try/poi/poi.dart |
| @@ -17,8 +17,7 @@ import 'package:compiler/implementation/source_file_provider.dart' show |
| FormattingDiagnosticHandler, |
| SourceFileProvider; |
| -import 'package:compiler/compiler.dart' as api show |
| - Diagnostic; |
| +import 'package:compiler/compiler.dart' as api; |
| import 'package:compiler/implementation/dart2jslib.dart' show |
| Compiler, |
| @@ -31,26 +30,43 @@ import 'package:compiler/implementation/elements/visitor.dart' show |
| import 'package:compiler/implementation/elements/elements.dart' show |
| ClassElement, |
| + CompilationUnitElement, |
| Element, |
| + LibraryElement, |
| ScopeContainerElement; |
| import 'package:compiler/implementation/scanner/scannerlib.dart' show |
| PartialClassElement, |
| PartialElement; |
| +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]); |
| - return runPoi(script, position).then((Element element) { |
| - print('Found $element.'); |
| - }); |
| -} |
| -Future<Element> runPoi(Uri script, int position) { |
| FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler(); |
| handler |
| ..verbose = true |
| ..enableColors = true; |
| + api.CompilerInputProvider inputProvider = handler.provider; |
| + |
| + inputProvider(script); |
| + handler( |
| + script, position, position + 1, |
| + 'Point of interest.', api.Diagnostic.HINT); |
| + |
| + Future future = runPoi(script, position, inputProvider, handler); |
| + return future.then((Element element) { |
| + print(scopeInformation(element, position)); |
| + }); |
| +} |
| + |
| +Future<Element> runPoi( |
| + Uri script, int position, |
| + api.CompilerInputProvider inputProvider, |
| + api.DiagnosticHandler handler) { |
| Uri libraryRoot = Uri.base.resolve('sdk/'); |
| Uri packageRoot = Uri.base.resolveUri( |
| @@ -67,7 +83,7 @@ Future<Element> runPoi(Uri script, int position) { |
| Compiler cachedCompiler = null; |
| cachedCompiler = reuseCompiler( |
| diagnosticHandler: handler, |
| - inputProvider: handler.provider, |
| + inputProvider: inputProvider, |
| options: options, |
| cachedCompiler: cachedCompiler, |
| libraryRoot: libraryRoot, |
| @@ -80,26 +96,23 @@ Future<Element> runPoi(Uri script, int position) { |
| if (success != true) { |
| throw 'Compilation failed'; |
| } |
| - return poi(cachedCompiler, script, position); |
| + return findPosition(position, cachedCompiler.mainApp); |
| }); |
| } |
| -Element poi(Compiler compiler, Uri script, int offset) { |
| - compiler.handler( |
| - script, offset, offset + 1, |
| - 'Point of interest.', api.Diagnostic.HINT); |
| - |
| - Element element = findPosition(offset, compiler.mainApp); |
| - |
| - return element; |
| -} |
| - |
| Element findPosition(int position, Element element) { |
| FindPositionVisitor visitor = new FindPositionVisitor(position, element); |
| element.accept(visitor); |
| return visitor.element; |
| } |
| +String scopeInformation(Element element, int position) { |
| + ScopeInformationVisitor vistor = |
|
Johnni Winther
2014/07/14 10:35:36
'vistor' -> 'visitor'.
ahe
2014/07/14 13:06:07
Done.
|
| + new ScopeInformationVisitor(element, position); |
| + element.accept(vistor); |
| + return '${vistor.buffer}'; |
| +} |
| + |
| class FindPositionVisitor extends ElementVisitor { |
| final int position; |
| Element element; |
| @@ -107,19 +120,21 @@ class FindPositionVisitor extends ElementVisitor { |
| FindPositionVisitor(this.position, this.element); |
| visitElement(Element e) { |
| - if (e is! PartialElement) return; |
| - if (e.beginToken.charOffset <= position && |
| - position < e.endToken.next.charOffset) { |
| - element = e; |
| + if (e is PartialElement) { |
| + if (e.beginToken.charOffset <= position && |
| + position < e.endToken.next.charOffset) { |
| + element = e; |
| + } |
| } |
| } |
| visitClassElement(ClassElement e) { |
| - if (e is! PartialClassElement) return; |
| - if (e.beginToken.charOffset <= position && |
| - position < e.endToken.next.charOffset) { |
| - element = e; |
| - visitScopeContainerElement(e); |
| + if (e is PartialClassElement) { |
| + if (e.beginToken.charOffset <= position && |
| + position < e.endToken.next.charOffset) { |
| + element = e; |
| + visitScopeContainerElement(e); |
| + } |
| } |
| } |
| @@ -141,3 +156,99 @@ class ScriptOnlyFilter implements QueueFilter { |
| } |
| } |
| } |
| + |
| +class ScopeInformationVisitor extends ElementVisitor/* <void> */ { |
| + // TODO(ahe): Include function paramters and local variables. |
|
Johnni Winther
2014/07/14 10:35:36
'paramters' -> 'parameters'
ahe
2014/07/14 13:06:07
Done.
|
| + |
| + final Element element; |
| + final int position; |
| + final StringBuffer buffer = new StringBuffer(); |
| + int indentationLevel = 0; |
| + |
| + ScopeInformationVisitor(this.element, this.position); |
| + |
| + String get indentation => ' ' * indentationLevel; |
| + |
| + StringBuffer get indented => buffer..write(indentation); |
| + |
| + void visitElement(Element e) { |
| + serialize(e, omitEnclosing: false); |
| + } |
| + |
| + void visitLibraryElement(LibraryElement e) { |
| + bool isFirst = true; |
| + serialize( |
| + e, omitEnclosing: true, |
| + name: relativize(Uri.base, e.canonicalUri, false), |
| + serializeMembers: () { |
| + // TODO(ahe): Include imported elements in libraries. |
| + e.forEachLocalMember((Element member) { |
| + if (!isFirst) { |
| + buffer.write(','); |
| + } |
| + buffer.write('\n'); |
| + indented; |
| + serialize(member); |
| + isFirst = false; |
| + }); |
| + }); |
| + } |
| + |
| + void visitScopeContainerElement(ScopeContainerElement e) { |
| + bool isFirst = true; |
| + serialize(e, omitEnclosing: false, serializeMembers: () { |
| + // TODO(ahe): Include inherited members in classes. |
| + e.forEachLocalMember((Element member) { |
| + if (!isFirst) { |
| + buffer.write(','); |
| + } |
| + buffer.write('\n'); |
| + indented; |
| + serialize(member); |
| + isFirst = false; |
| + }); |
| + }); |
| + } |
| + |
| + void visitCompilationUnitElement(CompilationUnitElement e) { |
| + e.enclosingElement.accept(this); |
| + } |
| + |
| + void serialize( |
| + Element element, |
| + {bool omitEnclosing: true, |
| + void serializeMembers(), |
| + String name}) { |
| + if (name == null) { |
| + name = element.name; |
| + } |
| + buffer.write('{\n'); |
| + indentationLevel++; |
| + indented |
| + ..write('"name": "') |
| + ..write(name) |
| + ..write('",\n'); |
| + indented |
| + ..write('"kind": "') |
| + ..write(element.kind) |
| + ..write('"'); |
| + // TODO(ahe): Add a type/signature field. |
| + if (serializeMembers != null) { |
| + buffer.write(',\n'); |
| + indented.write('"members": ['); |
| + indentationLevel++; |
| + serializeMembers(); |
| + indentationLevel--; |
| + buffer.write('\n'); |
| + indented.write(']'); |
| + } |
| + if (!omitEnclosing) { |
| + buffer.write(',\n'); |
| + indented.write('"enclosing": '); |
| + element.enclosingElement.accept(this); |
| + } |
| + indentationLevel--; |
| + buffer.write('\n'); |
| + indented.write('}'); |
| + } |
| +} |