Index: pkg/kernel/lib/analyzer/loader.dart |
diff --git a/pkg/kernel/lib/analyzer/loader.dart b/pkg/kernel/lib/analyzer/loader.dart |
index fb523000daa7dfbe3c33803eee39bcfd0881b10f..ae169260ea99300157ce6e8bd8f436305648dfc9 100644 |
--- a/pkg/kernel/lib/analyzer/loader.dart |
+++ b/pkg/kernel/lib/analyzer/loader.dart |
@@ -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); |
} |