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 b58a0eb6c5e99eb269c61455a61225bb5b4b5215..b1981391693c94555ab57486cadcbf02a1507a80 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| @@ -680,6 +680,20 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| } |
| } |
| + /// Returns the first type in the list or [:dynamic:] if the list is empty. |
| + DartType firstType(Link<DartType> link) { |
| + return link.isEmpty ? types.dynamicType : link.head; |
| + } |
| + |
| + /** |
| + * Returns the second type in the list or [:dynamic:] if the list is too |
| + * short. |
| + */ |
| + DartType secondType(Link<DartType> link) { |
| + return link.isEmpty || link.tail.isEmpty |
| + ? types.dynamicType : link.tail.head; |
| + } |
| + |
| /** |
| * Checks [: target o= value :] for some operator o, and returns the type |
| * of the result. This method also handles increment/decrement expressions |
| @@ -701,7 +715,7 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| FunctionType operatorType = operator; |
| // [result] is the type of target o value. |
| DartType result = operatorType.returnType; |
| - DartType operatorArgument = operatorType.parameterTypes.head; |
| + DartType operatorArgument = firstType(operatorType.parameterTypes); |
| // Check target o value. |
| bool validValue = checkAssignable(valueNode, value, operatorArgument); |
| if (validValue || !(node.isPrefix || node.isPostfix)) { |
| @@ -732,7 +746,7 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| node, base, const SourceString('[]'), MemberKind.OPERATOR); |
| if (indexGet is FunctionType) { |
| FunctionType indexGetType = indexGet; |
| - DartType indexGetKey = indexGetType.parameterTypes.head; |
| + DartType indexGetKey = firstType(indexGetType.parameterTypes); |
| // Check base[key]. |
| bool validKey = checkAssignable(keyNode, key, indexGetKey); |
| @@ -745,7 +759,7 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| FunctionType operatorType = operator; |
| // Check base[key] o value. |
| - DartType operatorArgument = operatorType.parameterTypes.head; |
| + DartType operatorArgument = firstType(operatorType.parameterTypes); |
| bool validValue = checkAssignable(valueNode, value, operatorArgument); |
| // [result] is the type of base[key] o value. |
| @@ -756,9 +770,8 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| node, base, const SourceString('[]='), MemberKind.OPERATOR); |
| if (indexSet is FunctionType) { |
| FunctionType indexSetType = indexSet; |
| - DartType indexSetKey = indexSetType.parameterTypes.head; |
| - DartType indexSetValue = |
| - indexSetType.parameterTypes.tail.head; |
| + DartType indexSetKey = firstType(indexSetType.parameterTypes); |
| + DartType indexSetValue = secondType(indexSetType.parameterTypes); |
| if (validKey || indexGetKey != indexSetKey) { |
| // Only check base[key] on []= if base[key] was valid for [] or |
| @@ -793,10 +806,14 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| node, base, const SourceString('[]='), MemberKind.OPERATOR); |
| if (indexSet is FunctionType) { |
| FunctionType indexSetType = indexSet; |
| - DartType indexSetKey = indexSetType.parameterTypes.head; |
| - checkAssignable(keyNode, key, indexSetKey); |
| - DartType indexSetValue = indexSetType.parameterTypes.tail.head; |
| - checkAssignable(node.assignmentOperator, value, indexSetValue); |
| + if (!indexSetType.parameterTypes.isEmpty) { |
|
karlklose
2013/05/27 08:45:22
You don't need these tests, do you? first/secondTy
Johnni Winther
2013/05/27 11:01:23
I don't test first/secondType. They are used to av
|
| + DartType indexSetKey = firstType(indexSetType.parameterTypes); |
| + checkAssignable(keyNode, key, indexSetKey); |
| + if (!indexSetType.parameterTypes.tail.isEmpty) { |
| + DartType indexSetValue = secondType(indexSetType.parameterTypes); |
| + checkAssignable(node.assignmentOperator, value, indexSetValue); |
| + } |
| + } |
| } |
| return value; |
| } else { |
| @@ -899,7 +916,7 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| DartType visitLiteralList(LiteralList node) { |
| InterfaceType listType = elements.getType(node); |
| - DartType listElementType = listType.typeArguments.head; |
| + DartType listElementType = firstType(listType.typeArguments); |
| for (Link<Node> link = node.elements.nodes; |
| !link.isEmpty; |
| link = link.tail) { |
| @@ -1087,8 +1104,8 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| visitLiteralMap(LiteralMap node) { |
| InterfaceType mapType = elements.getType(node); |
| - DartType mapKeyType = mapType.typeArguments.head; |
| - DartType mapValueType = mapType.typeArguments.tail.head; |
| + DartType mapKeyType = firstType(mapType.typeArguments); |
| + DartType mapValueType = secondType(mapType.typeArguments); |
| for (Link<Node> link = node.entries.nodes; |
| !link.isEmpty; |
| link = link.tail) { |
| @@ -1122,6 +1139,12 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| } |
| visitTryStatement(TryStatement node) { |
| + // TODO(johnniwinther): Handle reachability. |
|
karlklose
2013/05/27 08:45:22
Please explain in more detail what is missing.
Johnni Winther
2013/05/27 12:41:08
Done.
|
| + analyze(node.tryBlock); |
| + for (CatchBlock catchBlock in node.catchBlocks) { |
| + analyze(catchBlock); |
| + } |
| + analyzeWithDefault(node.finallyBlock, null); |
| return unhandledStatement(); |
| } |
| @@ -1130,7 +1153,7 @@ class TypeCheckerVisitor implements Visitor<DartType> { |
| } |
| visitCatchBlock(CatchBlock node) { |
| - return unhandledStatement(); |
| + return analyze(node.block); |
| } |
| visitTypedef(Typedef node) { |