blob: 1bf085d53c53d9dd0215856190644fe6315f9cf6 [file] [log] [blame]
// Copyright (c) 2019, 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.
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/summary/format.dart';
/// Create informative data for nodes that need it, and set IDs of this
/// data to the nodes.
List<UnlinkedInformativeDataBuilder> createInformativeData(
CompilationUnit unit) {
var visitor = _SetInformativeId();
unit.accept(visitor);
return visitor.dataList;
}
/// If [createInformativeData] set the informative data identifier for the
/// [node], return it, otherwise return zero.
int getInformativeId(AstNode node) {
int id = node.getProperty(_SetInformativeId.ID);
return id ?? 0;
}
class _SetInformativeId extends SimpleAstVisitor<void> {
static final String ID = 'informativeId';
final List<UnlinkedInformativeDataBuilder> dataList = [];
void setData(AstNode node, UnlinkedInformativeDataBuilder data) {
var id = 1 + dataList.length;
node.setProperty(ID, id);
dataList.add(data);
}
@override
void visitClassDeclaration(ClassDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.classDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.typeParameters?.accept(this);
node.members.accept(this);
}
@override
void visitClassTypeAlias(ClassTypeAlias node) {
setData(
node,
UnlinkedInformativeDataBuilder.classTypeAlias(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.typeParameters?.accept(this);
}
@override
void visitCompilationUnit(CompilationUnit node) {
setData(
node,
UnlinkedInformativeDataBuilder.compilationUnit(
codeOffset: node.offset,
codeLength: node.length,
compilationUnit_lineStarts: node.lineInfo.lineStarts,
),
);
node.directives.accept(this);
node.declarations.accept(this);
}
@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.constructorDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name?.offset ?? 0,
constructorDeclaration_periodOffset: node.period?.offset ?? 0,
constructorDeclaration_returnTypeOffset: node.returnType.offset,
),
);
node.parameters?.accept(this);
}
@override
void visitDefaultFormalParameter(DefaultFormalParameter node) {
var defaultValueCode = node.defaultValue?.toSource();
setData(
node,
UnlinkedInformativeDataBuilder.defaultFormalParameter(
codeOffset: node.offset,
codeLength: node.length,
defaultFormalParameter_defaultValueCode: defaultValueCode,
),
);
node.parameter.accept(this);
}
@override
void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.enumConstantDeclaration(
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
}
@override
void visitEnumDeclaration(EnumDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.enumDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.constants.accept(this);
}
@override
void visitExportDirective(ExportDirective node) {
setData(
node,
UnlinkedInformativeDataBuilder.exportDirective(
directiveKeywordOffset: node.keyword.offset,
),
);
node.combinators.accept(this);
}
@override
void visitExtensionDeclaration(ExtensionDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.extensionDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name?.offset ?? 0,
),
);
node.typeParameters?.accept(this);
node.members.accept(this);
}
@override
void visitFieldDeclaration(FieldDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.fieldDeclaration(
documentationComment_tokens: _nodeCommentTokens(node),
),
);
node.fields.accept(this);
}
@override
void visitFieldFormalParameter(FieldFormalParameter node) {
setData(
node,
UnlinkedInformativeDataBuilder.fieldFormalParameter(
codeOffset: node.offset,
codeLength: node.length,
nameOffset: node.identifier.offset,
),
);
}
@override
void visitFormalParameterList(FormalParameterList node) {
node.parameters.accept(this);
}
@override
void visitFunctionDeclaration(FunctionDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.functionDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.functionExpression.accept(this);
}
@override
void visitFunctionExpression(FunctionExpression node) {
node.typeParameters?.accept(this);
node.parameters?.accept(this);
}
@override
void visitFunctionTypeAlias(FunctionTypeAlias node) {
setData(
node,
UnlinkedInformativeDataBuilder.functionTypeAlias(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.typeParameters?.accept(this);
node.parameters.accept(this);
}
@override
void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
setData(
node,
UnlinkedInformativeDataBuilder.functionTypedFormalParameter(
codeOffset: node.offset,
codeLength: node.length,
nameOffset: node.identifier.offset,
),
);
}
@override
void visitGenericFunctionType(GenericFunctionType node) {
node.typeParameters?.accept(this);
node.parameters.accept(this);
}
@override
void visitGenericTypeAlias(GenericTypeAlias node) {
setData(
node,
UnlinkedInformativeDataBuilder.genericTypeAlias(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.typeParameters?.accept(this);
node.functionType?.accept(this);
}
@override
void visitHideCombinator(HideCombinator node) {
setData(
node,
UnlinkedInformativeDataBuilder.hideCombinator(
combinatorEnd: node.end,
combinatorKeywordOffset: node.offset,
),
);
}
@override
void visitImportDirective(ImportDirective node) {
setData(
node,
UnlinkedInformativeDataBuilder.importDirective(
directiveKeywordOffset: node.keyword.offset,
importDirective_prefixOffset: node.prefix?.offset ?? 0,
),
);
node.combinators.accept(this);
}
@override
void visitLibraryDirective(LibraryDirective node) {
setData(
node,
UnlinkedInformativeDataBuilder.libraryDirective(
documentationComment_tokens: _nodeCommentTokens(node),
),
);
}
@override
void visitMethodDeclaration(MethodDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.methodDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.typeParameters?.accept(this);
node.parameters?.accept(this);
}
@override
void visitMixinDeclaration(MixinDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.mixinDeclaration(
codeOffset: node.offset,
codeLength: node.length,
documentationComment_tokens: _nodeCommentTokens(node),
nameOffset: node.name.offset,
),
);
node.typeParameters?.accept(this);
node.members.accept(this);
}
@override
void visitPartDirective(PartDirective node) {
setData(
node,
UnlinkedInformativeDataBuilder.partDirective(
directiveKeywordOffset: node.keyword.offset,
),
);
}
@override
void visitPartOfDirective(PartOfDirective node) {
setData(
node,
UnlinkedInformativeDataBuilder.partDirective(
directiveKeywordOffset: node.keyword.offset,
),
);
}
@override
void visitShowCombinator(ShowCombinator node) {
setData(
node,
UnlinkedInformativeDataBuilder.showCombinator(
combinatorEnd: node.end,
combinatorKeywordOffset: node.offset,
),
);
}
@override
void visitSimpleFormalParameter(SimpleFormalParameter node) {
setData(
node,
UnlinkedInformativeDataBuilder.simpleFormalParameter(
codeOffset: node.offset,
codeLength: node.length,
nameOffset: node.identifier?.offset ?? 0,
),
);
}
@override
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
setData(
node,
UnlinkedInformativeDataBuilder.topLevelVariableDeclaration(
documentationComment_tokens: _nodeCommentTokens(node),
),
);
node.variables.accept(this);
}
@override
void visitTypeParameter(TypeParameter node) {
setData(
node,
UnlinkedInformativeDataBuilder.typeParameter(
codeOffset: node.offset,
codeLength: node.length,
nameOffset: node.name.offset,
),
);
}
@override
void visitTypeParameterList(TypeParameterList node) {
node.typeParameters.accept(this);
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
var variableList = node.parent as VariableDeclarationList;
var isFirst = identical(variableList.variables[0], node);
var codeOffset = (isFirst ? variableList.parent : node).offset;
var codeLength = node.end - codeOffset;
setData(
node,
UnlinkedInformativeDataBuilder.variableDeclaration(
codeOffset: codeOffset,
codeLength: codeLength,
nameOffset: node.name.offset,
),
);
}
@override
void visitVariableDeclarationList(VariableDeclarationList node) {
node.variables.accept(this);
}
static List<String> _commentTokens(Comment comment) {
if (comment == null) return null;
return comment.tokens.map((token) => token.lexeme).toList();
}
static List<String> _nodeCommentTokens(AnnotatedNode node) {
return _commentTokens(node.documentationComment);
}
}