Created
August 3, 2015 23:54
-
-
Save kasperpeulen/098ce711aa8e362cc366 to your computer and use it in GitHub Desktop.
Alginment is off after newline
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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 services.analyzer; | |
| import 'package:analyzer/analyzer.dart'; | |
| import 'package:analyzer/src/generated/element.dart'; | |
| import 'package:analyzer/src/generated/engine.dart' hide Logger; | |
| import 'package:analyzer/src/generated/java_io.dart'; | |
| import 'package:analyzer/src/generated/sdk.dart'; | |
| import 'package:analyzer/src/generated/sdk_io.dart'; | |
| import 'package:analyzer/src/generated/source.dart'; | |
| import 'package:cli_util/cli_util.dart' as cli_util; | |
| main() async { | |
| var b = await dartdoc("void main() => print('hello world');", 20); | |
| print(b); | |
| } | |
| Map<String, String> dartdoc(String source, int offset) { | |
| String _sdkPath = cli_util.getSdkDir([]).path; | |
| DartSdk sdk = new DirectoryBasedDartSdk(new JavaFile(_sdkPath), true); | |
| AnalysisContext _context = AnalysisEngine.instance.createAnalysisContext(); | |
| List<UriResolver> resolvers = [ | |
| new DartUriResolver(sdk) | |
| ]; | |
| _context.sourceFactory = new SourceFactory(resolvers); | |
| var _source = new StringSource(source, "main.dart"); | |
| ChangeSet changeSet = new ChangeSet(); | |
| changeSet.addedSource(_source); | |
| _context.applyChanges(changeSet); | |
| LibraryElement library = _context.computeLibraryElement(_source); | |
| CompilationUnit unit = _context.resolveCompilationUnit(_source, library); | |
| 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; | |
| Map info = {}; | |
| // element | |
| Element element = ElementLocator.locateWithOffset(expression, offset); | |
| if (element != null) { | |
| // variable, if synthetic accessor | |
| if (element is PropertyAccessorElement) { | |
| PropertyAccessorElement accessor = element; | |
| if (accessor.isSynthetic) element = accessor.variable; | |
| } | |
| // documentation | |
| String dartDoc = element.computeDocumentationComment(); | |
| dartDoc = cleanDartDoc(dartDoc); | |
| if (dartDoc != null) info['dartdoc'] = dartDoc; | |
| } | |
| return info; | |
| } | |
| return null; | |
| } | |
| /// An implementation of [Source] that is based on an in-memory string. | |
| class StringSource implements Source { | |
| final String fullName; | |
| int _modificationStamp; | |
| String _contents; | |
| StringSource(this._contents, this.fullName) | |
| : _modificationStamp = new DateTime.now().millisecondsSinceEpoch; | |
| void updateSource(String newSource) { | |
| _contents = newSource; | |
| _modificationStamp = new DateTime.now().millisecondsSinceEpoch; | |
| } | |
| int get modificationStamp => _modificationStamp; | |
| bool operator ==(Object object) { | |
| if (object is StringSource) { | |
| StringSource ssObject = object; | |
| return ssObject._contents == _contents && ssObject.fullName == fullName; | |
| } | |
| return false; | |
| } | |
| bool exists() => true; | |
| TimestampedData<String> get contents => | |
| new TimestampedData(modificationStamp, _contents); | |
| String get encoding => 'utf-8'; | |
| String get shortName => fullName; | |
| UriKind get uriKind => UriKind.FILE_URI; | |
| int get hashCode => fullName.hashCode; | |
| bool get isInSystemLibrary => false; | |
| Uri get uri { | |
| throw new UnsupportedError("StringSource doesn't support uri."); | |
| } | |
| // TODO: I don't think this is generally sufficent, but it meets our purposes | |
| // here. | |
| Uri resolveRelativeUri(Uri relativeUri) { | |
| return relativeUri; | |
| } | |
| @override | |
| Source get source => this; | |
| } | |
| /** | |
| * Converts [str] from a Dartdoc string with slashes and stars to a plain text | |
| * representation of the comment. | |
| */ | |
| String cleanDartDoc(String str) { | |
| if (str == null) return null; | |
| // Remove /** */. | |
| str = str.trim(); | |
| if (str.startsWith('/**')) str = str.substring(3); | |
| if (str.endsWith("*/")) str = str.substring(0, str.length - 2); | |
| str = str.trim(); | |
| // Remove leading '* '. | |
| StringBuffer sb = new StringBuffer(); | |
| bool firstLine = true; | |
| for (String line in str.split('\n')) { | |
| line = line.trim(); | |
| // Remove leading '* ' and '///'; don't remove a leading '*' if there is a | |
| // matching '*' in the line. | |
| if (line.startsWith('* ')) { | |
| line = line.substring(2); | |
| } else if (line.startsWith("*") && line.lastIndexOf('*') == 0) { | |
| 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); | |
| } | |
| return sb.toString(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment