Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/typechecker.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| index 5a85c7882b7b8e6bd500061dc03f425109816916..ef7cb84e3ef710821f903660f4c18aca950f09ff 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| @@ -409,17 +409,44 @@ class InterfaceType extends DartType { |
| class FunctionType extends DartType { |
| final Element element; |
| - DartType returnType; |
| - Link<DartType> parameterTypes; |
| + final DartType returnType; |
| + final Link<DartType> parameterTypes; |
| + final Link<DartType> optionalParameterTypes; |
| + final Link<SourceString> namedParameters; |
| + final Link<DartType> namedParameterTypes; |
| final bool isMalformed; |
| - FunctionType(DartType returnType, Link<DartType> parameterTypes, |
| - Element this.element) |
| + FunctionType(Element this.element, |
| + DartType returnType, |
| + Link<DartType> parameterTypes, |
| + Link<DartType> optionalParameterTypes, |
| + Link<SourceString> this.namedParameters, |
| + Link<DartType> namedParameterTypes) |
| : this.returnType = returnType, |
| this.parameterTypes = parameterTypes, |
| - this.isMalformed = returnType != null && returnType.isMalformed || |
| - hasMalformed(parameterTypes) { |
| + this.optionalParameterTypes = optionalParameterTypes, |
| + this.namedParameterTypes = namedParameterTypes, |
| + this.isMalformed = returnType != null && |
|
karlklose
2013/01/29 13:13:29
It is annoying that we cannot use field initialize
Johnni Winther
2013/01/29 13:53:59
Done.
|
| + returnType.isMalformed || |
| + hasMalformed(parameterTypes) || |
| + hasMalformed(optionalParameterTypes) || |
| + hasMalformed(namedParameterTypes) { |
| assert(element == null || invariant(element, element.isDeclaration)); |
| + // Assert that optional |
| + assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty); |
| + } |
| + |
| + DartType getNamedParameterType(String name) { |
|
Johnni Winther
2013/01/29 13:53:59
Method removed.
|
| + Link<SourceString> namedParameter = namedParameters; |
|
karlklose
2013/01/29 13:13:29
Perhaps call this 'names' (plural works better wit
|
| + Link<DartType> namedParameterType = namedParameterTypes; |
|
karlklose
2013/01/29 13:13:29
And this 'types'.
|
| + while (!namedParameter.isEmpty && !namedParameterType.isEmpty) { |
| + if (name == namedParameter.head) { |
|
karlklose
2013/01/29 13:13:29
How does this work? name is a string.
|
| + return namedParameterType.head; |
| + } |
| + namedParameter = namedParameter.tail; |
| + namedParameterType = namedParameterType.tail; |
| + } |
| + return null; |
| } |
| TypeKind get kind => TypeKind.FUNCTION; |
| @@ -432,14 +459,26 @@ class FunctionType extends DartType { |
| } |
| var newReturnType = returnType.subst(arguments, parameters); |
| bool changed = !identical(newReturnType, returnType); |
| - var newParameterTypes = Types.substTypes(parameterTypes, arguments, |
| - parameters); |
| - if (!changed && !identical(parameterTypes, newParameterTypes)) { |
| + var newParameterTypes = |
| + Types.substTypes(parameterTypes, arguments, parameters); |
| + var newOptionalParameterTypes = |
| + Types.substTypes(optionalParameterTypes, arguments, parameters); |
| + var newNamedParameterTypes = |
| + Types.substTypes(namedParameterTypes, arguments, parameters); |
| + if (!changed && |
| + (!identical(parameterTypes, newParameterTypes) || |
| + !identical(optionalParameterTypes, newOptionalParameterTypes) || |
| + !identical(namedParameterTypes, newNamedParameterTypes))) { |
| changed = true; |
| } |
| if (changed) { |
| // Create a new type only if necessary. |
| - return new FunctionType(newReturnType, newParameterTypes, element); |
| + return new FunctionType(element, |
| + newReturnType, |
| + newParameterTypes, |
| + newOptionalParameterTypes, |
| + namedParameters, |
| + newNamedParameterTypes); |
| } |
| return this; |
| } |
| @@ -453,6 +492,16 @@ class FunctionType extends DartType { |
| return false; |
| } |
| } |
| + for (DartType parameterType in optionalParameterTypes) { |
| + if (!parameterType.forEachMalformedType(f)) { |
| + return false; |
| + } |
| + } |
| + for (DartType parameterType in namedParameterTypes) { |
| + if (!parameterType.forEachMalformedType(f)) { |
| + return false; |
| + } |
| + } |
| return true; |
| } |
| @@ -460,9 +509,39 @@ class FunctionType extends DartType { |
| String toString() { |
| StringBuffer sb = new StringBuffer(); |
| - bool first = true; |
| sb.add('('); |
| parameterTypes.printOn(sb, ', '); |
| + bool first = parameterTypes.isEmpty; |
| + if (!optionalParameterTypes.isEmpty) { |
| + if (!first) { |
| + sb.add(', '); |
| + } |
| + sb.add('['); |
| + optionalParameterTypes.printOn(sb, ', '); |
| + sb.add(']'); |
| + first = false; |
| + } |
| + if (!namedParameterTypes.isEmpty) { |
| + if (!first) { |
| + sb.add(', '); |
| + } |
| + sb.add('{'); |
| + Link<SourceString> namedParameter = namedParameters; |
| + Link<DartType> namedParameterType = namedParameterTypes; |
| + first = true; |
| + while (!namedParameter.isEmpty && !namedParameterType.isEmpty) { |
| + if (!first) { |
| + sb.add(', '); |
| + } |
| + sb.add(namedParameterType.head); |
| + sb.add(' '); |
| + sb.add(namedParameter.head.slowToString()); |
| + namedParameter = namedParameter.tail; |
| + namedParameterType = namedParameterType.tail; |
| + first = false; |
| + } |
| + sb.add('}'); |
| + } |
| sb.add(') -> ${returnType}'); |
| return sb.toString(); |
| } |
| @@ -475,13 +554,6 @@ class FunctionType extends DartType { |
| return arity; |
| } |
| - void initializeFrom(FunctionType other) { |
| - assert(returnType == null); |
| - assert(parameterTypes == null); |
| - returnType = other.returnType; |
| - parameterTypes = other.parameterTypes; |
| - } |
| - |
| int get hashCode { |
| int hash = 17 * element.hashCode + 3 * returnType.hashCode; |
| for (Link<DartType> parameters = parameterTypes; |