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('}'); |
+ } |
+} |