| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 class World { | 7 class World { |
| 8 final Compiler compiler; | 8 final Compiler compiler; |
| 9 final FunctionSet allFunctions; | 9 final FunctionSet allFunctions; |
| 10 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 10 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 Set<ClassElement> classes = subclassesOf(cls); | 134 Set<ClassElement> classes = subclassesOf(cls); |
| 135 return classes != null && !classes.isEmpty; | 135 return classes != null && !classes.isEmpty; |
| 136 } | 136 } |
| 137 | 137 |
| 138 bool hasAnySubtype(ClassElement cls) { | 138 bool hasAnySubtype(ClassElement cls) { |
| 139 Set<ClassElement> classes = subtypesOf(cls); | 139 Set<ClassElement> classes = subtypesOf(cls); |
| 140 return classes != null && !classes.isEmpty; | 140 return classes != null && !classes.isEmpty; |
| 141 } | 141 } |
| 142 | 142 |
| 143 bool hasAnyUserDefinedGetter(Selector selector) { | 143 bool hasAnyUserDefinedGetter(Selector selector) { |
| 144 return allFunctions.filter(selector).any((each) => each.isGetter()); | 144 return allFunctions.filter(selector).any((each) => each.isGetter); |
| 145 } | 145 } |
| 146 | 146 |
| 147 // Returns whether a subclass of [superclass] implements [type]. | 147 // Returns whether a subclass of [superclass] implements [type]. |
| 148 bool hasAnySubclassThatImplements(ClassElement superclass, | 148 bool hasAnySubclassThatImplements(ClassElement superclass, |
| 149 ClassElement type) { | 149 ClassElement type) { |
| 150 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); | 150 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| 151 if (subclasses == null) return false; | 151 if (subclasses == null) return false; |
| 152 return subclasses.contains(type); | 152 return subclasses.contains(type); |
| 153 } | 153 } |
| 154 | 154 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 173 Set<ClassElement> subtypes = subtypesOf(supertype); | 173 Set<ClassElement> subtypes = subtypesOf(supertype); |
| 174 return subtypes != null && subtypes.contains(test.declaration); | 174 return subtypes != null && subtypes.contains(test.declaration); |
| 175 } | 175 } |
| 176 | 176 |
| 177 bool isSubclass(ClassElement superclass, ClassElement test) { | 177 bool isSubclass(ClassElement superclass, ClassElement test) { |
| 178 Set<ClassElement> subclasses = subclassesOf(superclass); | 178 Set<ClassElement> subclasses = subclassesOf(superclass); |
| 179 return subclasses != null && subclasses.contains(test.declaration); | 179 return subclasses != null && subclasses.contains(test.declaration); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void registerUsedElement(Element element) { | 182 void registerUsedElement(Element element) { |
| 183 if (element.isInstanceMember() && !element.isAbstract) { | 183 if (element.isInstanceMember && !element.isAbstract) { |
| 184 allFunctions.add(element); | 184 allFunctions.add(element); |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 | 187 |
| 188 VariableElement locateSingleField(Selector selector) { | 188 VariableElement locateSingleField(Selector selector) { |
| 189 Element result = locateSingleElement(selector); | 189 Element result = locateSingleElement(selector); |
| 190 return (result != null && result.isField()) ? result : null; | 190 return (result != null && result.isField) ? result : null; |
| 191 } | 191 } |
| 192 | 192 |
| 193 Element locateSingleElement(Selector selector) { | 193 Element locateSingleElement(Selector selector) { |
| 194 ti.TypeMask mask = selector.mask == null | 194 ti.TypeMask mask = selector.mask == null |
| 195 ? new ti.TypeMask.subclass(compiler.objectClass) | 195 ? new ti.TypeMask.subclass(compiler.objectClass) |
| 196 : selector.mask; | 196 : selector.mask; |
| 197 return mask.locateSingleElement(selector, compiler); | 197 return mask.locateSingleElement(selector, compiler); |
| 198 } | 198 } |
| 199 | 199 |
| 200 void addFunctionCalledInLoop(Element element) { | 200 void addFunctionCalledInLoop(Element element) { |
| 201 functionsCalledInLoop.add(element.declaration); | 201 functionsCalledInLoop.add(element.declaration); |
| 202 } | 202 } |
| 203 | 203 |
| 204 bool isCalledInLoop(Element element) { | 204 bool isCalledInLoop(Element element) { |
| 205 return functionsCalledInLoop.contains(element.declaration); | 205 return functionsCalledInLoop.contains(element.declaration); |
| 206 } | 206 } |
| 207 | 207 |
| 208 bool fieldNeverChanges(Element element) { | 208 bool fieldNeverChanges(Element element) { |
| 209 if (!element.isField()) return false; | 209 if (!element.isField) return false; |
| 210 if (element.isNative()) { | 210 if (element.isNative) { |
| 211 // Some native fields are views of data that may be changed by operations. | 211 // Some native fields are views of data that may be changed by operations. |
| 212 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). | 212 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). |
| 213 // TODO(sra): Refine the effect classification so that native effects are | 213 // TODO(sra): Refine the effect classification so that native effects are |
| 214 // distinct from ordinary Dart effects. | 214 // distinct from ordinary Dart effects. |
| 215 return false; | 215 return false; |
| 216 } | 216 } |
| 217 | 217 |
| 218 return element.modifiers.isFinal() | 218 return element.modifiers.isFinal |
| 219 || element.modifiers.isConst() | 219 || element.modifiers.isConst |
| 220 || (element.isInstanceMember() | 220 || (element.isInstanceMember |
| 221 && !compiler.resolverWorld.hasInvokedSetter(element, compiler)); | 221 && !compiler.resolverWorld.hasInvokedSetter(element, compiler)); |
| 222 } | 222 } |
| 223 | 223 |
| 224 SideEffects getSideEffectsOfElement(Element element) { | 224 SideEffects getSideEffectsOfElement(Element element) { |
| 225 // The type inferrer (where the side effects are being computed), | 225 // The type inferrer (where the side effects are being computed), |
| 226 // does not see generative constructor bodies because they are | 226 // does not see generative constructor bodies because they are |
| 227 // created by the backend. Also, it does not make any distinction | 227 // created by the backend. Also, it does not make any distinction |
| 228 // between a constructor and its body for side effects. This | 228 // between a constructor and its body for side effects. This |
| 229 // implies that currently, the side effects of a constructor body | 229 // implies that currently, the side effects of a constructor body |
| 230 // contain the side effects of the initializers. | 230 // contain the side effects of the initializers. |
| 231 assert(!element.isGenerativeConstructorBody()); | 231 assert(!element.isGenerativeConstructorBody); |
| 232 assert(!element.isField()); | 232 assert(!element.isField); |
| 233 return sideEffects.putIfAbsent(element.declaration, () { | 233 return sideEffects.putIfAbsent(element.declaration, () { |
| 234 return new SideEffects(); | 234 return new SideEffects(); |
| 235 }); | 235 }); |
| 236 } | 236 } |
| 237 | 237 |
| 238 void registerSideEffects(Element element, SideEffects effects) { | 238 void registerSideEffects(Element element, SideEffects effects) { |
| 239 if (sideEffectsFreeElements.contains(element)) return; | 239 if (sideEffectsFreeElements.contains(element)) return; |
| 240 sideEffects[element.declaration] = effects; | 240 sideEffects[element.declaration] = effects; |
| 241 } | 241 } |
| 242 | 242 |
| 243 void registerSideEffectsFree(Element element) { | 243 void registerSideEffectsFree(Element element) { |
| 244 sideEffects[element.declaration] = new SideEffects.empty(); | 244 sideEffects[element.declaration] = new SideEffects.empty(); |
| 245 sideEffectsFreeElements.add(element); | 245 sideEffectsFreeElements.add(element); |
| 246 } | 246 } |
| 247 | 247 |
| 248 SideEffects getSideEffectsOfSelector(Selector selector) { | 248 SideEffects getSideEffectsOfSelector(Selector selector) { |
| 249 // We're not tracking side effects of closures. | 249 // We're not tracking side effects of closures. |
| 250 if (selector.isClosureCall()) return new SideEffects(); | 250 if (selector.isClosureCall) return new SideEffects(); |
| 251 SideEffects sideEffects = new SideEffects.empty(); | 251 SideEffects sideEffects = new SideEffects.empty(); |
| 252 for (Element e in allFunctions.filter(selector)) { | 252 for (Element e in allFunctions.filter(selector)) { |
| 253 if (e.isField()) { | 253 if (e.isField) { |
| 254 if (selector.isGetter()) { | 254 if (selector.isGetter) { |
| 255 if (!fieldNeverChanges(e)) { | 255 if (!fieldNeverChanges(e)) { |
| 256 sideEffects.setDependsOnInstancePropertyStore(); | 256 sideEffects.setDependsOnInstancePropertyStore(); |
| 257 } | 257 } |
| 258 } else if (selector.isSetter()) { | 258 } else if (selector.isSetter) { |
| 259 sideEffects.setChangesInstanceProperty(); | 259 sideEffects.setChangesInstanceProperty(); |
| 260 } else { | 260 } else { |
| 261 assert(selector.isCall()); | 261 assert(selector.isCall); |
| 262 sideEffects.setAllSideEffects(); | 262 sideEffects.setAllSideEffects(); |
| 263 sideEffects.setDependsOnSomething(); | 263 sideEffects.setDependsOnSomething(); |
| 264 } | 264 } |
| 265 } else { | 265 } else { |
| 266 sideEffects.add(getSideEffectsOfElement(e)); | 266 sideEffects.add(getSideEffectsOfElement(e)); |
| 267 } | 267 } |
| 268 } | 268 } |
| 269 return sideEffects; | 269 return sideEffects; |
| 270 } | 270 } |
| 271 | 271 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 292 // method of function classes that were generated for function | 292 // method of function classes that were generated for function |
| 293 // expressions. In such a case, we have to look at the original | 293 // expressions. In such a case, we have to look at the original |
| 294 // function expressions's element. | 294 // function expressions's element. |
| 295 // TODO(herhut): Generate classes for function expressions earlier. | 295 // TODO(herhut): Generate classes for function expressions earlier. |
| 296 if (element is SynthesizedCallMethodElementX) { | 296 if (element is SynthesizedCallMethodElementX) { |
| 297 return getMightBePassedToApply(element.expression); | 297 return getMightBePassedToApply(element.expression); |
| 298 } | 298 } |
| 299 return functionsThatMightBePassedToApply.contains(element); | 299 return functionsThatMightBePassedToApply.contains(element); |
| 300 } | 300 } |
| 301 } | 301 } |
| OLD | NEW |