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

Side by Side Diff: pkg/analyzer/lib/src/summary/resynthesize.dart

Issue 2026013002: Resynthesize local functions lazily. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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 unified diff | Download patch
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/element.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library summary_resynthesizer; 5 library summary_resynthesizer;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 currentConstructor.isCycleFree = serializedExecutable.isConst && 1823 currentConstructor.isCycleFree = serializedExecutable.isConst &&
1824 !constCycles.contains(serializedExecutable.constCycleSlot); 1824 !constCycles.contains(serializedExecutable.constCycleSlot);
1825 if (serializedExecutable.name.isEmpty) { 1825 if (serializedExecutable.name.isEmpty) {
1826 currentConstructor.nameEnd = 1826 currentConstructor.nameEnd =
1827 serializedExecutable.nameOffset + classElement.name.length; 1827 serializedExecutable.nameOffset + classElement.name.length;
1828 } else { 1828 } else {
1829 currentConstructor.nameEnd = serializedExecutable.nameEnd; 1829 currentConstructor.nameEnd = serializedExecutable.nameEnd;
1830 currentConstructor.periodOffset = serializedExecutable.periodOffset; 1830 currentConstructor.periodOffset = serializedExecutable.periodOffset;
1831 } 1831 }
1832 constructors[serializedExecutable.name] = currentConstructor; 1832 constructors[serializedExecutable.name] = currentConstructor;
1833 buildExecutableCommonParts(currentConstructor, serializedExecutable);
1834 currentConstructor.constantInitializers = serializedExecutable 1833 currentConstructor.constantInitializers = serializedExecutable
1835 .constantInitializers 1834 .constantInitializers
1836 .map((i) => buildConstructorInitializer(currentConstructor, i)) 1835 .map((i) => buildConstructorInitializer(currentConstructor, i))
1837 .toList(); 1836 .toList();
1838 if (serializedExecutable.isRedirectedConstructor) { 1837 if (serializedExecutable.isRedirectedConstructor) {
1839 if (serializedExecutable.isFactory) { 1838 if (serializedExecutable.isFactory) {
1840 EntityRef redirectedConstructor = 1839 EntityRef redirectedConstructor =
1841 serializedExecutable.redirectedConstructor; 1840 serializedExecutable.redirectedConstructor;
1842 _ReferenceInfo info = getReferenceInfo(redirectedConstructor.reference); 1841 _ReferenceInfo info = getReferenceInfo(redirectedConstructor.reference);
1843 List<EntityRef> typeArguments = redirectedConstructor.typeArguments; 1842 List<EntityRef> typeArguments = redirectedConstructor.typeArguments;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1990 name = name.substring(0, name.length - 1); 1989 name = name.substring(0, name.length - 1);
1991 } 1990 }
1992 switch (kind) { 1991 switch (kind) {
1993 case UnlinkedExecutableKind.functionOrMethod: 1992 case UnlinkedExecutableKind.functionOrMethod:
1994 if (isTopLevel) { 1993 if (isTopLevel) {
1995 // Created lazily. 1994 // Created lazily.
1996 } else { 1995 } else {
1997 MethodElementImpl executableElement = 1996 MethodElementImpl executableElement =
1998 new MethodElementImpl.forSerialized( 1997 new MethodElementImpl.forSerialized(
1999 serializedExecutable, enclosingElement); 1998 serializedExecutable, enclosingElement);
2000 buildExecutableCommonParts(executableElement, serializedExecutable);
2001 holder.addMethod(executableElement); 1999 holder.addMethod(executableElement);
2002 } 2000 }
2003 break; 2001 break;
2004 case UnlinkedExecutableKind.getter: 2002 case UnlinkedExecutableKind.getter:
2005 case UnlinkedExecutableKind.setter: 2003 case UnlinkedExecutableKind.setter:
2006 // Top-level accessors are created lazily. 2004 // Top-level accessors are created lazily.
2007 if (isTopLevel) { 2005 if (isTopLevel) {
2008 break; 2006 break;
2009 } 2007 }
2010 // Class member accessors. 2008 // Class member accessors.
2011 PropertyAccessorElementImpl executableElement = 2009 PropertyAccessorElementImpl executableElement =
2012 new PropertyAccessorElementImpl.forSerialized( 2010 new PropertyAccessorElementImpl.forSerialized(
2013 serializedExecutable, enclosingElement); 2011 serializedExecutable, enclosingElement);
2014 buildExecutableCommonParts(executableElement, serializedExecutable);
2015 DartType type; 2012 DartType type;
2016 if (kind == UnlinkedExecutableKind.getter) { 2013 if (kind == UnlinkedExecutableKind.getter) {
2017 type = executableElement.returnType; 2014 type = executableElement.returnType;
2018 } else { 2015 } else {
2019 type = executableElement.parameters[0].type; 2016 type = executableElement.parameters[0].type;
2020 } 2017 }
2021 holder.addAccessor(executableElement); 2018 holder.addAccessor(executableElement);
2022 FieldElementImpl field = buildImplicitField(name, type, kind, holder); 2019 FieldElementImpl field = buildImplicitField(name, type, kind, holder);
2023 field.static = serializedExecutable.isStatic; 2020 field.static = serializedExecutable.isStatic;
2024 executableElement.variable = field; 2021 executableElement.variable = field;
2025 if (kind == UnlinkedExecutableKind.getter) { 2022 if (kind == UnlinkedExecutableKind.getter) {
2026 field.getter = executableElement; 2023 field.getter = executableElement;
2027 } else { 2024 } else {
2028 field.setter = executableElement; 2025 field.setter = executableElement;
2029 } 2026 }
2030 break; 2027 break;
2031 default: 2028 default:
2032 // The only other executable type is a constructor, and that is handled 2029 // The only other executable type is a constructor, and that is handled
2033 // separately (in [buildConstructor]. So this code should be 2030 // separately (in [buildConstructor]. So this code should be
2034 // unreachable. 2031 // unreachable.
2035 assert(false); 2032 assert(false);
2036 } 2033 }
2037 } 2034 }
2038 2035
2039 /** 2036 /**
2040 * Handle the parts of an executable element that are common to constructors,
2041 * functions, methods, getters, and setters.
2042 */
2043 void buildExecutableCommonParts(ExecutableElementImpl executableElement,
2044 UnlinkedExecutable serializedExecutable) {
2045 {
2046 List<UnlinkedExecutable> unlinkedFunctions =
2047 serializedExecutable.localFunctions;
2048 int length = unlinkedFunctions.length;
2049 if (length != 0) {
2050 List<FunctionElementImpl> localFunctions =
2051 new List<FunctionElementImpl>(length);
2052 for (int i = 0; i < length; i++) {
2053 localFunctions[i] =
2054 buildLocalFunction(unlinkedFunctions[i], executableElement);
2055 }
2056 executableElement.functions = localFunctions;
2057 }
2058 }
2059 }
2060
2061 /**
2062 * Build the implicit getter and setter associated with [element], and place 2037 * Build the implicit getter and setter associated with [element], and place
2063 * them in [holder]. 2038 * them in [holder].
2064 */ 2039 */
2065 void buildImplicitAccessors( 2040 void buildImplicitAccessors(
2066 PropertyInducingElementImpl element, ElementHolder holder) { 2041 PropertyInducingElementImpl element, ElementHolder holder) {
2067 PropertyAccessorElementImpl getter = buildImplicitGetter(element); 2042 PropertyAccessorElementImpl getter = buildImplicitGetter(element);
2068 holder?.addAccessor(getter); 2043 holder?.addAccessor(getter);
2069 if (!(element.isConst || element.isFinal)) { 2044 if (!(element.isConst || element.isFinal)) {
2070 PropertyAccessorElementImpl setter = buildImplicitSetter(element); 2045 PropertyAccessorElementImpl setter = buildImplicitSetter(element);
2071 holder?.addAccessor(setter); 2046 holder?.addAccessor(setter);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 } 2104 }
2130 EntityRef type = linkedTypeMap[slot]; 2105 EntityRef type = linkedTypeMap[slot];
2131 if (type == null) { 2106 if (type == null) {
2132 // A missing entry in [LinkedUnit.types] means there is no [DartType] 2107 // A missing entry in [LinkedUnit.types] means there is no [DartType]
2133 // stored in this slot. 2108 // stored in this slot.
2134 return null; 2109 return null;
2135 } 2110 }
2136 return buildType(type, typeParameterContext); 2111 return buildType(type, typeParameterContext);
2137 } 2112 }
2138 2113
2139 /**
2140 * Resynthesize a local [FunctionElement].
2141 */
2142 FunctionElementImpl buildLocalFunction(
2143 UnlinkedExecutable serializedExecutable, ElementImpl enclosingElement) {
2144 FunctionElementImpl element = new FunctionElementImpl.forSerialized(
2145 serializedExecutable, enclosingElement);
2146 if (serializedExecutable.visibleOffset != 0) {
2147 element.setVisibleRange(serializedExecutable.visibleOffset,
2148 serializedExecutable.visibleLength);
2149 }
2150 buildExecutableCommonParts(element, serializedExecutable);
2151 return element;
2152 }
2153
2154 List<FunctionElementImpl> buildTopLevelFunctions() { 2114 List<FunctionElementImpl> buildTopLevelFunctions() {
2155 List<FunctionElementImpl> functions = <FunctionElementImpl>[]; 2115 List<FunctionElementImpl> functions = <FunctionElementImpl>[];
2156 List<UnlinkedExecutable> executables = unlinkedUnit.executables; 2116 List<UnlinkedExecutable> executables = unlinkedUnit.executables;
2157 for (UnlinkedExecutable unlinkedExecutable in executables) { 2117 for (UnlinkedExecutable unlinkedExecutable in executables) {
2158 if (unlinkedExecutable.kind == UnlinkedExecutableKind.functionOrMethod) { 2118 if (unlinkedExecutable.kind == UnlinkedExecutableKind.functionOrMethod) {
2159 FunctionElementImpl function = 2119 FunctionElementImpl function =
2160 new FunctionElementImpl.forSerialized(unlinkedExecutable, unit); 2120 new FunctionElementImpl.forSerialized(unlinkedExecutable, unit);
2161 buildExecutableCommonParts(function, unlinkedExecutable);
2162 functions.add(function); 2121 functions.add(function);
2163 } 2122 }
2164 } 2123 }
2165 return functions; 2124 return functions;
2166 } 2125 }
2167 2126
2168 /** 2127 /**
2169 * Build a [DartType] object based on a [EntityRef]. This [DartType] 2128 * Build a [DartType] object based on a [EntityRef]. This [DartType]
2170 * may refer to elements in other libraries than the library being 2129 * may refer to elements in other libraries than the library being
2171 * deserialized, so handles are used to avoid having to deserialize other 2130 * deserialized, so handles are used to avoid having to deserialize other
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 String name = unlinkedExecutable.name; 2176 String name = unlinkedExecutable.name;
2218 if (kind == UnlinkedExecutableKind.setter) { 2177 if (kind == UnlinkedExecutableKind.setter) {
2219 assert(name.endsWith('=')); 2178 assert(name.endsWith('='));
2220 name = name.substring(0, name.length - 1); 2179 name = name.substring(0, name.length - 1);
2221 } 2180 }
2222 // create 2181 // create
2223 PropertyAccessorElementImpl accessor = 2182 PropertyAccessorElementImpl accessor =
2224 new PropertyAccessorElementImpl.forSerialized( 2183 new PropertyAccessorElementImpl.forSerialized(
2225 unlinkedExecutable, unit); 2184 unlinkedExecutable, unit);
2226 accessorsData.accessors.add(accessor); 2185 accessorsData.accessors.add(accessor);
2227 buildExecutableCommonParts(accessor, unlinkedExecutable);
2228 // implicit variable 2186 // implicit variable
2229 TopLevelVariableElementImpl variable = implicitVariables[name]; 2187 TopLevelVariableElementImpl variable = implicitVariables[name];
2230 if (variable == null) { 2188 if (variable == null) {
2231 variable = new TopLevelVariableElementImpl(name, -1); 2189 variable = new TopLevelVariableElementImpl(name, -1);
2232 variable.enclosingElement = unit; 2190 variable.enclosingElement = unit;
2233 implicitVariables[name] = variable; 2191 implicitVariables[name] = variable;
2234 accessorsData.implicitVariables.add(variable); 2192 accessorsData.implicitVariables.add(variable);
2235 variable.synthetic = true; 2193 variable.synthetic = true;
2236 variable.final2 = kind == UnlinkedExecutableKind.getter; 2194 variable.final2 = kind == UnlinkedExecutableKind.getter;
2237 } else { 2195 } else {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 /** 2266 /**
2309 * If the given [serializedInitializer] is not `null`, return the 2267 * If the given [serializedInitializer] is not `null`, return the
2310 * corresponding [FunctionElementImpl], otherwise return `null`. 2268 * corresponding [FunctionElementImpl], otherwise return `null`.
2311 */ 2269 */
2312 FunctionElementImpl buildVariableInitializer( 2270 FunctionElementImpl buildVariableInitializer(
2313 VariableElementImpl variable, UnlinkedExecutable serializedInitializer) { 2271 VariableElementImpl variable, UnlinkedExecutable serializedInitializer) {
2314 if (serializedInitializer == null) { 2272 if (serializedInitializer == null) {
2315 return null; 2273 return null;
2316 } 2274 }
2317 FunctionElementImpl initializerElement = 2275 FunctionElementImpl initializerElement =
2318 buildLocalFunction(serializedInitializer, variable); 2276 new FunctionElementImpl.forSerialized(serializedInitializer, variable);
2319 initializerElement.synthetic = true; 2277 initializerElement.synthetic = true;
2320 return initializerElement; 2278 return initializerElement;
2321 } 2279 }
2322 2280
2323 /** 2281 /**
2324 * Return [_ReferenceInfo] with the given [index], lazily resolving it. 2282 * Return [_ReferenceInfo] with the given [index], lazily resolving it.
2325 */ 2283 */
2326 _ReferenceInfo getReferenceInfo(int index) { 2284 _ReferenceInfo getReferenceInfo(int index) {
2327 _ReferenceInfo result = referenceInfos[index]; 2285 _ReferenceInfo result = referenceInfos[index];
2328 if (result == null) { 2286 if (result == null) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 static String _getElementIdentifier(String name, ReferenceKind kind) { 2486 static String _getElementIdentifier(String name, ReferenceKind kind) {
2529 if (kind == ReferenceKind.topLevelPropertyAccessor || 2487 if (kind == ReferenceKind.topLevelPropertyAccessor ||
2530 kind == ReferenceKind.propertyAccessor) { 2488 kind == ReferenceKind.propertyAccessor) {
2531 if (!name.endsWith('=')) { 2489 if (!name.endsWith('=')) {
2532 return name + '?'; 2490 return name + '?';
2533 } 2491 }
2534 } 2492 }
2535 return name; 2493 return name;
2536 } 2494 }
2537 } 2495 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/element.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698