OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |