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; |