blob: 203043a1b9528b1f147f23169e124e1851c96334 [file] [log] [blame]
// Copyright (c) 2015, 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 analyzer.src.summary.public_namespace_visitor;
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
/**
* Compute the public namespace portion of the summary for the given [unit],
* which is presumed to be an unresolved AST.
*/
UnlinkedPublicNamespaceBuilder computePublicNamespace(CompilationUnit unit) {
_PublicNamespaceVisitor visitor = new _PublicNamespaceVisitor();
unit.accept(visitor);
return new UnlinkedPublicNamespaceBuilder(
names: visitor.names, exports: visitor.exports, parts: visitor.parts);
}
/**
* Serialize a [Configuration] into a [UnlinkedConfigurationBuilder].
*/
UnlinkedConfigurationBuilder serializeConfiguration(
Configuration configuration) {
return new UnlinkedConfigurationBuilder(
name: configuration.name.components.map((i) => i.name).join('.'),
value: configuration.value?.stringValue ?? 'true',
uri: configuration.uri.stringValue);
}
class _CombinatorEncoder extends SimpleAstVisitor<UnlinkedCombinatorBuilder> {
_CombinatorEncoder();
List<String> encodeNames(NodeList<SimpleIdentifier> names) =>
names.map((SimpleIdentifier id) => id.name).toList();
@override
UnlinkedCombinatorBuilder visitHideCombinator(HideCombinator node) {
return new UnlinkedCombinatorBuilder(hides: encodeNames(node.hiddenNames));
}
@override
UnlinkedCombinatorBuilder visitShowCombinator(ShowCombinator node) {
return new UnlinkedCombinatorBuilder(
shows: encodeNames(node.shownNames),
offset: node.offset,
end: node.end);
}
}
class _PublicNamespaceVisitor extends RecursiveAstVisitor {
final List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
final List<UnlinkedExportPublicBuilder> exports =
<UnlinkedExportPublicBuilder>[];
final List<String> parts = <String>[];
_PublicNamespaceVisitor();
UnlinkedPublicNameBuilder addNameIfPublic(
String name, ReferenceKind kind, int numTypeParameters) {
if (isPublic(name)) {
UnlinkedPublicNameBuilder b = new UnlinkedPublicNameBuilder(
name: name, kind: kind, numTypeParameters: numTypeParameters);
names.add(b);
return b;
}
return null;
}
bool isPublic(String name) => !name.startsWith('_');
@override
visitClassDeclaration(ClassDeclaration node) {
UnlinkedPublicNameBuilder cls = addNameIfPublic(
node.name.name,
ReferenceKind.classOrEnum,
node.typeParameters?.typeParameters?.length ?? 0);
if (cls != null) {
for (ClassMember member in node.members) {
if (member is FieldDeclaration && member.isStatic) {
for (VariableDeclaration field in member.fields.variables) {
String name = field.name.name;
if (isPublic(name)) {
cls.members.add(new UnlinkedPublicNameBuilder(
name: name,
kind: ReferenceKind.propertyAccessor,
numTypeParameters: 0));
}
}
}
if (member is MethodDeclaration &&
member.isStatic &&
!member.isSetter &&
!member.isOperator) {
String name = member.name.name;
if (isPublic(name)) {
cls.members.add(new UnlinkedPublicNameBuilder(
name: name,
kind: member.isGetter
? ReferenceKind.propertyAccessor
: ReferenceKind.method,
numTypeParameters:
member.typeParameters?.typeParameters?.length ?? 0));
}
}
if (member is ConstructorDeclaration && member.name != null) {
String name = member.name.name;
if (isPublic(name)) {
cls.members.add(new UnlinkedPublicNameBuilder(
name: name,
kind: ReferenceKind.constructor,
numTypeParameters: 0));
}
}
}
}
}
@override
visitClassTypeAlias(ClassTypeAlias node) {
addNameIfPublic(node.name.name, ReferenceKind.classOrEnum,
node.typeParameters?.typeParameters?.length ?? 0);
}
@override
visitEnumDeclaration(EnumDeclaration node) {
UnlinkedPublicNameBuilder enm =
addNameIfPublic(node.name.name, ReferenceKind.classOrEnum, 0);
if (enm != null) {
enm.members.add(new UnlinkedPublicNameBuilder(
name: 'values',
kind: ReferenceKind.propertyAccessor,
numTypeParameters: 0));
for (EnumConstantDeclaration enumConstant in node.constants) {
String name = enumConstant.name.name;
if (isPublic(name)) {
enm.members.add(new UnlinkedPublicNameBuilder(
name: name,
kind: ReferenceKind.propertyAccessor,
numTypeParameters: 0));
}
}
}
}
@override
visitExportDirective(ExportDirective node) {
exports.add(new UnlinkedExportPublicBuilder(
uri: node.uri.stringValue,
combinators: node.combinators
.map((Combinator c) => c.accept(new _CombinatorEncoder()))
.toList(),
configurations:
node.configurations.map(serializeConfiguration).toList()));
}
@override
visitFunctionDeclaration(FunctionDeclaration node) {
String name = node.name.name;
if (node.isSetter) {
name += '=';
}
addNameIfPublic(
name,
node.isGetter || node.isSetter
? ReferenceKind.topLevelPropertyAccessor
: ReferenceKind.topLevelFunction,
node.functionExpression.typeParameters?.typeParameters?.length ?? 0);
}
@override
visitFunctionTypeAlias(FunctionTypeAlias node) {
addNameIfPublic(node.name.name, ReferenceKind.typedef,
node.typeParameters?.typeParameters?.length ?? 0);
}
@override
visitPartDirective(PartDirective node) {
parts.add(node.uri.stringValue ?? '');
}
@override
visitVariableDeclaration(VariableDeclaration node) {
String name = node.name.name;
addNameIfPublic(name, ReferenceKind.topLevelPropertyAccessor, 0);
if (!node.isFinal && !node.isConst) {
addNameIfPublic('$name=', ReferenceKind.topLevelPropertyAccessor, 0);
}
}
}