Skip to content

Instantly share code, notes, and snippets.

@kasperpeulen
Created August 3, 2015 23:54
Show Gist options
  • Select an option

  • Save kasperpeulen/098ce711aa8e362cc366 to your computer and use it in GitHub Desktop.

Select an option

Save kasperpeulen/098ce711aa8e362cc366 to your computer and use it in GitHub Desktop.
Alginment is off after newline
// 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