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

Unified Diff: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java

Issue 9403026: Issue 1575. Allow declare new named parameters in method override. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Style tweaks. Created 8 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index 50b57754640065acf336184be7f882206cb1b31e..62114801d322a858dadc0da07bb4657a13f25b85 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -6,9 +6,11 @@ package com.google.dart.compiler.type;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.dart.compiler.DartCompilationError;
@@ -1821,7 +1823,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
for (InterfaceType supertype : supertypes) {
for (Element member : supertype.getElement().getMembers()) {
String name = member.getName();
- if (name.startsWith("_")) {
+ if (DartIdentifier.isPrivateName(name)) {
if (currentLibrary != member.getEnclosingElement().getEnclosingElement()) {
continue;
}
@@ -1954,63 +1956,85 @@ public class TypeAnalyzer implements DartCompilationPhase {
String name = member.getName();
Type superMember = typeAsMemberOf(superElement, currentClass);
if (member.getKind() == ElementKind.METHOD && superElement.getKind() == ElementKind.METHOD) {
- MethodElement method = (MethodElement)member;
+ MethodElement method = (MethodElement) member;
MethodElement superMethod = (MethodElement) superElement;
+ if (hasLegalMethodOverrideSignature(node, method, superMethod)) {
+ if (!types.isSubtype(member.getType(), superMember)) {
+ typeError(node,
+ TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE,
+ name,
+ superElement.getEnclosingElement().getName(),
+ member.getType(),
+ superMember);
+ }
+ }
+ } else if (!types.isAssignable(superMember, member.getType())) {
+ typeError(node,
+ TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER,
+ name,
+ superElement.getEnclosingElement().getName(),
+ member.getType(),
+ superMember);
+ }
+ }
- // Compare the # of parameters
- List<VariableElement> parameters = method.getParameters();
- List<VariableElement> superParameters = superMethod
- .getParameters();
- if (superParameters.size() != parameters.size()) {
+ /**
+ * @return <code>true</code> if given "method" has signature compatible with "superMethod".
+ */
+ private boolean hasLegalMethodOverrideSignature(DartNode node,
+ MethodElement method,
+ MethodElement superMethod) {
+ // Prepare parameters.
+ List<VariableElement> parameters = method.getParameters();
+ List<VariableElement> superParameters = superMethod.getParameters();
+ // Number of required parameters should be same.
+ {
+ int numRequired = getNumRequiredParameters(parameters);
+ int superNumRequired = getNumRequiredParameters(superParameters);
+ if (numRequired != superNumRequired) {
onError(node,
- ResolverErrorCode.CANNOT_OVERRIDE_METHOD_WRONG_NUM_PARAMS,
- member.getName());
- } else {
- // Make sure that named parameters match
- List<VariableElement> named = new ArrayList<VariableElement>();
- for (VariableElement v : parameters) {
- if (v.isNamed()) {
- named.add(v);
- }
- }
- List<VariableElement> superNamed = new ArrayList<VariableElement>();
- for (VariableElement v : superParameters) {
- if (v.isNamed()) {
- superNamed.add(v);
- }
+ ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS,
+ method.getName());
+ return false;
+ }
+ }
+ // "method" should have at least all named parameters of "superMethod" in the same order.
+ List<VariableElement> named = getNamedParameters(parameters);
+ List<VariableElement> superNamed = getNamedParameters(superParameters);
+ Iterator<VariableElement> namedIterator = named.iterator();
+ Iterator<VariableElement> superNamedIterator = superNamed.iterator();
+ while (superNamedIterator.hasNext()) {
+ VariableElement superParameter = superNamedIterator.next();
+ if (namedIterator.hasNext()) {
+ VariableElement parameter = namedIterator.next();
+ if (Objects.equal(parameter.getName(), superParameter.getName())) {
+ continue;
}
- if (named.size() != superNamed.size()) {
- onError(node,
- ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_NAMED_PARAMS,
- member.getName());
- } else {
- boolean errorFound = false;
- while (!named.isEmpty()) {
- VariableElement v1 = named.remove(0);
- VariableElement v2 = superNamed.remove(0);
- if (!v1.getName().equals(v2.getName())) {
- onError(v1.getNode(),
- ResolverErrorCode.CANNOT_OVERRIDE_METHOD_ORDER_NAMED_PARAMS,
- member.getName());
- errorFound = true;
- break;
- }
- }
- if (!errorFound && !types.isSubtype(member.getType(), superMember)) {
- // Wrong # of parameters is a compile-time error and has already
- // been checked.
- if (method.getParameters().size() == superMethod.getParameters().size()) {
- typeError(node, TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE, name, superElement
- .getEnclosingElement().getName(), member.getType(), superMember);
- }
- }
+ }
+ onError(node, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
+ return false;
+ }
+ return true;
+ }
- }
+ private int getNumRequiredParameters(List<VariableElement> parameters) {
+ int numRequired = 0;
+ for (VariableElement parameter : parameters) {
+ if (!parameter.isNamed()) {
+ numRequired++;
+ }
+ }
+ return numRequired;
+ }
+
+ private List<VariableElement> getNamedParameters(List<VariableElement> parameters) {
+ List<VariableElement> named = Lists.newArrayList();
+ for (VariableElement v : parameters) {
+ if (v.isNamed()) {
+ named.add(v);
}
- } else if (!types.isAssignable(superMember, member.getType())) {
- typeError(node, TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER, name, superElement
- .getEnclosingElement().getName(), member.getType(), superMember);
}
+ return named;
}
}
}

Powered by Google App Engine
This is Rietveld 408576698