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

Side by Side Diff: pkg/analyzer/lib/src/generated/element.dart

Issue 1405143006: improve static type analysis for `await for` (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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 | « no previous file | pkg/analyzer/lib/src/generated/element_resolver.dart » ('j') | 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 engine.element; 5 library engine.element;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' show min; 8 import 'dart:math' show min;
9 9
10 import 'package:analyzer/src/generated/utilities_general.dart'; 10 import 'package:analyzer/src/generated/utilities_general.dart';
(...skipping 4873 matching lines...) Expand 10 before | Expand all | Expand 10 after
4884 * [element]. 4884 * [element].
4885 */ 4885 */
4886 FunctionTypeImpl(ExecutableElement element, [this.prunedTypedefs]) 4886 FunctionTypeImpl(ExecutableElement element, [this.prunedTypedefs])
4887 : super(element, null); 4887 : super(element, null);
4888 4888
4889 /** 4889 /**
4890 * Initialize a newly created function type to be declared by the given 4890 * Initialize a newly created function type to be declared by the given
4891 * [element]. 4891 * [element].
4892 */ 4892 */
4893 @deprecated // Use new FunctionTypeImpl(element) 4893 @deprecated // Use new FunctionTypeImpl(element)
4894 FunctionTypeImpl.con1(ExecutableElement element) 4894 FunctionTypeImpl.con1(ExecutableElement element) : this(element);
4895 : prunedTypedefs = null,
4896 super(element, null);
4897 4895
4898 /** 4896 /**
4899 * Initialize a newly created function type to be declared by the given 4897 * Initialize a newly created function type to be declared by the given
4900 * [element]. 4898 * [element].
4901 */ 4899 */
4902 @deprecated // Use new FunctionTypeImpl.forTypedef(element) 4900 @deprecated // Use new FunctionTypeImpl.forTypedef(element)
4903 FunctionTypeImpl.con2(FunctionTypeAliasElement element) 4901 FunctionTypeImpl.con2(FunctionTypeAliasElement element)
4904 : prunedTypedefs = null, 4902 : this.forTypedef(element);
4905 super(element, element == null ? null : element.name);
4906 4903
4907 /** 4904 /**
4908 * Initialize a newly created function type to be declared by the given 4905 * Initialize a newly created function type to be declared by the given
4909 * [element]. 4906 * [element].
4910 */ 4907 */
4911 FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element, 4908 FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
4912 [this.prunedTypedefs]) 4909 [this.prunedTypedefs])
4913 : super(element, element == null ? null : element.name); 4910 : super(element, element == null ? null : element.name);
4914 4911
4915 /** 4912 /**
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after
6228 * setter) is the result of the lookup. Otherwise, if <i>C</i> has a 6225 * setter) is the result of the lookup. Otherwise, if <i>C</i> has a
6229 * superclass <i>S</i>, then the result of the lookup is the result of 6226 * superclass <i>S</i>, then the result of the lookup is the result of
6230 * looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect 6227 * looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
6231 * to <i>L</i>. Otherwise, we say that the lookup has failed. 6228 * to <i>L</i>. Otherwise, we say that the lookup has failed.
6232 * </blockquote> 6229 * </blockquote>
6233 */ 6230 */
6234 PropertyAccessorElement lookUpGetterInSuperclass( 6231 PropertyAccessorElement lookUpGetterInSuperclass(
6235 String name, LibraryElement library); 6232 String name, LibraryElement library);
6236 6233
6237 /** 6234 /**
6235 * Look up the member with the given [name] in this type and all extended
6236 * and mixed in classes, and by default including [thisType]. If the search
6237 * fails, this will then search interfaces.
6238 *
6239 * Return the element representing the member that was found, or `null` if
6240 * there is no getter with the given name.
6241 *
6242 * The [library] determines if a private member name is visible, and does not
6243 * need to be supplied for public names.
6244 */
6245 PropertyAccessorElement lookUpInheritedGetter(String name,
6246 {LibraryElement library, bool thisType: true});
6247
6248 /**
6249 * Look up the member with the given [name] in this type and all extended
6250 * and mixed in classes, starting from this type. If the search fails,
6251 * search interfaces.
6252 *
6253 * Return the element representing the member that was found, or `null` if
6254 * there is no getter with the given name.
6255 *
6256 * The [library] determines if a private member name is visible, and does not
6257 * need to be supplied for public names.
6258 */
6259 ExecutableElement lookUpInheritedGetterOrMethod(String name,
6260 {LibraryElement library});
6261
6262 /**
6263 * Look up the member with the given [name] in this type and all extended
6264 * and mixed in classes, and by default including [thisType]. If the search
6265 * fails, this will then search interfaces.
6266 *
6267 * Return the element representing the member that was found, or `null` if
6268 * there is no getter with the given name.
6269 *
6270 * The [library] determines if a private member name is visible, and does not
6271 * need to be supplied for public names.
6272 */
6273 MethodElement lookUpInheritedMethod(String name,
6274 {LibraryElement library, bool thisType: true});
6275
6276 /**
6277 * Look up the member with the given [name] in this type and all extended
6278 * and mixed in classes, and by default including [thisType]. If the search
6279 * fails, this will then search interfaces.
6280 *
6281 * Return the element representing the member that was found, or `null` if
6282 * there is no getter with the given name.
6283 *
6284 * The [library] determines if a private member name is visible, and does not
6285 * need to be supplied for public names.
6286 */
6287 PropertyAccessorElement lookUpInheritedSetter(String name,
6288 {LibraryElement library, bool thisType: true});
6289
6290 /**
6238 * Return the element representing the method that results from looking up the 6291 * Return the element representing the method that results from looking up the
6239 * method with the given [name] in this class with respect to the given 6292 * method with the given [name] in this class with respect to the given
6240 * [library], or `null` if the look up fails. The behavior of this method is 6293 * [library], or `null` if the look up fails. The behavior of this method is
6241 * defined by the Dart Language Specification in section 12.15.1: 6294 * defined by the Dart Language Specification in section 12.15.1:
6242 * <blockquote> 6295 * <blockquote>
6243 * The result of looking up method <i>m</i> in class <i>C</i> with respect to 6296 * The result of looking up method <i>m</i> in class <i>C</i> with respect to
6244 * library <i>L</i> is: 6297 * library <i>L</i> is:
6245 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible 6298 * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
6246 * to <i>L</i>, then that method is the result of the lookup. Otherwise, if 6299 * to <i>L</i>, then that method is the result of the lookup. Otherwise, if
6247 * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the 6300 * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
6835 return element; 6888 return element;
6836 } 6889 }
6837 } 6890 }
6838 supertype = supertype.superclass; 6891 supertype = supertype.superclass;
6839 supertypeElement = supertype == null ? null : supertype.element; 6892 supertypeElement = supertype == null ? null : supertype.element;
6840 } 6893 }
6841 return null; 6894 return null;
6842 } 6895 }
6843 6896
6844 @override 6897 @override
6898 PropertyAccessorElement lookUpInheritedGetter(String name,
6899 {LibraryElement library, bool thisType: true}) {
6900 PropertyAccessorElement result;
6901 if (thisType) {
6902 result = lookUpGetter(name, library);
6903 } else {
6904 result = lookUpGetterInSuperclass(name, library);
6905 }
6906 if (result != null) {
6907 return result;
6908 }
6909 return _lookUpMemberInInterfaces(this, false, library,
6910 new HashSet<ClassElement>(), (InterfaceType t) => t.getGetter(name));
6911 }
6912
6913 @override
6914 ExecutableElement lookUpInheritedGetterOrMethod(String name,
6915 {LibraryElement library}) {
6916 ExecutableElement result =
6917 lookUpGetter(name, library) ?? lookUpMethod(name, library);
6918
6919 if (result != null) {
6920 return result;
6921 }
6922 return _lookUpMemberInInterfaces(
6923 this,
6924 false,
6925 library,
6926 new HashSet<ClassElement>(),
6927 (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
6928 }
6929
6930 @override
6931 MethodElement lookUpInheritedMethod(String name,
6932 {LibraryElement library, bool thisType: true}) {
6933 MethodElement result;
6934 if (thisType) {
6935 result = lookUpMethod(name, library);
6936 } else {
6937 result = lookUpMethodInSuperclass(name, library);
6938 }
6939 if (result != null) {
6940 return result;
6941 }
6942 return _lookUpMemberInInterfaces(this, false, library,
6943 new HashSet<ClassElement>(), (InterfaceType t) => t.getMethod(name));
6944 }
6945
6946 @override
6947 PropertyAccessorElement lookUpInheritedSetter(String name,
6948 {LibraryElement library, bool thisType: true}) {
6949 PropertyAccessorElement result;
6950 if (thisType) {
6951 result = lookUpSetter(name, library);
6952 } else {
6953 result = lookUpSetterInSuperclass(name, library);
6954 }
6955 if (result != null) {
6956 return result;
6957 }
6958 return _lookUpMemberInInterfaces(this, false, library,
6959 new HashSet<ClassElement>(), (t) => t.getSetter(name));
6960 }
6961
6962 @override
6845 MethodElement lookUpMethod(String methodName, LibraryElement library) { 6963 MethodElement lookUpMethod(String methodName, LibraryElement library) {
6846 MethodElement element = getMethod(methodName); 6964 MethodElement element = getMethod(methodName);
6847 if (element != null && element.isAccessibleIn(library)) { 6965 if (element != null && element.isAccessibleIn(library)) {
6848 return element; 6966 return element;
6849 } 6967 }
6850 return lookUpMethodInSuperclass(methodName, library); 6968 return lookUpMethodInSuperclass(methodName, library);
6851 } 6969 }
6852 6970
6853 @override 6971 @override
6854 MethodElement lookUpMethodInSuperclass( 6972 MethodElement lookUpMethodInSuperclass(
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
7108 /** 7226 /**
7109 * Return the intersection of the [first] and [second] sets of types, where 7227 * Return the intersection of the [first] and [second] sets of types, where
7110 * intersection is based on the equality of the types themselves. 7228 * intersection is based on the equality of the types themselves.
7111 */ 7229 */
7112 static List<InterfaceType> _intersection( 7230 static List<InterfaceType> _intersection(
7113 Set<InterfaceType> first, Set<InterfaceType> second) { 7231 Set<InterfaceType> first, Set<InterfaceType> second) {
7114 Set<InterfaceType> result = new HashSet<InterfaceType>.from(first); 7232 Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
7115 result.retainAll(second); 7233 result.retainAll(second);
7116 return new List.from(result); 7234 return new List.from(result);
7117 } 7235 }
7236
7237 /**
7238 * Look up the getter with the given [name] in the interfaces
7239 * implemented by the given [targetType], either directly or indirectly.
7240 * Return the element representing the getter that was found, or `null` if
7241 * there is no getter with the given name. The flag [includeTargetType] should
7242 * be `true` if the search should include the target type. The
7243 * [visitedInterfaces] is a set containing all of the interfaces that have
7244 * been examined, used to prevent infinite recursion and to optimize the
7245 * search.
7246 */
7247 static ExecutableElement _lookUpMemberInInterfaces(
7248 InterfaceType targetType,
7249 bool includeTargetType,
7250 LibraryElement library,
7251 HashSet<ClassElement> visitedInterfaces,
7252 ExecutableElement getMember(InterfaceType type)) {
7253 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
7254 // specification (titled "Inheritance and Overriding" under "Interfaces")
7255 // describes a much more complex scheme for finding the inherited member.
7256 // We need to follow that scheme. The code below should cover the 80% case.
7257 ClassElement targetClass = targetType.element;
7258 if (!visitedInterfaces.add(targetClass)) {
7259 return null;
7260 }
7261 if (includeTargetType) {
7262 ExecutableElement member = getMember(targetType);
7263 if (member != null && member.isAccessibleIn(library)) {
7264 return member;
7265 }
7266 }
7267 for (InterfaceType interfaceType in targetType.interfaces) {
7268 ExecutableElement member = _lookUpMemberInInterfaces(
7269 interfaceType, true, library, visitedInterfaces, getMember);
7270 if (member != null) {
7271 return member;
7272 }
7273 }
7274 for (InterfaceType mixinType in targetType.mixins.reversed) {
7275 PropertyAccessorElement member = _lookUpMemberInInterfaces(
7276 mixinType, true, library, visitedInterfaces, getMember);
7277 if (member != null) {
7278 return member;
7279 }
7280 }
7281 InterfaceType superclass = targetType.superclass;
7282 if (superclass == null) {
7283 return null;
7284 }
7285 return _lookUpMemberInInterfaces(
7286 superclass, true, library, visitedInterfaces, getMember);
7287 }
7118 } 7288 }
7119 7289
7120 /** 7290 /**
7121 * A label associated with a statement. 7291 * A label associated with a statement.
7122 */ 7292 */
7123 abstract class LabelElement implements Element { 7293 abstract class LabelElement implements Element {
7124 /** 7294 /**
7125 * An empty list of label elements. 7295 * An empty list of label elements.
7126 */ 7296 */
7127 static const List<LabelElement> EMPTY_LIST = const <LabelElement>[]; 7297 static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
7510 for (ImportElement importElement in imports) { 7680 for (ImportElement importElement in imports) {
7511 (importElement as ImportElementImpl).enclosingElement = this; 7681 (importElement as ImportElementImpl).enclosingElement = this;
7512 PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl; 7682 PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
7513 if (prefix != null) { 7683 if (prefix != null) {
7514 prefix.enclosingElement = this; 7684 prefix.enclosingElement = this;
7515 } 7685 }
7516 } 7686 }
7517 this._imports = imports; 7687 this._imports = imports;
7518 } 7688 }
7519 7689
7520 /** Given an update to this library which may have added or deleted edges
7521 * in the import/export graph originating from this node only, remove any
7522 * cached library cycles in the element model which may have been invalidated.
7523 */
7524 void invalidateLibraryCycles() {
7525 if (_libraryCycle == null) {
7526 // We have already invalidated this node, or we have never computed
7527 // library cycle information for it. In the former case, we're done. In
7528 // the latter case, this node cannot be reachable from any node for which
7529 // we have computed library cycle information. Therefore, any edges added
7530 // or deleted in the update causing this invalidation can only be edges to
7531 // nodes which either have no library cycle information (and hence do not
7532 // need invalidation), or which do not reach this node by any path.
7533 // In either case, no further invalidation is needed.
7534 return;
7535 }
7536 // If we have pre-computed library cycle information, then we must
7537 // invalidate the information both on this element, and on certain
7538 // other elements. Edges originating at this node may have been
7539 // added or deleted. A deleted edge that points outside of this cycle
7540 // cannot change the cycle information for anything outside of this cycle,
7541 // and so it is sufficient to delete the cached library information on this
7542 // cycle. An added edge which points to another node within the cycle
7543 // only invalidates the cycle. An added edge which points to a node earlier
7544 // in the topological sort of cycles induces no invalidation (since there
7545 // are by definition no back edges from earlier cycles in the topological
7546 // order, and hence no possible cycle can have been introduced. The only
7547 // remaining case is that we have added an edge to a node which is later
7548 // in the topological sort of cycles. This can induce cycles, since it
7549 // represents a new back edge. It would be sufficient to invalidate the
7550 // cycle information for all nodes that are between the target and the
7551 // node in the topological order. For simplicity, we simply invalidate
7552 // all nodes which are reachable from the the source node.
7553 // Note that in the invalidation phase, we do not cut off when we encounter
7554 // a node with no library cycle information, since we do not know whether
7555 // we are in the case where invalidation has already been performed, or we
7556 // are in the case where library cycles have simply never been computed from
7557 // a newly reachable node.
7558 Set<LibraryElementImpl> active = new HashSet();
7559 void invalidate(LibraryElementImpl library) {
7560 if (!active.add(library)) return;
7561 if (library._libraryCycle != null) {
7562 library._libraryCycle.forEach(invalidate);
7563 library._libraryCycle = null;
7564 }
7565 library.exportedLibraries.forEach(invalidate);
7566 library.importedLibraries.forEach(invalidate);
7567 }
7568 invalidate(this);
7569 }
7570
7571 @override 7690 @override
7572 bool get isBrowserApplication => 7691 bool get isBrowserApplication =>
7573 entryPoint != null && isOrImportsBrowserLibrary; 7692 entryPoint != null && isOrImportsBrowserLibrary;
7574 7693
7575 @override 7694 @override
7576 bool get isDartCore => name == "dart.core"; 7695 bool get isDartCore => name == "dart.core";
7577 7696
7578 @override 7697 @override
7579 bool get isInSdk => 7698 bool get isInSdk =>
7580 StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E); 7699 StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
7798 } 7917 }
7799 for (CompilationUnitElement part in _parts) { 7918 for (CompilationUnitElement part in _parts) {
7800 type = part.getType(className); 7919 type = part.getType(className);
7801 if (type != null) { 7920 if (type != null) {
7802 return type; 7921 return type;
7803 } 7922 }
7804 } 7923 }
7805 return null; 7924 return null;
7806 } 7925 }
7807 7926
7927 /** Given an update to this library which may have added or deleted edges
7928 * in the import/export graph originating from this node only, remove any
7929 * cached library cycles in the element model which may have been invalidated.
7930 */
7931 void invalidateLibraryCycles() {
7932 if (_libraryCycle == null) {
7933 // We have already invalidated this node, or we have never computed
7934 // library cycle information for it. In the former case, we're done. In
7935 // the latter case, this node cannot be reachable from any node for which
7936 // we have computed library cycle information. Therefore, any edges added
7937 // or deleted in the update causing this invalidation can only be edges to
7938 // nodes which either have no library cycle information (and hence do not
7939 // need invalidation), or which do not reach this node by any path.
7940 // In either case, no further invalidation is needed.
7941 return;
7942 }
7943 // If we have pre-computed library cycle information, then we must
7944 // invalidate the information both on this element, and on certain
7945 // other elements. Edges originating at this node may have been
7946 // added or deleted. A deleted edge that points outside of this cycle
7947 // cannot change the cycle information for anything outside of this cycle,
7948 // and so it is sufficient to delete the cached library information on this
7949 // cycle. An added edge which points to another node within the cycle
7950 // only invalidates the cycle. An added edge which points to a node earlier
7951 // in the topological sort of cycles induces no invalidation (since there
7952 // are by definition no back edges from earlier cycles in the topological
7953 // order, and hence no possible cycle can have been introduced. The only
7954 // remaining case is that we have added an edge to a node which is later
7955 // in the topological sort of cycles. This can induce cycles, since it
7956 // represents a new back edge. It would be sufficient to invalidate the
7957 // cycle information for all nodes that are between the target and the
7958 // node in the topological order. For simplicity, we simply invalidate
7959 // all nodes which are reachable from the the source node.
7960 // Note that in the invalidation phase, we do not cut off when we encounter
7961 // a node with no library cycle information, since we do not know whether
7962 // we are in the case where invalidation has already been performed, or we
7963 // are in the case where library cycles have simply never been computed from
7964 // a newly reachable node.
7965 Set<LibraryElementImpl> active = new HashSet();
7966 void invalidate(LibraryElementImpl library) {
7967 if (!active.add(library)) return;
7968 if (library._libraryCycle != null) {
7969 library._libraryCycle.forEach(invalidate);
7970 library._libraryCycle = null;
7971 }
7972 library.exportedLibraries.forEach(invalidate);
7973 library.importedLibraries.forEach(invalidate);
7974 }
7975 invalidate(this);
7976 }
7977
7808 @override 7978 @override
7809 bool isUpToDate(int timeStamp) { 7979 bool isUpToDate(int timeStamp) {
7810 Set<LibraryElement> visitedLibraries = new Set(); 7980 Set<LibraryElement> visitedLibraries = new Set();
7811 return _safeIsUpToDate(this, timeStamp, visitedLibraries); 7981 return _safeIsUpToDate(this, timeStamp, visitedLibraries);
7812 } 7982 }
7813 7983
7814 @override 7984 @override
7815 void visitChildren(ElementVisitor visitor) { 7985 void visitChildren(ElementVisitor visitor) {
7816 super.visitChildren(visitor); 7986 super.visitChildren(visitor);
7817 safelyVisitChild(_definingCompilationUnit, visitor); 7987 safelyVisitChild(_definingCompilationUnit, visitor);
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after
10967 11137
10968 @override 11138 @override
10969 void visitElement(Element element) { 11139 void visitElement(Element element) {
10970 int offset = element.nameOffset; 11140 int offset = element.nameOffset;
10971 if (offset != -1) { 11141 if (offset != -1) {
10972 map[offset] = element; 11142 map[offset] = element;
10973 } 11143 }
10974 super.visitElement(element); 11144 super.visitElement(element);
10975 } 11145 }
10976 } 11146 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/element_resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698