Chromium Code Reviews| Index: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
| diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
| index f56483d6ec0b1687ad8d0bc80afe4c9a6e0a986f..d6cdfc98f485995dc8a78df73cafdf9370945034 100644 |
| --- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
| +++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart |
| @@ -6,7 +6,7 @@ library simple_types_inferrer; |
| import '../closure.dart' show ClosureClassMap; |
| import '../common.dart'; |
| -import '../common/names.dart' show Selectors; |
| +import '../common/names.dart' show Identifiers, Selectors; |
| import '../compiler.dart' show Compiler; |
| import '../constants/values.dart' show ConstantValue, IntConstantValue; |
| import '../core_types.dart' show CoreClasses, CoreTypes; |
| @@ -878,23 +878,69 @@ class SimpleTypeInferrerVisitor<T> |
| T visitSuperIndexPrefix(ast.Send node, MethodElement getter, |
| MethodElement setter, ast.Node index, op.IncDecOperator operator, _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, getter, setter, indexType); |
| } |
| @override |
| T visitSuperIndexPostfix(ast.Send node, MethodElement getter, |
| MethodElement setter, ast.Node index, op.IncDecOperator operator, _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, getter, setter, indexType); |
| + } |
| + |
| + /// Handle compound prefix/postfix operations, like `super[0]++`. |
| + T handleSuperIndexPrefixPostfix( |
| + ast.Send node, Element getter, Element setter, T indexType) { |
| + return _handleSuperCompoundIndexSet( |
| + node, getter, setter, indexType, types.uint31Type); |
| } |
| /// Handle compound super index set, like `super[42] =+ 2`. |
| - T handleSuperCompoundIndexSet( |
| - ast.SendSet node, ast.Node index, ast.Node rhs) { |
| - T receiverType = superType; |
| + T handleSuperCompoundIndexSet(ast.SendSet node, Element getter, |
| + Element setter, ast.Node index, ast.Node rhs) { |
| T indexType = visit(index); |
| T rhsType = visit(rhs); |
| - return handleCompoundIndexSet(node, receiverType, indexType, rhsType); |
| + return _handleSuperCompoundIndexSet( |
| + node, getter, setter, indexType, rhsType); |
| + } |
| + |
| + T _handleSuperCompoundIndexSet(ast.SendSet node, Element getter, |
| + Element setter, T indexType, T rhsType) { |
| + Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
| + TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); |
| + Selector operatorSelector = |
|
Siggi Cherem (dart-lang)
2016/10/17 19:55:36
nit: move this and operatorMask into the else bran
|
| + elements.getOperatorSelectorInComplexSendSet(node); |
| + TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node); |
| + Selector setterSelector = elements.getSelector(node); |
| + TypeMask setterMask = elements.getTypeMask(node); |
| + |
| + T getterType = handleSuperSend(node, getterSelector, getterMask, getter, |
| + new ArgumentsTypes<T>([indexType], null)); |
| + |
| + T returnType; |
| + if (node.isIfNullAssignment) { |
| + returnType = types.allocateDiamondPhi(getterType, rhsType); |
| + } else { |
| + returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
| + getterType, new ArgumentsTypes<T>([rhsType], null)); |
| + } |
| + handleSuperSend(node, setterSelector, setterMask, setter, |
| + new ArgumentsTypes<T>([indexType, returnType], null)); |
| + |
| + if (node.isPostfix) { |
| + return getterType; |
| + } else { |
| + return returnType; |
| + } |
|
Siggi Cherem (dart-lang)
2016/10/17 19:55:36
nit: rewrite as
return node.isPostfix ? getterTy
|
| + } |
| + |
| + T handleSuperSend(ast.Node node, Selector selector, TypeMask mask, |
| + Element element, ArgumentsTypes arguments) { |
| + if (element.isMalformed) { |
| + return handleSuperNoSuchMethod(node, selector, mask, arguments); |
| + } else { |
| + return handleStaticSend(node, selector, mask, element, arguments); |
| + } |
| } |
| @override |
| @@ -906,25 +952,25 @@ class SimpleTypeInferrerVisitor<T> |
| op.AssignmentOperator operator, |
| ast.Node rhs, |
| _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, getter, setter, index, rhs); |
| } |
| @override |
| T visitSuperIndexSetIfNull(ast.SendSet node, MethodElement getter, |
| MethodElement setter, ast.Node index, ast.Node rhs, _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, getter, setter, index, rhs); |
| } |
| @override |
| T visitUnresolvedSuperCompoundIndexSet(ast.Send node, Element element, |
| ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, element, element, index, rhs); |
| } |
| @override |
| T visitUnresolvedSuperIndexSetIfNull( |
| ast.Send node, Element element, ast.Node index, ast.Node rhs, _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, element, element, index, rhs); |
| } |
| @override |
| @@ -936,13 +982,13 @@ class SimpleTypeInferrerVisitor<T> |
| op.AssignmentOperator operator, |
| ast.Node rhs, |
| _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, element, setter, index, rhs); |
| } |
| @override |
| T visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node, Element element, |
| MethodElement setter, ast.Node index, ast.Node rhs, _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, element, setter, index, rhs); |
| } |
| @override |
| @@ -954,27 +1000,27 @@ class SimpleTypeInferrerVisitor<T> |
| op.AssignmentOperator operator, |
| ast.Node rhs, |
| _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, getter, element, index, rhs); |
| } |
| @override |
| T visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node, |
| MethodElement getter, Element element, ast.Node index, ast.Node rhs, _) { |
| - return handleSuperCompoundIndexSet(node, index, rhs); |
| + return handleSuperCompoundIndexSet(node, getter, element, index, rhs); |
| } |
| @override |
| T visitUnresolvedSuperIndexPrefix(ast.Send node, Element element, |
| ast.Node index, op.IncDecOperator operator, _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, element, element, indexType); |
| } |
| @override |
| T visitUnresolvedSuperGetterIndexPrefix(ast.SendSet node, Element element, |
| MethodElement setter, ast.Node index, op.IncDecOperator operator, _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, element, setter, indexType); |
| } |
| @override |
| @@ -986,21 +1032,21 @@ class SimpleTypeInferrerVisitor<T> |
| op.IncDecOperator operator, |
| _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, getter, element, indexType); |
| } |
| @override |
| T visitUnresolvedSuperIndexPostfix(ast.Send node, Element element, |
| ast.Node index, op.IncDecOperator operator, _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, element, element, indexType); |
| } |
| @override |
| T visitUnresolvedSuperGetterIndexPostfix(ast.SendSet node, Element element, |
| MethodElement setter, ast.Node index, op.IncDecOperator operator, _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, element, setter, indexType); |
| } |
| @override |
| @@ -1012,7 +1058,245 @@ class SimpleTypeInferrerVisitor<T> |
| op.IncDecOperator operator, |
| _) { |
| T indexType = visit(index); |
| - return handleCompoundPrefixPostfix(node, superType, indexType); |
| + return handleSuperIndexPrefixPostfix(node, getter, element, indexType); |
| + } |
| + |
| + @override |
| + T visitSuperFieldCompound(ast.Send node, FieldElement field, |
| + op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, field, field, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperFieldSetterCompound(ast.Send node, FieldElement field, |
| + FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, field, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperGetterFieldCompound(ast.Send node, FunctionElement getter, |
| + FieldElement field, op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, getter, field, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperGetterSetterCompound(ast.Send node, FunctionElement getter, |
| + FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, getter, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperMethodSetterCompound(ast.Send node, FunctionElement method, |
| + FunctionElement setter, op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, method, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperCompound(ast.Send node, Element element, |
| + op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, element, element, rhs); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperGetterCompound(ast.Send node, Element getter, |
| + SetterElement setter, op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, getter, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperSetterCompound(ast.Send node, GetterElement getter, |
| + Element setter, op.AssignmentOperator operator, ast.Node rhs, _) { |
| + return handleSuperCompound(node, getter, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperFieldFieldSetIfNull(ast.Send node, FieldElement readField, |
| + FieldElement writtenField, ast.Node rhs, _) { |
| + return handleSuperCompound(node, readField, writtenField, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperFieldSetIfNull( |
| + ast.Send node, FieldElement field, ast.Node rhs, _) { |
| + return handleSuperCompound(node, field, field, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperFieldSetterSetIfNull(ast.Send node, FieldElement field, |
| + FunctionElement setter, ast.Node rhs, _) { |
| + return handleSuperCompound(node, field, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperGetterFieldSetIfNull(ast.Send node, FunctionElement getter, |
| + FieldElement field, ast.Node rhs, _) { |
| + return handleSuperCompound(node, getter, field, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperGetterSetterSetIfNull(ast.Send node, FunctionElement getter, |
| + FunctionElement setter, ast.Node rhs, _) { |
| + return handleSuperCompound(node, getter, setter, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperMethodSetIfNull( |
| + ast.Send node, FunctionElement method, ast.Node rhs, _) { |
| + return handleSuperCompound(node, method, null, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperMethodSetterSetIfNull(ast.Send node, FunctionElement method, |
| + FunctionElement setter, ast.Node rhs, _) { |
| + return handleSuperCompound(node, method, setter, rhs); |
| + } |
| + |
| + T handleSuperCompound( |
| + ast.SendSet node, Element getter, Element setter, ast.Node rhs) { |
| + T rhsType = visit(rhs); |
| + return _handleSuperCompound(node, getter, setter, rhsType); |
| + } |
| + |
| + @override |
| + T visitSuperFieldFieldPostfix(ast.SendSet node, FieldElement readField, |
| + FieldElement writtenField, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, readField, writtenField); |
| + } |
| + |
| + @override |
| + T visitSuperFieldFieldPrefix(ast.SendSet node, FieldElement readField, |
| + FieldElement writtenField, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, readField, writtenField); |
| + } |
| + |
| + @override |
| + T visitSuperFieldPostfix( |
| + ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, field, field); |
| + } |
| + |
| + @override |
| + T visitSuperFieldPrefix( |
| + ast.SendSet node, FieldElement field, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, field, field); |
| + } |
| + |
| + @override |
| + T visitSuperFieldSetterPostfix(ast.SendSet node, FieldElement field, |
| + FunctionElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, field, setter); |
| + } |
| + |
| + @override |
| + T visitSuperFieldSetterPrefix(ast.SendSet node, FieldElement field, |
| + FunctionElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, field, setter); |
| + } |
| + |
| + @override |
| + T visitSuperGetterFieldPostfix(ast.SendSet node, FunctionElement getter, |
| + FieldElement field, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, field); |
| + } |
| + |
| + @override |
| + T visitSuperGetterFieldPrefix(ast.SendSet node, FunctionElement getter, |
| + FieldElement field, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, field); |
| + } |
| + |
| + @override |
| + T visitSuperGetterSetterPostfix(ast.SendSet node, FunctionElement getter, |
| + FunctionElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, setter); |
| + } |
| + |
| + @override |
| + T visitSuperGetterSetterPrefix(ast.SendSet node, FunctionElement getter, |
| + FunctionElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, setter); |
| + } |
| + |
| + @override |
| + T visitSuperMethodSetterPostfix(ast.SendSet node, FunctionElement method, |
| + FunctionElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, method, setter); |
| + } |
| + |
| + @override |
| + T visitSuperMethodSetterPrefix(ast.SendSet node, FunctionElement method, |
| + FunctionElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, method, setter); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperPrefix( |
| + ast.SendSet node, Element element, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, element, element); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperPostfix( |
| + ast.SendSet node, Element element, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, element, element); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperGetterPrefix(ast.SendSet node, Element getter, |
| + SetterElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, setter); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperGetterPostfix(ast.SendSet node, Element getter, |
| + SetterElement setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, setter); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperSetterPrefix(ast.SendSet node, GetterElement getter, |
| + Element setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, setter); |
| + } |
| + |
| + @override |
| + T visitUnresolvedSuperSetterPostfix(ast.SendSet node, GetterElement getter, |
| + Element setter, op.IncDecOperator operator, _) { |
| + return handleSuperPrefixPostfix(node, getter, setter); |
| + } |
| + |
| + T handleSuperPrefixPostfix(ast.SendSet node, Element getter, Element setter) { |
| + return _handleSuperCompound(node, getter, setter, types.uint31Type); |
| + } |
| + |
| + T _handleSuperCompound( |
| + ast.SendSet node, Element getter, Element setter, T rhsType) { |
| + Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
| + TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); |
| + Selector operatorSelector = |
|
Siggi Cherem (dart-lang)
2016/10/17 19:55:36
similarly comments here (as in the _handleSuperCom
Johnni Winther
2016/10/18 07:46:27
Done.
|
| + elements.getOperatorSelectorInComplexSendSet(node); |
| + TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node); |
| + Selector setterSelector = elements.getSelector(node); |
| + TypeMask setterMask = elements.getTypeMask(node); |
| + |
| + T getterType = |
| + handleSuperSend(node, getterSelector, getterMask, getter, null); |
| + |
| + T returnType; |
| + if (node.isIfNullAssignment) { |
| + returnType = types.allocateDiamondPhi(getterType, rhsType); |
| + } else { |
| + returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
| + getterType, new ArgumentsTypes<T>([rhsType], null)); |
| + } |
| + handleSuperSend(node, setterSelector, setterMask, setter, |
| + new ArgumentsTypes<T>([returnType], null)); |
| + |
| + if (node.isPostfix) { |
| + return getterType; |
| + } else { |
| + return returnType; |
| + } |
| } |
| /// Handle index set, like `foo[0] = 42`. |
| @@ -1034,23 +1318,27 @@ class SimpleTypeInferrerVisitor<T> |
| } |
| /// Handle super index set, like `super[42] = true`. |
| - T handleSuperIndexSet(ast.SendSet node, ast.Node index, ast.Node rhs) { |
| - T receiverType = superType; |
| + T handleSuperIndexSet( |
| + ast.SendSet node, Element element, ast.Node index, ast.Node rhs) { |
| T indexType = visit(index); |
| T rhsType = visit(rhs); |
| - return handleIndexSet(node, receiverType, indexType, rhsType); |
| + Selector setterSelector = elements.getSelector(node); |
| + TypeMask setterMask = elements.getTypeMask(node); |
| + handleStaticSend(node, setterSelector, setterMask, element, |
| + new ArgumentsTypes<T>([indexType, rhsType], null)); |
| + return rhsType; |
| } |
| @override |
| T visitSuperIndexSet(ast.SendSet node, FunctionElement function, |
| ast.Node index, ast.Node rhs, _) { |
| - return handleSuperIndexSet(node, index, rhs); |
| + return handleSuperIndexSet(node, function, index, rhs); |
| } |
| @override |
| T visitUnresolvedSuperIndexSet( |
| ast.SendSet node, Element element, ast.Node index, ast.Node rhs, _) { |
| - return handleSuperIndexSet(node, index, rhs); |
| + return handleSuperIndexSet(node, element, index, rhs); |
| } |
| T handlePlainAssignment( |
| @@ -1114,10 +1402,22 @@ class SimpleTypeInferrerVisitor<T> |
| TypeMask mask = elements.getTypeMask(node); |
| // TODO(herhut): We could do better here if we knew what we |
| // are calling does not expose this. |
| + // TODO(johnniwinther): Do we still need this when calling directly? |
| isThisExposed = true; |
| + return handleSuperNoSuchMethod(node, selector, mask, arguments); |
| + } |
| + |
| + T handleSuperNoSuchMethod(ast.Send node, Selector selector, TypeMask mask, |
| + ArgumentsTypes arguments) { |
| // Ensure we create a node, to make explicit the call to the |
| // `noSuchMethod` handler. |
| - return handleDynamicSend(node, selector, mask, superType, arguments); |
| + ClassElement cls = outermostElement.enclosingClass.declaration; |
| + MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
| + if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
| + element = compiler.coreClasses.objectClass |
| + .lookupMember(Identifiers.noSuchMethod_); |
| + } |
| + return handleStaticSend(node, selector, mask, element, arguments); |
| } |
| /// Handle a .call invocation on the values retrieved from the super |
| @@ -1162,6 +1462,28 @@ class SimpleTypeInferrerVisitor<T> |
| return handleStaticSend(node, selector, mask, element, null); |
| } |
| + /// Handle update to a super field or setter [element]. |
| + T handleSuperSet(ast.Send node, Element element, ast.Node rhs) { |
| + T rhsType = visit(rhs); |
| + // TODO(herhut): We could do better here if we knew what we |
| + // are calling does not expose this. |
| + isThisExposed = true; |
| + Selector selector = elements.getSelector(node); |
| + TypeMask mask = elements.getTypeMask(node); |
| + return handleStaticSend( |
| + node, selector, mask, element, new ArgumentsTypes<T>([rhsType], null)); |
| + } |
| + |
| + @override |
| + T visitSuperFieldSet(ast.Send node, FieldElement method, ast.Node rhs, _) { |
| + return handleSuperSet(node, method, rhs); |
| + } |
| + |
| + @override |
| + T visitSuperSetterSet(ast.Send node, SetterElement field, ast.Node rhs, _) { |
| + return handleSuperSet(node, field, rhs); |
| + } |
| + |
| @override |
| T visitUnresolvedSuperIndex( |
| ast.Send node, Element element, ast.Node index, _) { |
| @@ -1196,6 +1518,17 @@ class SimpleTypeInferrerVisitor<T> |
| } |
| @override |
| + T visitSuperMethodSet(ast.Send node, MethodElement method, ast.Node rhs, _) { |
| + return handleErroneousSuperSend(node); |
| + } |
| + |
| + @override |
| + T visitFinalSuperFieldSet( |
| + ast.Send node, FieldElement method, ast.Node rhs, _) { |
| + return handleErroneousSuperSend(node); |
| + } |
| + |
| + @override |
| T visitUnresolvedSuperSet(ast.Send node, Element element, ast.Node rhs, _) { |
| return handleErroneousSuperSend(node); |
| } |