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

Unified Diff: pkg/analyzer/lib/src/generated/resolver.dart

Side-by-side diff isn't available for this file because of its large size.
Issue 489173002: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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:
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/parser.dart ('k') | pkg/analyzer/lib/src/generated/testing/ast_factory.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 78878046c12c64ba238d0f794ea58d803031848e..33c08635e4442761fbc8aff5d4bcf044c34e8b84 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -3613,6 +3613,7 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
Object visitEnumDeclaration(EnumDeclaration node) {
SimpleIdentifier enumName = node.name;
ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
+ enumElement.enum2 = true;
InterfaceTypeImpl enumType = new InterfaceTypeImpl.con1(enumElement);
enumElement.type = enumType;
_currentHolder.addEnum(enumElement);
@@ -4043,13 +4044,11 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
}
PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.forVariable(variable);
getter.getter = true;
- getter.static = variable.isStatic;
_currentHolder.addAccessor(getter);
variable.getter = getter;
if (!isFinal) {
PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.forVariable(variable);
setter.setter = true;
- setter.static = variable.isStatic;
ParameterElementImpl parameter = new ParameterElementImpl("_${variable.name}", variable.nameOffset);
parameter.synthetic = true;
parameter.parameterKind = ParameterKind.REQUIRED;
@@ -6832,11 +6831,15 @@ class ElementResolver extends SimpleAstVisitor<Object> {
}
} else {
if (staticOrPropagatedEnclosingElt is ClassElement) {
- InterfaceType targetType = staticOrPropagatedEnclosingElt.type;
+ ClassElement classElement = staticOrPropagatedEnclosingElt;
+ InterfaceType targetType = classElement.type;
if (targetType != null && targetType.isDartCoreFunction && propertyName.name == FunctionElement.CALL_METHOD_NAME) {
// TODO(brianwilkerson) Can we ever resolve the function being invoked?
//resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
return;
+ } else if (classElement.isEnum && propertyName.name == "_name") {
+ _resolver.reportErrorForNode(CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, propertyName, [propertyName.name]);
+ return;
}
}
ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER);
@@ -7128,23 +7131,22 @@ class EnumMemberBuilder extends RecursiveAstVisitor<Object> {
// Populate the fields.
//
List<FieldElement> fields = new List<FieldElement>();
+ List<PropertyAccessorElement> getters = new List<PropertyAccessorElement>();
InterfaceType intType = _typeProvider.intType;
- InterfaceType stringType = _typeProvider.stringType;
String indexFieldName = "index";
FieldElementImpl indexField = new FieldElementImpl(indexFieldName, -1);
indexField.final2 = true;
+ indexField.synthetic = true;
indexField.type = intType;
fields.add(indexField);
- String nameFieldName = "_name";
- FieldElementImpl nameField = new FieldElementImpl(nameFieldName, -1);
- nameField.final2 = true;
- nameField.type = stringType;
- fields.add(nameField);
+ getters.add(_createGetter(indexField));
FieldElementImpl valuesField = new FieldElementImpl("values", -1);
valuesField.static = true;
valuesField.const3 = true;
+ valuesField.synthetic = true;
valuesField.type = _typeProvider.listType.substitute4(<DartType> [enumType]);
fields.add(valuesField);
+ getters.add(_createGetter(valuesField));
//
// Build the enum constants.
//
@@ -7152,25 +7154,43 @@ class EnumMemberBuilder extends RecursiveAstVisitor<Object> {
int constantCount = constants.length;
for (int i = 0; i < constantCount; i++) {
SimpleIdentifier constantName = constants[i].name;
- FieldElementImpl constantElement = new ConstFieldElementImpl.con1(constantName);
- constantElement.static = true;
- constantElement.const3 = true;
- constantElement.type = enumType;
+ FieldElementImpl constantField = new ConstFieldElementImpl.con1(constantName);
+ constantField.static = true;
+ constantField.const3 = true;
+ constantField.type = enumType;
+ //
+ // Create a value for the constant.
+ //
HashMap<String, DartObjectImpl> fieldMap = new HashMap<String, DartObjectImpl>();
fieldMap[indexFieldName] = new DartObjectImpl(intType, new IntState(i));
- fieldMap[nameFieldName] = new DartObjectImpl(stringType, new StringState(constantName.name));
DartObjectImpl value = new DartObjectImpl(enumType, new GenericState(fieldMap));
- constantElement.evaluationResult = new ValidResult(value);
- fields.add(constantElement);
- constantName.staticElement = constantElement;
+ constantField.evaluationResult = new ValidResult(value);
+ fields.add(constantField);
+ getters.add(_createGetter(constantField));
+ constantName.staticElement = constantField;
}
//
// Finish building the enum.
//
enumElement.fields = new List.from(fields);
+ enumElement.accessors = new List.from(getters);
// Client code isn't allowed to invoke the constructor, so we do not model it.
return super.visitEnumDeclaration(node);
}
+
+ /**
+ * Create a getter that corresponds to the given field.
+ *
+ * @param field the field for which a getter is to be created
+ * @return the getter that was created
+ */
+ PropertyAccessorElement _createGetter(FieldElementImpl field) {
+ PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.forVariable(field);
+ getter.getter = true;
+ getter.returnType = field.type;
+ field.getter = getter;
+ return getter;
+ }
}
/**
@@ -7857,6 +7877,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (type is InterfaceType) {
InterfaceType interfaceType = type;
_checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
+ _checkForConstOrNewWithEnum(node, typeName, interfaceType);
if (_isInConstInstanceCreation) {
_checkForConstWithNonConst(node);
_checkForConstWithUndefinedConstructor(node, constructorName, typeName);
@@ -8075,6 +8096,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
Object visitSwitchStatement(SwitchStatement node) {
_checkForSwitchExpressionNotAssignable(node);
_checkForCaseBlocksNotTerminated(node);
+ _checkForMissingEnumConstantInSwitch(node);
return super.visitSwitchStatement(node);
}
@@ -9544,12 +9566,30 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * This verifies that the passed instance creation expression is not being invoked on an enum.
+ *
+ * @param node the instance creation expression to verify
+ * @param typeName the [TypeName] of the [ConstructorName] from the
+ * [InstanceCreationExpression], this is the AST node that the error is attached to
+ * @param type the type being constructed with this [InstanceCreationExpression]
+ * @return `true` if and only if an error code is generated on the passed node
+ * @see CompileTimeErrorCode#INSTANTIATE_ENUM
+ */
+ bool _checkForConstOrNewWithEnum(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
+ if (type.element.isEnum) {
+ _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANTIATE_ENUM, typeName, []);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* This verifies that the passed 'const' instance creation expression is not being invoked on a
* constructor that is not 'const'.
*
* This method assumes that the instance creation was tested to be 'const' before being called.
*
- * @param node the instance creation expression to evaluate
+ * @param node the instance creation expression to verify
* @return `true` if and only if an error code is generated on the passed node
* @see CompileTimeErrorCode#CONST_WITH_NON_CONST
*/
@@ -9613,6 +9653,14 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (node.staticElement != null) {
return false;
}
+ DartType type = typeName.type;
+ if (type is InterfaceType) {
+ ClassElement element = type.element;
+ if (element != null && element.isEnum) {
+ // We have already reported the error.
+ return false;
+ }
+ }
Identifier className = typeName.name;
// report as named or default constructor absence
SimpleIdentifier name = constructorName.name;
@@ -10724,6 +10772,59 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * Check to make sure that switch statements whose static type is an enum type either have a
+ * default case or include all of the enum constants.
+ *
+ * @param statement the switch statement to check
+ * @return `true` if and only if an error code is generated on the passed node
+ */
+ bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) {
+ // TODO(brianwilkerson) This needs to be checked after constant values have been computed.
+ Expression expression = statement.expression;
+ DartType expressionType = getStaticType(expression);
+ if (expressionType == null) {
+ return false;
+ }
+ Element expressionElement = expressionType.element;
+ if (expressionElement is! ClassElement) {
+ return false;
+ }
+ ClassElement classElement = expressionElement as ClassElement;
+ if (!classElement.isEnum) {
+ return false;
+ }
+ List<String> constantNames = new List<String>();
+ List<FieldElement> fields = classElement.fields;
+ int fieldCount = fields.length;
+ for (int i = 0; i < fieldCount; i++) {
+ FieldElement field = fields[i];
+ if (field.isStatic && !field.isSynthetic) {
+ constantNames.add(field.name);
+ }
+ }
+ NodeList<SwitchMember> members = statement.members;
+ int memberCount = members.length;
+ for (int i = 0; i < memberCount; i++) {
+ SwitchMember member = members[i];
+ if (member is SwitchDefault) {
+ return false;
+ }
+ String constantName = _getConstantName((member as SwitchCase).expression);
+ if (constantName != null) {
+ constantNames.remove(constantName);
+ }
+ }
+ int nameCount = constantNames.length;
+ if (nameCount == 0) {
+ return false;
+ }
+ for (int i = 0; i < nameCount; i++) {
+ _errorReporter.reportErrorForNode(CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, [constantNames[i]]);
+ }
+ return true;
+ }
+
+ /**
* This verifies that the given function body does not contain return statements that both have
* and do not have return values.
*
@@ -10852,6 +10953,14 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
if (node.staticElement != null) {
return false;
}
+ DartType type = typeName.type;
+ if (type is InterfaceType) {
+ ClassElement element = type.element;
+ if (element != null && element.isEnum) {
+ // We have already reported the error.
+ return false;
+ }
+ }
// prepare class name
Identifier className = typeName.name;
// report as named or default constructor absence
@@ -11950,6 +12059,25 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * Given an expression in a switch case whose value is expected to be an enum constant, return the
+ * name of the constant.
+ *
+ * @param expression the expression from the switch case
+ * @return the name of the constant referenced by the expression
+ */
+ String _getConstantName(Expression expression) {
+ // TODO(brianwilkerson) Convert this to return the element representing the constant.
+ if (expression is SimpleIdentifier) {
+ return expression.name;
+ } else if (expression is PrefixedIdentifier) {
+ return expression.identifier.name;
+ } else if (expression is PropertyAccess) {
+ return expression.propertyName.name;
+ }
+ return null;
+ }
+
+ /**
* Returns the Type (return type) for a given getter.
*
* @param propertyAccessorElement
@@ -22990,7 +23118,7 @@ class TypeResolverVisitor extends ScopedVisitor {
InterfaceType superclassType = null;
if (extendsClause != null) {
ErrorCode errorCode = (withClause == null ? CompileTimeErrorCode.EXTENDS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS);
- superclassType = _resolveType(extendsClause.superclass, errorCode, errorCode);
+ superclassType = _resolveType(extendsClause.superclass, errorCode, CompileTimeErrorCode.EXTENDS_ENUM, errorCode);
if (!identical(superclassType, typeProvider.objectType)) {
classElement.validMixin = false;
}
@@ -23014,7 +23142,7 @@ class TypeResolverVisitor extends ScopedVisitor {
super.visitClassTypeAlias(node);
ClassElementImpl classElement = _getClassElement(node.name);
ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS;
- InterfaceType superclassType = _resolveType(node.superclass, errorCode, errorCode);
+ InterfaceType superclassType = _resolveType(node.superclass, errorCode, CompileTimeErrorCode.EXTENDS_ENUM, errorCode);
if (superclassType == null) {
superclassType = typeProvider.objectType;
}
@@ -23841,14 +23969,14 @@ class TypeResolverVisitor extends ScopedVisitor {
*/
void _resolve(ClassElementImpl classElement, WithClause withClause, ImplementsClause implementsClause) {
if (withClause != null) {
- List<InterfaceType> mixinTypes = _resolveTypes(withClause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
+ List<InterfaceType> mixinTypes = _resolveTypes(withClause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_ENUM, CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
if (classElement != null) {
classElement.mixins = mixinTypes;
}
}
if (implementsClause != null) {
NodeList<TypeName> interfaces = implementsClause.interfaces;
- List<InterfaceType> interfaceTypes = _resolveTypes(interfaces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_DYNAMIC);
+ List<InterfaceType> interfaceTypes = _resolveTypes(interfaces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_ENUM, CompileTimeErrorCode.IMPLEMENTS_DYNAMIC);
if (classElement != null) {
classElement.interfaces = interfaceTypes;
}
@@ -23883,12 +24011,18 @@ class TypeResolverVisitor extends ScopedVisitor {
* @param typeName the type name specifying the type to be returned
* @param nonTypeError the error to produce if the type name is defined to be something other than
* a type
+ * @param enumTypeError the error to produce if the type name is defined to be an enum
* @param dynamicTypeError the error to produce if the type name is "dynamic"
* @return the type specified by the type name
*/
- InterfaceType _resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCode dynamicTypeError) {
+ InterfaceType _resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCode enumTypeError, ErrorCode dynamicTypeError) {
DartType type = typeName.type;
if (type is InterfaceType) {
+ ClassElement element = type.element;
+ if (element != null && element.isEnum) {
+ reportErrorForNode(enumTypeError, typeName, []);
+ return null;
+ }
return type;
}
// If the type is not an InterfaceType, then visitTypeName() sets the type to be a DynamicTypeImpl
@@ -23907,13 +24041,14 @@ class TypeResolverVisitor extends ScopedVisitor {
* @param typeNames the type names to be resolved
* @param nonTypeError the error to produce if the type name is defined to be something other than
* a type
+ * @param enumTypeError the error to produce if the type name is defined to be an enum
* @param dynamicTypeError the error to produce if the type name is "dynamic"
* @return an array containing all of the types that were resolved.
*/
- List<InterfaceType> _resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonTypeError, ErrorCode dynamicTypeError) {
+ List<InterfaceType> _resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonTypeError, ErrorCode enumTypeError, ErrorCode dynamicTypeError) {
List<InterfaceType> types = new List<InterfaceType>();
for (TypeName typeName in typeNames) {
- InterfaceType type = _resolveType(typeName, nonTypeError, dynamicTypeError);
+ InterfaceType type = _resolveType(typeName, nonTypeError, enumTypeError, dynamicTypeError);
if (type != null) {
types.add(type);
}
« no previous file with comments | « pkg/analyzer/lib/src/generated/parser.dart ('k') | pkg/analyzer/lib/src/generated/testing/ast_factory.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698