dartk: remove uses of .computeNode

As a result, this changes the order in which declarations appear in the generated output. The new order is more consistent with the textual order in the original file.

Calling .computeNode() is sort of an anti-pattern for using analyzer. This was
however used very sparsely in dartk. The few places where it was used,
computeNode was practically called immediately after resolving the library
element, so I don't expect this to make almost any difference in performance.

R=asgerf@google.com, paulberry@google.com

Review URL: https://codereview.chromium.org/2553303002 .
This commit is contained in:
Sigmund Cherem 2016-12-07 07:42:30 -08:00
parent 6da1083953
commit f315ae1c00

View file

@ -109,8 +109,8 @@ class DartLoader implements ReferenceLevelLoader {
..fileUri = "file://${element.source.fullName}";
}
void _buildTopLevelMember(ast.Member member, Element element) {
var astNode = element.computeNode();
void _buildTopLevelMember(
ast.Member member, Element element, Declaration astNode) {
assert(member.parent != null);
new MemberBodyBuilder(this, member, element).build(astNode);
}
@ -124,45 +124,56 @@ class DartLoader implements ReferenceLevelLoader {
return _libraryBeingLoaded == element;
}
void _buildLibraryBody(LibraryElement element, ast.Library library) {
void _buildLibraryBody(LibraryElement element, ast.Library library,
List<CompilationUnit> units) {
assert(_libraryBeingLoaded == null);
_libraryBeingLoaded = element;
var classes = <ast.Class>[];
var procedures = <ast.Procedure>[];
var fields = <ast.Field>[];
void loadClass(ClassElement classElement) {
var node = getClassReference(classElement);
promoteToBodyLevel(node);
void loadClass(NamedCompilationUnitMember declaration) {
// [declaration] can be a ClassDeclaration, EnumDeclaration, or a
// ClassTypeAlias.
ClassElement element = declaration.element;
var node = getClassReference(element);
promoteToBodyLevel(node, element, declaration);
classes.add(node);
}
void loadProcedure(Element memberElement) {
var node = getMemberReference(memberElement);
_buildTopLevelMember(node, memberElement);
void loadProcedure(FunctionDeclaration declaration) {
var element = declaration.element;
var node = getMemberReference(element);
_buildTopLevelMember(node, element, declaration);
procedures.add(node);
}
void loadField(Element memberElement) {
var node = getMemberReference(memberElement);
_buildTopLevelMember(node, memberElement);
fields.add(node);
void loadField(TopLevelVariableDeclaration declaration) {
for (var field in declaration.variables.variables) {
var element = field.element;
// Ignore fields inserted through error recovery.
if (element.name == '') continue;
var node = getMemberReference(element);
_buildTopLevelMember(node, element, field);
fields.add(node);
}
}
for (var unit in element.units) {
unit.types.forEach(loadClass);
unit.enums.forEach(loadClass);
for (var accessor in unit.accessors) {
if (!accessor.isSynthetic) {
loadProcedure(accessor);
}
}
for (var function in unit.functions) {
loadProcedure(function);
}
for (var field in unit.topLevelVariables) {
// Ignore fields inserted through error recovery.
if (!field.isSynthetic && field.name != '') {
loadField(field);
for (var unit in units) {
for (CompilationUnitMember declaration in unit.declarations) {
if (declaration is ClassDeclaration ||
declaration is EnumDeclaration ||
declaration is ClassTypeAlias) {
loadClass(declaration);
} else if (declaration is FunctionDeclaration) {
loadProcedure(declaration);
} else if (declaration is TopLevelVariableDeclaration) {
loadField(declaration);
} else if (declaration is FunctionTypeAlias) {
// Nothing to do. Typedefs are handled lazily while constructing type
// references.
} else {
throw "unexpected node: ${declaration.runtimeType} $declaration";
}
}
}
@ -352,13 +363,11 @@ class DartLoader implements ReferenceLevelLoader {
}
}
void promoteToBodyLevel(ast.Class classNode) {
void promoteToBodyLevel(ast.Class classNode, ClassElement element,
NamedCompilationUnitMember astNode) {
if (classNode.level == ast.ClassLevel.Body) return;
promoteToHierarchyLevel(classNode);
classNode.level = ast.ClassLevel.Body;
var element = getClassElement(classNode);
if (element == null) return;
var astNode = element.computeNode();
// Clear out the member references that were put in the class.
// The AST builder will load them all put back in the right order.
classNode..fields.clear()..procedures.clear()..constructors.clear();
@ -585,20 +594,28 @@ class DartLoader implements ReferenceLevelLoader {
.forUri2(applicationRoot.absoluteUri(node.importUri));
assert(source != null);
var element = context.computeLibraryElement(source);
context.resolveCompilationUnit(source, element);
_buildLibraryBody(element, node);
if (node.importUri.scheme != 'dart') {
for (var unit in element.units) {
LineInfo lines;
for (var error in context.computeErrors(unit.source)) {
if (error.errorCode is CompileTimeErrorCode ||
error.errorCode is ParserErrorCode ||
error.errorCode is ScannerErrorCode ||
error.errorCode is StrongModeCode) {
lines ??= context.computeLineInfo(source);
errors.add(formatErrorMessage(error, source.shortName, lines));
}
}
var units = <CompilationUnit>[];
bool reportErrors = node.importUri.scheme != 'dart';
var tree = context.resolveCompilationUnit(source, element);
units.add(tree);
if (reportErrors) _processErrors(source);
for (var part in element.parts) {
var source = part.source;
units.add(context.resolveCompilationUnit(source, element));
if (reportErrors) _processErrors(source);
}
_buildLibraryBody(element, node, units);
}
void _processErrors(Source source) {
LineInfo lines;
for (var error in context.computeErrors(source)) {
if (error.errorCode is CompileTimeErrorCode ||
error.errorCode is ParserErrorCode ||
error.errorCode is ScannerErrorCode ||
error.errorCode is StrongModeCode) {
lines ??= context.computeLineInfo(source);
errors.add(formatErrorMessage(error, source.shortName, lines));
}
}
}
@ -655,10 +672,9 @@ class DartLoader implements ReferenceLevelLoader {
for (LibraryElement libraryElement in libraryElements) {
for (CompilationUnitElement compilationUnitElement
in libraryElement.units) {
// TODO(jensj): Get this another way?
LineInfo lineInfo = compilationUnitElement.computeNode().lineInfo;
program.uriToLineStarts[
"file://${compilationUnitElement.source.source.fullName}"] =
var source = compilationUnitElement.source;
LineInfo lineInfo = context.computeLineInfo(source);
program.uriToLineStarts["file://${source.fullName}"] =
new List<int>.generate(lineInfo.lineCount, lineInfo.getOffsetOfLine,
growable: false);
}