Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (revision 30666) |
| +++ sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart (working copy) |
| @@ -507,12 +507,6 @@ |
| } |
| } |
| - bool hasOnePositionalArgumentWithType(TypeMask type) { |
| - return arguments.named.isEmpty |
| - && arguments.positional.length == 1 |
| - && arguments.positional[0].type == type; |
| - } |
| - |
| /** |
| * We optimize certain operations on the [int] class because we know |
| * more about their return type than the actual Dart code. For |
| @@ -521,33 +515,48 @@ |
| */ |
| TypeInformation handleIntrisifiedSelector(Selector selector, |
| TypeGraphInferrerEngine inferrer) { |
| - if (!inferrer.compiler.backend.intImplementation.isResolved) return null; |
| - TypeMask intType = inferrer.compiler.typesTask.intType; |
| - TypeMask nullableIntType = intType.nullable(); |
| + Compiler compiler = inferrer.compiler; |
| + if (!compiler.backend.intImplementation.isResolved) return null; |
| TypeMask emptyType = const TypeMask.nonNullEmpty(); |
| - if (selector.mask != intType && selector.mask != nullableIntType) { |
| + if (selector.mask == null) return null; |
| + if (!selector.mask.containsOnlyInt(compiler)) { |
| return null; |
| } |
| if (!selector.isCall() && !selector.isOperator()) return null; |
| if (!arguments.named.isEmpty) return null; |
| if (arguments.positional.length > 1) return null; |
| + ClassElement uint31Implementation = compiler.backend.uint31Implementation; |
| + bool intCheck(info) => info.type.containsOnlyInt(compiler); |
|
floitsch
2013/11/26 15:08:20
I don't like the name "check". "predicate" or simi
ngeoffray
2013/11/26 15:19:12
Used is* instead.
|
| + bool emptyCheck(info) => info.type == emptyType; |
| + bool uint31Check(info) { |
| + return info.type.satisfies(uint31Implementation, compiler); |
| + } |
| + |
| String name = selector.name; |
| if (name == '*' || name == '+' || name == '%' || name == 'remainder') { |
| - if (hasOnePositionalArgumentWithType(intType) |
| - || hasOnePositionalArgumentWithType(nullableIntType)) { |
| + if (arguments.hasOnePositionalArgumentThatMatches(intCheck)) { |
| return inferrer.types.intType; |
| - } else if (hasOnePositionalArgumentWithType(emptyType)) { |
| + } else if (arguments.hasOnePositionalArgumentThatMatches(emptyCheck)) { |
| return inferrer.types.nonNullEmptyType; |
| } else { |
| return null; |
| } |
| + } else if (name == '|' || name == '>>' || name == '^') { |
| + if (uint31Check(receiver) |
| + && arguments.hasOnePositionalArgumentThatMatches(uint31Check)) { |
|
floitsch
2013/11/26 15:08:20
">>" doesn't need the right-hand side.
If uint31 >
ngeoffray
2013/11/26 15:19:12
Done.
|
| + return inferrer.types.uint31Type; |
| + } |
| + } else if (name == '&') { |
| + if (uint31Check(receiver) |
| + || arguments.hasOnePositionalArgumentThatMatches(uint31Check)) { |
| + return inferrer.types.uint31Type; |
| + } |
| } else if (name == '-') { |
| if (arguments.hasNoArguments()) return inferrer.types.intType; |
| - if (hasOnePositionalArgumentWithType(intType) |
| - || hasOnePositionalArgumentWithType(nullableIntType)) { |
| + if (arguments.hasOnePositionalArgumentThatMatches(intCheck)) { |
| return inferrer.types.intType; |
| - } else if (hasOnePositionalArgumentWithType(emptyType)) { |
| + } else if (arguments.hasOnePositionalArgumentThatMatches(emptyCheck)) { |
| return inferrer.types.nonNullEmptyType; |
| } |
| return null; |