Add Member.documentationComment and use it to resynthesize documentation from Kernel.

R=ahe@google.com, brianwilkerson@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2990873002 .
This commit is contained in:
Konstantin Shcheglov 2017-07-27 15:22:44 -07:00
parent 87aaa8bdb3
commit 47ecf72272
17 changed files with 163 additions and 64 deletions

View file

@ -3974,6 +3974,9 @@ abstract class ExecutableElementImpl extends ElementImpl
@override
String get documentationComment {
if (_kernel != null) {
return _kernel.documentationComment;
}
if (serializedExecutable != null) {
return serializedExecutable?.documentationComment?.text;
}
@ -7610,6 +7613,9 @@ abstract class NonParameterVariableElementImpl extends VariableElementImpl {
@override
String get documentationComment {
if (_kernel != null) {
return _kernel.documentationComment;
}
if (_unlinkedVariable != null) {
return _unlinkedVariable?.documentationComment?.text;
}

View file

@ -307,11 +307,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_constExpr_pushReference_enum_method();
}
@failingTest
test_constructor_documented() async {
await super.test_constructor_documented();
}
@failingTest
test_constructor_initializers_assertInvocation() async {
await super.test_constructor_initializers_assertInvocation();
@ -483,11 +478,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_field_covariant();
}
@failingTest
test_field_documented() async {
await super.test_field_documented();
}
@failingTest
test_field_propagatedType_final_dep_inLib() async {
await super.test_field_propagatedType_final_dep_inLib();
@ -503,11 +493,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_field_propagatedType_final_noDep_instance();
}
@failingTest
test_function_documented() async {
await super.test_function_documented();
}
@failingTest
test_function_entry_point_in_export_hidden() async {
await super.test_function_entry_point_in_export_hidden();
@ -578,11 +563,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_getElement_unit();
}
@failingTest
test_getter_documented() async {
await super.test_getter_documented();
}
@failingTest
test_import_configurations_useDefault() async {
await super.test_import_configurations_useDefault();
@ -795,11 +775,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_metadata_simpleFormalParameter_withDefault();
}
@failingTest
test_method_documented() async {
await super.test_method_documented();
}
@failingTest
test_parameter_checked() async {
await super.test_parameter_checked();
@ -840,11 +815,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_setter_covariant();
}
@failingTest
test_setter_documented() async {
await super.test_setter_documented();
}
@failingTest
test_syntheticFunctionType_inGenericClass() async {
await super.test_syntheticFunctionType_inGenericClass();
@ -1105,11 +1075,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
await super.test_unresolved_part();
}
@failingTest
test_variable_documented() async {
await super.test_variable_documented();
}
@failingTest
test_variable_getterInLib_setterInPart() async {
await super.test_variable_getterInLib_setterInPart();

View file

@ -13,9 +13,9 @@ abstract class FieldBuilder<T> extends MemberBuilder {
final int modifiers;
FieldBuilder(
this.name, this.modifiers, LibraryBuilder compilationUnit, int charOffset)
: super(compilationUnit, charOffset);
FieldBuilder(String documentationComment, this.name, this.modifiers,
LibraryBuilder compilationUnit, int charOffset)
: super(compilationUnit, charOffset, documentationComment);
String get debugName => "FieldBuilder";

View file

@ -13,9 +13,11 @@ abstract class MemberBuilder extends ModifierBuilder {
/// library and updated later.
Builder parent;
String documentationComment;
String get name;
MemberBuilder(Builder parent, int charOffset)
MemberBuilder(Builder parent, int charOffset, this.documentationComment)
: parent = parent,
super(parent, charOffset);

View file

@ -34,6 +34,7 @@ abstract class ProcedureBuilder<T extends TypeBuilder> extends MemberBuilder {
final List<FormalParameterBuilder> formals;
ProcedureBuilder(
String documentationComment,
this.metadata,
this.modifiers,
this.returnType,
@ -42,7 +43,7 @@ abstract class ProcedureBuilder<T extends TypeBuilder> extends MemberBuilder {
this.formals,
LibraryBuilder compilationUnit,
int charOffset)
: super(compilationUnit, charOffset);
: super(compilationUnit, charOffset, documentationComment);
String get debugName => "ProcedureBuilder";

View file

@ -26,7 +26,7 @@ class DillMemberBuilder extends MemberBuilder {
DillMemberBuilder(Member member, Builder parent)
: modifiers = computeModifiers(member),
member = member,
super(parent, member.fileOffset);
super(parent, member.fileOffset, member.documentationComment);
String get debugName => "DillMemberBuilder";

View file

@ -125,9 +125,10 @@ class KernelEnumBuilder extends SourceClassBuilder
/// static const List<E> values = const <E>[id0, ..., idn-1];
/// String toString() => { 0: E.id0, . . ., n-1: E.idn-1}[index]
/// }
members["index"] = new KernelFieldBuilder(
null, intType, "index", finalMask, parent, charOffset, null, true);
members["index"] = new KernelFieldBuilder(null, null, intType, "index",
finalMask, parent, charOffset, null, true);
KernelConstructorBuilder constructorBuilder = new KernelConstructorBuilder(
null,
null,
constMask,
null,
@ -144,10 +145,19 @@ class KernelEnumBuilder extends SourceClassBuilder
constructors[""] = constructorBuilder;
int index = 0;
List<MapEntry> toStringEntries = <MapEntry>[];
KernelFieldBuilder valuesBuilder = new KernelFieldBuilder(null, listType,
"values", constMask | staticMask, parent, charOffset, null, true);
KernelFieldBuilder valuesBuilder = new KernelFieldBuilder(
null,
null,
listType,
"values",
constMask | staticMask,
parent,
charOffset,
null,
true);
members["values"] = valuesBuilder;
KernelProcedureBuilder toStringBuilder = new KernelProcedureBuilder(
null,
null,
0,
stringType,
@ -178,8 +188,16 @@ class KernelEnumBuilder extends SourceClassBuilder
constantNamesAndOffsets[i] = null;
continue;
}
KernelFieldBuilder fieldBuilder = new KernelFieldBuilder(null, selfType,
name, constMask | staticMask, parent, charOffset, null, true);
KernelFieldBuilder fieldBuilder = new KernelFieldBuilder(
null,
null,
selfType,
name,
constMask | staticMask,
parent,
charOffset,
null,
true);
members[name] = fieldBuilder;
toStringEntries.add(new MapEntry(
new IntLiteral(index), new StringLiteral("$className.$name")));

View file

@ -37,6 +37,7 @@ class KernelFieldBuilder extends FieldBuilder<Expression> {
final bool hasInitializer;
KernelFieldBuilder(
String documentationComment,
this.metadata,
this.type,
String name,
@ -47,7 +48,8 @@ class KernelFieldBuilder extends FieldBuilder<Expression> {
this.hasInitializer)
: field = new KernelField(null, fileUri: compilationUnit?.relativeFileUri)
..fileOffset = charOffset,
super(name, modifiers, compilationUnit, charOffset);
super(
documentationComment, name, modifiers, compilationUnit, charOffset);
void set initializer(Expression value) {
if (!hasInitializer && value is! NullLiteral && !isConst && !isFinal) {
@ -61,6 +63,7 @@ class KernelFieldBuilder extends FieldBuilder<Expression> {
type == null && (hasInitializer || isInstanceMember);
Field build(SourceLibraryBuilder library) {
field.documentationComment = documentationComment;
field.name ??= new Name(name, library.target);
if (type != null) {
field.type = type.build(library);

View file

@ -502,6 +502,7 @@ class KernelLibraryBuilder
@override
void addField(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
KernelTypeBuilder type,
@ -511,8 +512,16 @@ class KernelLibraryBuilder
bool hasInitializer) {
addBuilder(
name,
new KernelFieldBuilder(metadata, type, name, modifiers, this,
charOffset, initializerTokenForInference, hasInitializer),
new KernelFieldBuilder(
documentationComment,
metadata,
type,
name,
modifiers,
this,
charOffset,
initializerTokenForInference,
hasInitializer),
charOffset);
}
@ -541,6 +550,7 @@ class KernelLibraryBuilder
}
void addProcedure(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
KernelTypeBuilder returnType,
@ -562,6 +572,7 @@ class KernelLibraryBuilder
if (constructorName != null) {
name = constructorName;
procedure = new KernelConstructorBuilder(
documentationComment,
metadata,
modifiers & ~abstractMask,
returnType,
@ -575,6 +586,7 @@ class KernelLibraryBuilder
nativeMethodName);
} else {
procedure = new KernelProcedureBuilder(
documentationComment,
metadata,
modifiers,
returnType,
@ -596,6 +608,7 @@ class KernelLibraryBuilder
}
void addFactoryMethod(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
ConstructorReferenceBuilder constructorNameReference,
@ -618,6 +631,7 @@ class KernelLibraryBuilder
}
assert(constructorNameReference.suffix == null);
KernelProcedureBuilder procedure = new KernelProcedureBuilder(
documentationComment,
metadata,
staticMask | modifiers,
returnType,

View file

@ -81,6 +81,7 @@ abstract class KernelFunctionBuilder
Statement actualBody;
KernelFunctionBuilder(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
KernelTypeBuilder returnType,
@ -90,8 +91,8 @@ abstract class KernelFunctionBuilder
KernelLibraryBuilder compilationUnit,
int charOffset,
this.nativeMethodName)
: super(metadata, modifiers, returnType, name, typeVariables, formals,
compilationUnit, charOffset);
: super(documentationComment, metadata, modifiers, returnType, name,
typeVariables, formals, compilationUnit, charOffset);
void set body(Statement newBody) {
if (newBody != null) {
@ -207,6 +208,7 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
final ConstructorReferenceBuilder redirectionTarget;
KernelProcedureBuilder(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
KernelTypeBuilder returnType,
@ -224,8 +226,17 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
fileUri: compilationUnit?.relativeFileUri)
..fileOffset = charOffset
..fileEndOffset = charEndOffset,
super(metadata, modifiers, returnType, name, typeVariables, formals,
compilationUnit, charOffset, nativeMethodName);
super(
documentationComment,
metadata,
modifiers,
returnType,
name,
typeVariables,
formals,
compilationUnit,
charOffset,
nativeMethodName);
ProcedureKind get kind => procedure.kind;
@ -276,6 +287,7 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
procedure.isExternal = isExternal;
procedure.isConst = isConst;
procedure.name = new Name(name, library.target);
procedure.documentationComment = documentationComment;
}
if (isEligibleForTopLevelInference) {
library.loader.typeInferenceEngine.recordMember(procedure);
@ -310,6 +322,7 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
RedirectingInitializer redirectingInitializer;
KernelConstructorBuilder(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
KernelTypeBuilder returnType,
@ -324,8 +337,17 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
: constructor = new Constructor(null)
..fileOffset = charOffset
..fileEndOffset = charEndOffset,
super(metadata, modifiers, returnType, name, typeVariables, formals,
compilationUnit, charOffset, nativeMethodName);
super(
documentationComment,
metadata,
modifiers,
returnType,
name,
typeVariables,
formals,
compilationUnit,
charOffset,
nativeMethodName);
bool get isInstanceMember => false;
@ -348,6 +370,7 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
constructor.isConst = isConst;
constructor.isExternal = isExternal;
constructor.name = new Name(name, library.target);
constructor.documentationComment = documentationComment;
}
return constructor;
}

View file

@ -331,8 +331,19 @@ class KernelTarget extends TargetImplementation {
// method. Similarly considerations apply to separate compilation. It
// could also make sense to add a way to mark .dill files as having
// compile-time errors.
KernelProcedureBuilder mainBuilder = new KernelProcedureBuilder(null, 0,
null, "main", null, null, ProcedureKind.Method, library, -1, -1, -1);
KernelProcedureBuilder mainBuilder = new KernelProcedureBuilder(
null,
null,
0,
null,
"main",
null,
null,
ProcedureKind.Method,
library,
-1,
-1,
-1);
library.addBuilder(mainBuilder.name, mainBuilder, -1);
mainBuilder.body = new Block(new List<Statement>.from(errors.map(
(LocatedMessage message) => new ExpressionStatement(new Throw(

View file

@ -328,8 +328,10 @@ class OutlineBuilder extends UnhandledListener {
int modifiers =
Modifier.validate(pop(), isAbstract: kind == MethodBody.Abstract);
List<MetadataBuilder> metadata = pop();
String documentationComment = _getDocumentationComment(beginToken);
checkEmpty(beginToken.charOffset);
library.addProcedure(
documentationComment,
metadata,
modifiers,
returnType,
@ -429,7 +431,9 @@ class OutlineBuilder extends UnhandledListener {
modifiers &= ~abstractMask;
}
List<MetadataBuilder> metadata = pop();
String documentationComment = _getDocumentationComment(beginToken);
library.addProcedure(
documentationComment,
metadata,
modifiers,
returnType,
@ -722,7 +726,9 @@ class OutlineBuilder extends UnhandledListener {
TypeBuilder type = pop();
int modifiers = Modifier.validate(pop());
List<MetadataBuilder> metadata = pop();
library.addFields(metadata, modifiers, type, fieldsInfo);
String documentationComment = _getDocumentationComment(beginToken);
library.addFields(
documentationComment, metadata, modifiers, type, fieldsInfo);
checkEmpty(beginToken.charOffset);
}
@ -733,7 +739,9 @@ class OutlineBuilder extends UnhandledListener {
TypeBuilder type = pop();
int modifiers = Modifier.validate(pop());
List<MetadataBuilder> metadata = pop();
library.addFields(metadata, modifiers, type, fieldsInfo);
String documentationComment = _getDocumentationComment(beginToken);
library.addFields(
documentationComment, metadata, modifiers, type, fieldsInfo);
}
@override
@ -793,7 +801,9 @@ class OutlineBuilder extends UnhandledListener {
var name = pop();
int modifiers = Modifier.validate(pop());
List<MetadataBuilder> metadata = pop();
String documentationComment = _getDocumentationComment(beginToken);
library.addFactoryMethod(
documentationComment,
metadata,
modifiers,
name,

View file

@ -219,6 +219,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
int charOffset);
void addField(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
T type,
@ -227,8 +228,8 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
Token initializerTokenForInference,
bool hasInitializer);
void addFields(List<MetadataBuilder> metadata, int modifiers, T type,
List<Object> fieldsInfo) {
void addFields(String documentationComment, List<MetadataBuilder> metadata,
int modifiers, T type, List<Object> fieldsInfo) {
for (int i = 0; i < fieldsInfo.length; i += 4) {
String name = fieldsInfo[i];
int charOffset = fieldsInfo[i + 1];
@ -239,12 +240,13 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
Token beforeLast = fieldsInfo[i + 3];
beforeLast.setNext(new Token.eof(beforeLast.next.offset));
}
addField(metadata, modifiers, type, name, charOffset,
initializerTokenForInference, hasInitializer);
addField(documentationComment, metadata, modifiers, type, name,
charOffset, initializerTokenForInference, hasInitializer);
}
}
void addProcedure(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
T returnType,
@ -275,6 +277,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
int charOffset);
void addFactoryMethod(
String documentationComment,
List<MetadataBuilder> metadata,
int modifiers,
ConstructorReferenceBuilder name,

View file

@ -860,6 +860,10 @@ abstract class Member extends NamedNode {
/// (this is the default if none is specifically set).
int fileEndOffset = TreeNode.noOffset;
/// Documentation comment of the member, or `null`.
@informative
String documentationComment;
/// List of metadata annotations on the member.
///
/// This defaults to an immutable empty list. Use [addAnnotation] to add

View file

@ -532,6 +532,7 @@ class BinaryBuilder {
readUInt(); // parent class binary offset.
var name = readName();
var fileUri = readUriReference();
var documentationComment = readStringOrNullIfEmpty();
var annotations = readAnnotationList(node);
debugPath.add(node.name?.name ?? 'field');
var type = readDartType();
@ -544,6 +545,7 @@ class BinaryBuilder {
node.flags = flags;
node.name = name;
node.fileUri = fileUri;
node.documentationComment = documentationComment;
node.annotations = annotations;
node.type = type;
node.initializer = initializer;
@ -568,6 +570,7 @@ class BinaryBuilder {
var flags = readByte();
readUInt(); // parent class binary offset.
var name = readName();
var documentationComment = readStringOrNullIfEmpty();
var annotations = readAnnotationList(node);
debugPath.add(node.name?.name ?? 'constructor');
var function = readFunctionNode();
@ -586,6 +589,7 @@ class BinaryBuilder {
node.fileEndOffset = fileEndOffset;
node.flags = flags;
node.name = name;
node.documentationComment = documentationComment;
node.annotations = annotations;
node.function = function..parent = node;
node.transformerFlags = transformerFlags;
@ -611,6 +615,7 @@ class BinaryBuilder {
readUInt(); // parent class binary offset.
var name = readName();
var fileUri = readUriReference();
var documentationComment = readStringOrNullIfEmpty();
var annotations = readAnnotationList(node);
debugPath.add(node.name?.name ?? 'procedure');
var function = readFunctionNodeOption();
@ -623,6 +628,7 @@ class BinaryBuilder {
node.flags = flags;
node.name = name;
node.fileUri = fileUri;
node.documentationComment = documentationComment;
node.annotations = annotations;
node.function = function;
node.function?.parent = node;

View file

@ -420,6 +420,7 @@ class BinaryPrinter extends Visitor {
Class parent = node.parent;
writeUInt30(parent.binaryOffset);
writeName(node.name ?? _emptyName);
writeStringReference(node.documentationComment ?? '');
writeAnnotationList(node.annotations);
assert(node.function.typeParameters.isEmpty);
writeNode(node.function);
@ -449,6 +450,7 @@ class BinaryPrinter extends Visitor {
}
writeName(node.name ?? '');
writeUriReference(node.fileUri ?? '');
writeStringReference(node.documentationComment ?? '');
writeAnnotationList(node.annotations);
writeOptionalNode(node.function);
_variableIndexer = null;
@ -472,6 +474,7 @@ class BinaryPrinter extends Visitor {
}
writeName(node.name);
writeUriReference(node.fileUri ?? '');
writeStringReference(node.documentationComment ?? '');
writeAnnotationList(node.annotations);
writeNode(node.type);
writeOptionalNode(node.initializer);
@ -1375,11 +1378,29 @@ class StringIndexer extends RecursiveVisitor<Null> {
node.visitChildren(this);
}
@override
visitConstructor(Constructor node) {
putOptional(node.documentationComment);
super.visitConstructor(node);
}
@override
visitField(Field node) {
putOptional(node.documentationComment);
super.visitField(node);
}
visitNamedExpression(NamedExpression node) {
put(node.name);
node.visitChildren(this);
}
@override
visitProcedure(Procedure node) {
putOptional(node.documentationComment);
super.visitProcedure(node);
}
visitStringLiteral(StringLiteral node) {
put(node.value);
}

View file

@ -860,6 +860,7 @@ class FieldHelper {
kParentClassBinaryOffset,
kName,
kSourceUriIndex,
kDocumentationCommentIndex,
kAnnotations,
kType,
kInitializer,
@ -919,6 +920,9 @@ class FieldHelper {
builder_->record_token_position(position_);
builder_->record_token_position(end_position_);
if (++next_read_ == field) return;
case kDocumentationCommentIndex:
builder_->ReadStringReference();
if (++next_read_ == field) return;
case kAnnotations: {
annotation_count_ = builder_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {
@ -1009,6 +1013,7 @@ class ProcedureHelper {
kParentClassBinaryOffset,
kName,
kSourceUriIndex,
kDocumentationCommentIndex,
kAnnotations,
kFunction,
kEnd
@ -1063,6 +1068,9 @@ class ProcedureHelper {
builder_->record_token_position(position_);
builder_->record_token_position(end_position_);
if (++next_read_ == field) return;
case kDocumentationCommentIndex:
builder_->ReadStringReference();
if (++next_read_ == field) return;
case kAnnotations: {
annotation_count_ = builder_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {
@ -1129,6 +1137,7 @@ class ConstructorHelper {
kFlags,
kParentClassBinaryOffset,
kName,
kDocumentationCommentIndex,
kAnnotations,
kFunction,
kInitializers,
@ -1174,6 +1183,9 @@ class ConstructorHelper {
case kName:
builder_->SkipName(); // read name.
if (++next_read_ == field) return;
case kDocumentationCommentIndex:
builder_->ReadStringReference();
if (++next_read_ == field) return;
case kAnnotations: {
annotation_count_ = builder_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {