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

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

Issue 11309011: Issue 4289. Separate optional positional and named parameters (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 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 3ccd7e2578cf5096068aaa27e416edfceb16abdd..ba5e65a64ef635cc6d4d698b14db88f43f391825 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -127,6 +127,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -1137,14 +1138,13 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
// Check optional parameters.
- // TODO(scheglov) currently this block does not work,
- // because we handle all optional parameter as named
{
Map<String, Type> optionalParameterTypes = ftype.getOptionalParameterTypes();
Iterator<Entry<String, Type>> optionalParameterTypesIterator =
optionalParameterTypes.entrySet().iterator();
while (optionalParameterTypesIterator.hasNext()
- && argumentTypes.hasNext()) {
+ && argumentTypes.hasNext()
+ && !(argumentNodes.get(argumentIndex) instanceof DartNamedExpression)) {
Entry<String, Type> namedEntry = optionalParameterTypesIterator.next();
Type optionalType = namedEntry.getValue();
optionalType.getClass(); // quick null check
@@ -1171,28 +1171,28 @@ public class TypeAnalyzer implements DartCompilationPhase {
Map<String, Type> namedParameterTypes = ftype.getNamedParameterTypes();
Iterator<Entry<String, Type>> namedParameterTypesIterator =
namedParameterTypes.entrySet().iterator();
- // Check positional arguments for named parameters.
- while (namedParameterTypesIterator.hasNext()
- && argumentTypes.hasNext()
- && !(argumentNodes.get(argumentIndex) instanceof DartNamedExpression)) {
- Entry<String, Type> namedEntry = namedParameterTypesIterator.next();
- String parameterName = namedEntry.getKey();
- usedNamedParametersPositional.add(parameterName);
- Type namedType = namedEntry.getValue();
- namedType.getClass(); // quick null check
- Type argumentType = argumentTypes.next();
- argumentType.getClass(); // quick null check
- DartExpression argumentNode = argumentNodes.get(argumentIndex);
- if (parameters != null) {
- argumentNode.setInvocationParameterId(parameters.get(argumentIndex));
- } else {
- argumentNode.setInvocationParameterId(argumentIndex);
- }
- if (checkAssignable(argumentNode, namedType, argumentType)) {
- inferFunctionLiteralParametersTypes(argumentNode, namedType);
- }
- argumentIndex++;
- }
+// // Check positional arguments for named parameters.
Brian Wilkerson 2012/10/27 00:09:39 Is there any reason not to delete the commented ou
+// while (namedParameterTypesIterator.hasNext()
+// && argumentTypes.hasNext()
+// && !(argumentNodes.get(argumentIndex) instanceof DartNamedExpression)) {
+// Entry<String, Type> namedEntry = namedParameterTypesIterator.next();
+// String parameterName = namedEntry.getKey();
+// usedNamedParametersPositional.add(parameterName);
+// Type namedType = namedEntry.getValue();
+// namedType.getClass(); // quick null check
+// Type argumentType = argumentTypes.next();
+// argumentType.getClass(); // quick null check
+// DartExpression argumentNode = argumentNodes.get(argumentIndex);
+// if (parameters != null) {
+// argumentNode.setInvocationParameterId(parameters.get(argumentIndex));
+// } else {
+// argumentNode.setInvocationParameterId(argumentIndex);
+// }
+// if (checkAssignable(argumentNode, namedType, argumentType)) {
+// inferFunctionLiteralParametersTypes(argumentNode, namedType);
+// }
+// argumentIndex++;
+// }
// Check named arguments for named parameters.
while (argumentTypes.hasNext()
&& argumentNodes.get(argumentIndex) instanceof DartNamedExpression) {
@@ -2947,6 +2947,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
referencedTypes.add(type.getReturnType());
// parameters
referencedTypes.addAll(type.getParameterTypes());
+ referencedTypes.addAll(type.getOptionalParameterTypes().values());
referencedTypes.addAll(type.getNamedParameterTypes().values());
}
// check that referenced types do not have references on "target"
@@ -3328,64 +3329,161 @@ public class TypeAnalyzer implements DartCompilationPhase {
List<VariableElement> superParameters = superMethod.getParameters();
// Number of required parameters should be same.
{
- int numRequired = getNumRequiredParameters(parameters);
- int superNumRequired = getNumRequiredParameters(superParameters);
+ int numRequired = Elements.getNumberOfRequiredParameters(method);
+ int superNumRequired = Elements.getNumberOfRequiredParameters(superMethod);
if (numRequired != superNumRequired) {
- StringBuilder builder = new StringBuilder();
- builder.append(method.getName());
- builder.append("(");
- boolean inNamed = false;
- int parameterCount = superParameters.size();
- for (int i = 0; i < parameterCount; i++) {
- if (i > 0) {
- builder.append(", ");
- }
- VariableElement parameter = superParameters.get(i);
- if (!inNamed && parameter.isNamed()) {
- builder.append("[");
- inNamed = true;
- }
- builder.append(parameter.getType().toString());
- }
- if (inNamed) {
- builder.append("]");
- }
- builder.append(")");
onError(errorTarget,
ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS,
- builder.toString(),
+ getMethodSignature(superMethod),
superMethod.getEnclosingElement().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())) {
- DartExpression superDefValue = superParameter.getDefaultValue();
- DartExpression defValue = parameter.getDefaultValue();
- if (superDefValue != null
- && !Objects.equal(ObjectUtils.toString(defValue),
- ObjectUtils.toString(superDefValue))) {
- onError(parameter.getSourceInfo(),
- TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
- superDefValue);
- }
- continue;
+ // TODO(scheglov) remove after http://code.google.com/p/dart/issues/detail?id=6306
+ if (Elements.isLibrarySource(errorTarget.getSourceInfo().getSource(), "/io/io_runtime.dart")) {
+ return true;
+ }
+ // "method" should have at least same number of optional positional parameters as "superMethod"
+ {
+ LinkedHashMap<VariableElement, DartExpression> defMethod = getParametersDefaultsOptional(parameters);
+ LinkedHashMap<VariableElement, DartExpression> defSuper = getParametersDefaultsOptional(superParameters);
+ if (defMethod.size() < defSuper.size()) {
+ onError(errorTarget,
+ ResolverErrorCode.CANNOT_OVERRIDE_METHOD_OPTIONAL_PARAMS,
+ getMethodSignature(superMethod),
+ superMethod.getEnclosingElement().getName());
+ return false;
+ }
+ Iterator<Entry<VariableElement, DartExpression>> defMethodIter = defMethod.entrySet().iterator();
+ Iterator<Entry<VariableElement, DartExpression>> defSuperIter = defSuper.entrySet().iterator();
+ while (defSuperIter.hasNext()) {
+ Entry<VariableElement, DartExpression> methodEntry = defMethodIter.next();
+ Entry<VariableElement, DartExpression> superEntry = defSuperIter.next();
+ DartExpression methodValue = methodEntry.getValue();
+ DartExpression superValue = superEntry.getValue();
+ if (superValue != null
+ && !Objects.equal(ObjectUtils.toString(methodValue),
+ ObjectUtils.toString(superValue))) {
+ onError(methodEntry.getKey().getSourceInfo(),
+ TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
+ superValue);
}
}
- onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
- return false;
}
+ // "method" should have at least all named parameters of "superMethod".
+ {
+ Map<String, VariableElement> methodNames = getParametersNamed(parameters);
+ Map<String, VariableElement> superNames = getParametersNamed(superParameters);
+ if (!methodNames.keySet().containsAll(superNames.keySet())) {
+ onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
+ return false;
+ }
+ Map<String, DartExpression> methodDefs = getParametersDefaultsNamed(parameters);
+ Map<String, DartExpression> superDefs = getParametersDefaultsNamed(superParameters);
+ for (Entry<String, DartExpression> entry : superDefs.entrySet()) {
+ String name = entry.getKey();
+ DartExpression defValue = methodDefs.get(name);
+ DartExpression superDefValue = superDefs.get(name);
+ if (superDefValue != null
+ && !Objects.equal(ObjectUtils.toString(defValue),
+ ObjectUtils.toString(superDefValue))) {
+ onError(methodNames.get(name).getSourceInfo(),
+ TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
+ superDefValue);
+ }
+ }
+ }
+// List<VariableElement> named = getNamedParameters(parameters);
Brian Wilkerson 2012/10/27 00:09:39 Is there any reason not to delete the commented ou
+// 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())) {
+// DartExpression superDefValue = superParameter.getDefaultValue();
+// DartExpression defValue = parameter.getDefaultValue();
+// if (superDefValue != null
+// && !Objects.equal(ObjectUtils.toString(defValue),
+// ObjectUtils.toString(superDefValue))) {
+// onError(parameter.getSourceInfo(),
+// TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
+// superDefValue);
+// }
+// continue;
+// }
+// }
+// onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
+// return false;
+// }
return true;
}
+ private String getMethodSignature(MethodElement method) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(method.getName());
+ builder.append("(");
+ boolean inOptional = false;
+ boolean inNamed = false;
+ List<VariableElement> superParameters = method.getParameters();
+ int parameterCount = superParameters.size();
+ for (int i = 0; i < parameterCount; i++) {
+ if (i > 0) {
+ builder.append(", ");
+ }
+ VariableElement parameter = superParameters.get(i);
+ if (!inOptional && parameter.isOptional()) {
+ builder.append("[");
+ inOptional = true;
+ }
+ if (!inNamed && parameter.isNamed()) {
+ builder.append("{");
+ inNamed = true;
+ }
+ builder.append(parameter.getType().toString());
+ }
+ if (inOptional) {
+ builder.append("]");
+ }
+ if (inNamed) {
+ builder.append("}");
+ }
+ builder.append(")");
+ String methodSignature = builder.toString();
+ return methodSignature;
+ }
+
+ private LinkedHashMap<VariableElement, DartExpression> getParametersDefaultsOptional(List<VariableElement> parameters) {
+ LinkedHashMap<VariableElement, DartExpression> defaults = Maps.newLinkedHashMap();
+ for (VariableElement parameter : parameters) {
+ if (parameter.isOptional()) {
+ defaults.put(parameter, parameter.getDefaultValue());
+ }
+ }
+ return defaults;
+ }
+
+ private Map<String, VariableElement> getParametersNamed(List<VariableElement> parameters) {
+ Map<String, VariableElement> namedParameters = Maps.newHashMap();
+ for (VariableElement parameter : parameters) {
+ if (parameter.isNamed()) {
+ namedParameters.put(parameter.getName(), parameter);
+ }
+ }
+ return namedParameters;
+ }
+
+ private Map<String, DartExpression> getParametersDefaultsNamed(List<VariableElement> parameters) {
+ Map<String, DartExpression> defaults = Maps.newHashMap();
+ for (VariableElement parameter : parameters) {
+ if (parameter.isNamed()) {
+ defaults.put(parameter.getName(), parameter.getDefaultValue());
+ }
+ }
+ return defaults;
+ }
+
private int getNumRequiredParameters(List<VariableElement> parameters) {
int numRequired = 0;
for (VariableElement parameter : parameters) {

Powered by Google App Engine
This is Rietveld 408576698