Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: pkg/analyzer/lib/src/summary/resynthesize.dart

Issue 1969943002: Resynthesize _DeferredClassElement lazily. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/summary/resynthesize.dart
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index acc6ff386016ec9daf51c68dea22901a562ebe0f..e88339c17db2b13ab199faefbebce2be8a14a8e5 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -714,6 +714,12 @@ class _DeferredClassElement extends ClassElementHandle {
ClassElementImpl _actualElement;
+ /**
+ * We don't resynthesize executables of classes until they are requested.
Paul Berry 2016/05/11 22:09:37 Nit: based on the name, I made the incorrect assum
+ * TODO(scheglov) Check whether we need separate flags for separate kinds.
+ */
+ bool _hasExecutables = false;
+
@override
final String name;
@@ -733,15 +739,27 @@ class _DeferredClassElement extends ClassElementHandle {
: super(null, location);
@override
+ List<PropertyAccessorElement> get accessors {
+ _ensureExecutables();
+ return actualElement.accessors;
+ }
+
+ @override
ClassElementImpl get actualElement {
if (_actualElement == null) {
- _actualElement = unitResynthesizer.buildClassImpl(serializedClass);
+ _actualElement = unitResynthesizer.buildClassImpl(serializedClass, this);
_actualElement.enclosingElement = unitElement;
}
return _actualElement;
}
@override
+ List<ConstructorElement> get constructors {
+ _ensureExecutables();
+ return actualElement.constructors;
+ }
+
+ @override
AnalysisContext get context => unitElement.context;
@override
@@ -751,6 +769,42 @@ class _DeferredClassElement extends ClassElementHandle {
CompilationUnitElement get enclosingElement {
return unitElement;
}
+
+ @override
+ List<MethodElement> get methods {
+ _ensureExecutables();
+ return actualElement.methods;
+ }
+
+ @override
+ void ensureAccessorsReady() {
+ _ensureExecutables();
+ }
+
+ @override
+ void ensureActualElementComplete() {
+ _ensureExecutables();
+ }
+
+ @override
+ void ensureConstructorsReady() {
+ _ensureExecutables();
+ }
+
+ @override
+ void ensureMethodsReady() {
+ _ensureExecutables();
+ }
+
+ /**
+ * Ensure that we have [actualElement], and it has all executables.
+ */
+ void _ensureExecutables() {
+ if (!_hasExecutables) {
+ _hasExecutables = true;
+ unitResynthesizer.buildClassExecutables(actualElement, serializedClass);
+ }
+ }
}
/**
@@ -1610,7 +1664,7 @@ class _UnitResynthesizer {
ClassElement classElement;
if (libraryResynthesizer.isCoreLibrary &&
serializedClass.supertype == null) {
- classElement = buildClassImpl(serializedClass);
+ classElement = buildClassImpl(serializedClass, null);
if (!serializedClass.hasNoSupertype) {
libraryResynthesizer.delayedObjectSubclasses.add(classElement);
}
@@ -1621,25 +1675,11 @@ class _UnitResynthesizer {
}
/**
- * Resynthesize a [ClassElementImpl].
+ * Fill the given [ClassElementImpl] with executable elements and fields.
*/
- ClassElementImpl buildClassImpl(UnlinkedClass serializedClass) {
- ClassElementImpl classElement =
- new ClassElementImpl(serializedClass.name, serializedClass.nameOffset);
- classElement.hasBeenInferred = summaryResynthesizer.strongMode;
- classElement.typeParameters =
- buildTypeParameters(serializedClass.typeParameters);
- classElement.abstract = serializedClass.isAbstract;
- classElement.mixinApplication = serializedClass.isMixinApplication;
- InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
- if (serializedClass.supertype != null) {
- classElement.supertype = buildType(serializedClass.supertype);
- } else if (!libraryResynthesizer.isCoreLibrary) {
- classElement.supertype = typeProvider.objectType;
- }
- classElement.interfaces =
- serializedClass.interfaces.map(buildType).toList();
- classElement.mixins = serializedClass.mixins.map(buildType).toList();
+ void buildClassExecutables(
+ ClassElementImpl classElement, UnlinkedClass serializedClass) {
+ currentTypeParameters.add(classElement.typeParameters);
ElementHolder memberHolder = new ElementHolder();
fields = <String, FieldElementImpl>{};
for (UnlinkedVariable serializedVariable in serializedClass.fields) {
@@ -1653,7 +1693,7 @@ class _UnitResynthesizer {
case UnlinkedExecutableKind.constructor:
constructorFound = true;
buildConstructor(
- serializedExecutable, memberHolder, correspondingType);
+ serializedExecutable, memberHolder, classElement.type);
break;
case UnlinkedExecutableKind.functionOrMethod:
case UnlinkedExecutableKind.getter:
@@ -1673,7 +1713,7 @@ class _UnitResynthesizer {
// Synthesize implicit constructors.
ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
constructor.synthetic = true;
- constructor.returnType = correspondingType;
+ constructor.returnType = classElement.type;
constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
constructor, null, getCurrentTypeArguments(), false);
memberHolder.addConstructor(constructor);
@@ -1683,14 +1723,47 @@ class _UnitResynthesizer {
classElement.accessors = memberHolder.accessors;
classElement.fields = memberHolder.fields;
classElement.methods = memberHolder.methods;
+ resolveConstructorInitializers(classElement);
+ currentTypeParameters.removeLast();
+ assert(currentTypeParameters.isEmpty);
+ }
+
+ /**
+ * Resynthesize a [ClassElementImpl]. If [handle] is not `null`, then
+ * executables are not resynthesized, and [InterfaceTypeImpl] is created
+ * around the [handle], so that executables are resynthesized lazily.
+ */
+ ClassElementImpl buildClassImpl(
+ UnlinkedClass serializedClass, ClassElementHandle handle) {
+ ClassElementImpl classElement =
+ new ClassElementImpl(serializedClass.name, serializedClass.nameOffset);
+ classElement.hasBeenInferred = summaryResynthesizer.strongMode;
+ classElement.typeParameters =
+ buildTypeParameters(serializedClass.typeParameters);
+ classElement.abstract = serializedClass.isAbstract;
+ classElement.mixinApplication = serializedClass.isMixinApplication;
+ InterfaceTypeImpl correspondingType =
+ new InterfaceTypeImpl(handle ?? classElement);
+ if (serializedClass.supertype != null) {
+ classElement.supertype = buildType(serializedClass.supertype);
+ } else if (!libraryResynthesizer.isCoreLibrary) {
+ classElement.supertype = typeProvider.objectType;
+ }
+ classElement.interfaces =
+ serializedClass.interfaces.map(buildType).toList();
+ classElement.mixins = serializedClass.mixins.map(buildType).toList();
correspondingType.typeArguments = getCurrentTypeArguments();
classElement.type = correspondingType;
buildDocumentation(classElement, serializedClass.documentationComment);
buildAnnotations(classElement, serializedClass.annotations);
buildCodeRange(classElement, serializedClass.codeRange);
- resolveConstructorInitializers(classElement);
currentTypeParameters.removeLast();
assert(currentTypeParameters.isEmpty);
+ // TODO(scheglov) Somehow Observatory shows too much time spent here
+ // during DDC run on the large codebase. I would expect only Object here.
+ if (handle == null) {
+ buildClassExecutables(classElement, serializedClass);
+ }
fields = null;
constructors = null;
return classElement;

Powered by Google App Engine
This is Rietveld 408576698