Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(879)

Unified Diff: pkg/compiler/lib/src/resolution/send_resolver.dart

Issue 1306143002: Remove SendResolver.computeSendStructure. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fix handling of invalid this access. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/resolution/send_resolver.dart
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index efd92cf2724e4eba6f5e8ac476dc0e7f5cff6d8a..49369ccf692c40b15d17d5115797cf1e32f5cc9e 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -6,8 +6,6 @@ library dart2js.semantics_visitor.resolver;
import '../constants/expressions.dart';
import '../dart_types.dart';
-import '../diagnostics/invariant.dart' show
- invariant;
import '../diagnostics/messages.dart' show
MessageKind;
import '../diagnostics/spannable.dart' show
@@ -18,548 +16,15 @@ import '../tree/tree.dart';
import '../universe/universe.dart';
import 'access_semantics.dart';
-import 'operators.dart';
import 'semantic_visitor.dart';
import 'send_structure.dart';
import 'tree_elements.dart';
-enum SendStructureKind {
- GET,
- SET,
- INVOKE,
- UNARY,
- NOT,
- BINARY,
- EQ,
- NOT_EQ,
- COMPOUND,
- INDEX,
- INDEX_SET,
- COMPOUND_INDEX_SET,
- PREFIX,
- POSTFIX,
- INDEX_PREFIX,
- INDEX_POSTFIX,
-}
-
abstract class SendResolverMixin {
TreeElements get elements;
internalError(Spannable spannable, String message);
- AccessSemantics handleCompoundErroneousSetterAccess(
- Send node,
- Element setter,
- Element getter) {
- assert(invariant(node, Elements.isUnresolved(setter),
- message: "Unexpected erreneous compound setter: $setter."));
- if (getter.isStatic) {
- if (getter.isGetter) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_STATIC_SETTER, getter, setter);
- } else if (getter.isField) {
- // TODO(johnniwinther): Handle const field separately.
- assert(invariant(node, getter.isFinal || getter.isConst,
- message: "Field expected to be final or const."));
- return new StaticAccess.finalStaticField(getter);
- } else if (getter.isFunction) {
- return new StaticAccess.staticMethod(getter);
- } else {
- return internalError(node,
- "Unexpected erroneous static compound: getter=$getter");
- }
- } else if (getter.isTopLevel) {
- if (getter.isGetter) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER, getter, setter);
- } else if (getter.isField) {
- // TODO(johnniwinther): Handle const field separately.
- assert(invariant(node, getter.isFinal || getter.isConst,
- message: "Field expected to be final or const."));
- return new StaticAccess.finalTopLevelField(getter);
- } else if (getter.isFunction) {
- return new StaticAccess.topLevelMethod(getter);
- } else {
- return internalError(node,
- "Unexpected erroneous top level compound: getter=$getter");
- }
- } else if (getter.isParameter) {
- assert(invariant(node, getter.isFinal,
- message: "Parameter expected to be final."));
- return new StaticAccess.finalParameter(getter);
- } else if (getter.isLocal) {
- if (getter.isVariable) {
- // TODO(johnniwinther): Handle const variable separately.
- assert(invariant(node, getter.isFinal || getter.isConst,
- message: "Variable expected to be final or const."));
- return new StaticAccess.finalLocalVariable(getter);
- } else if (getter.isFunction) {
- return new StaticAccess.localFunction(getter);
- } else {
- return internalError(node,
- "Unexpected erroneous local compound: getter=$getter");
- }
- } else if (getter.isErroneous) {
- return new StaticAccess.unresolved(getter);
- } else {
- return internalError(node,
- "Unexpected erroneous compound: getter=$getter");
- }
- }
-
- AccessSemantics handleStaticallyResolvedAccess(
- Send node,
- Element element,
- Element getter,
- {bool isCompound}) {
- if (element == null) {
- assert(invariant(node, isCompound, message:
- "Non-compound static access without element."));
- assert(invariant(node, getter != null, message:
- "Compound static access without element."));
- return handleCompoundErroneousSetterAccess(node, element, getter);
- }
- if (element.isErroneous) {
- if (isCompound) {
- return handleCompoundErroneousSetterAccess(node, element, getter);
- }
- return new StaticAccess.unresolved(element);
- } else if (element.isParameter) {
- if (element.isFinal) {
- return new StaticAccess.finalParameter(element);
- } else {
- return new StaticAccess.parameter(element);
- }
- } else if (element.isLocal) {
- if (element.isFunction) {
- return new StaticAccess.localFunction(element);
- } else if (element.isFinal || element.isConst) {
- return new StaticAccess.finalLocalVariable(element);
- } else {
- return new StaticAccess.localVariable(element);
- }
- } else if (element.isStatic) {
- if (element.isField) {
- if (element.isFinal || element.isConst) {
- // TODO(johnniwinther): Handle const field separately.
- return new StaticAccess.finalStaticField(element);
- }
- return new StaticAccess.staticField(element);
- } else if (element.isGetter) {
- if (isCompound) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_STATIC_SETTER, element, null);
- }
- return new StaticAccess.staticGetter(element);
- } else if (element.isSetter) {
- if (getter != null) {
- CompoundAccessKind accessKind;
- if (getter.isErroneous) {
- accessKind = CompoundAccessKind.UNRESOLVED_STATIC_GETTER;
- } else if (getter.isAbstractField) {
- AbstractFieldElement abstractField = getter;
- if (abstractField.getter == null) {
- accessKind = CompoundAccessKind.UNRESOLVED_STATIC_GETTER;
- } else {
- // TODO(johnniwinther): This might be dead code.
- getter = abstractField.getter;
- accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
- }
- } else if (getter.isGetter) {
- accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
- } else {
- accessKind = CompoundAccessKind.STATIC_METHOD_SETTER;
- }
- return new CompoundAccessSemantics(
- accessKind, getter, element);
- } else {
- return new StaticAccess.staticSetter(element);
- }
- } else {
- return new StaticAccess.staticMethod(element);
- }
- } else if (element.isTopLevel) {
- if (element.isField) {
- if (element.isFinal || element.isConst) {
- // TODO(johnniwinther): Handle const field separately.
- return new StaticAccess.finalTopLevelField(element);
- }
- return new StaticAccess.topLevelField(element);
- } else if (element.isGetter) {
- return new StaticAccess.topLevelGetter(element);
- } else if (element.isSetter) {
- if (getter != null) {
- CompoundAccessKind accessKind;
- if (getter.isErroneous) {
- accessKind = CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER;
- } else if (getter.isAbstractField) {
- AbstractFieldElement abstractField = getter;
- if (abstractField.getter == null) {
- accessKind = CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER;
- } else {
- // TODO(johnniwinther): This might be dead code.
- getter = abstractField.getter;
- accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
- }
- } else if (getter.isGetter) {
- accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
- } else {
- accessKind = CompoundAccessKind.TOPLEVEL_METHOD_SETTER;
- }
- return new CompoundAccessSemantics(
- accessKind, getter, element);
- } else {
- return new StaticAccess.topLevelSetter(element);
- }
- } else {
- return new StaticAccess.topLevelMethod(element);
- }
- } else {
- return internalError(
- node, "Unhandled resolved property access: $element");
- }
- }
-
- SendStructure computeSendStructure(Send node) {
- SendStructure sendStructure = elements.getSendStructure(node);
- if (sendStructure != null) {
- return sendStructure;
- }
-
- if (elements.isAssert(node)) {
- return internalError(node, "Unexpected assert.");
- }
-
- AssignmentOperator assignmentOperator;
- BinaryOperator binaryOperator;
- IncDecOperator incDecOperator;
-
- if (node.isOperator) {
- String operatorText = node.selector.asOperator().source;
- if (operatorText == 'is') {
- return internalError(node, "Unexpected is test.");
- } else if (operatorText == 'as') {
- return internalError(node, "Unexpected as cast.");
- } else if (operatorText == '&&') {
- return internalError(node, "Unexpected logical and.");
- } else if (operatorText == '||') {
- return internalError(node, "Unexpected logical or.");
- } else if (operatorText == '??') {
- return internalError(node, "Unexpected if-null.");
- }
- }
-
- SendStructureKind kind;
-
- if (node.asSendSet() != null) {
- SendSet sendSet = node.asSendSet();
- String operatorText = sendSet.assignmentOperator.source;
- if (sendSet.isPrefix || sendSet.isPostfix) {
- kind = sendSet.isPrefix
- ? SendStructureKind.PREFIX
- : SendStructureKind.POSTFIX;
- incDecOperator = IncDecOperator.parse(operatorText);
- if (incDecOperator == null) {
- return internalError(
- node, "No inc/dec operator for '$operatorText'.");
- }
- } else {
- assignmentOperator = AssignmentOperator.parse(operatorText);
- if (assignmentOperator != null) {
- switch (assignmentOperator.kind) {
- case AssignmentOperatorKind.ASSIGN:
- kind = SendStructureKind.SET;
- break;
- default:
- kind = SendStructureKind.COMPOUND;
- }
- } else {
- return internalError(
- node, "No assignment operator for '$operatorText'.");
- }
- }
- } else if (!node.isPropertyAccess) {
- kind = SendStructureKind.INVOKE;
- } else {
- kind = SendStructureKind.GET;
- }
-
- if (node.isOperator) {
- String operatorText = node.selector.asOperator().source;
- if (node.arguments.isEmpty) {
- return internalError(node, "Unexpected unary $operatorText.");
- } else {
- binaryOperator = BinaryOperator.parse(operatorText);
- if (binaryOperator != null) {
- switch (binaryOperator.kind) {
- case BinaryOperatorKind.EQ:
- kind = SendStructureKind.EQ;
- return internalError(node, "Unexpected binary $kind.");
- case BinaryOperatorKind.NOT_EQ:
- kind = SendStructureKind.NOT_EQ;
- return internalError(node, "Unexpected binary $kind.");
- case BinaryOperatorKind.INDEX:
- if (node.isPrefix) {
- kind = SendStructureKind.INDEX_PREFIX;
- } else if (node.isPostfix) {
- kind = SendStructureKind.INDEX_POSTFIX;
- } else if (node.arguments.tail.isEmpty) {
- // a[b]
- kind = SendStructureKind.INDEX;
- return internalError(node, "Unexpected binary $kind.");
- } else {
- if (kind == SendStructureKind.COMPOUND) {
- // a[b] += c
- kind = SendStructureKind.COMPOUND_INDEX_SET;
- } else {
- // a[b] = c
- kind = SendStructureKind.INDEX_SET;
- }
- }
- break;
- default:
- kind = SendStructureKind.BINARY;
- return internalError(node, "Unexpected binary $kind.");
- }
- } else {
- return internalError(
- node, "Unexpected invalid binary $operatorText.");
- }
- }
- }
- AccessSemantics semantics = computeAccessSemantics(
- node,
- isSet: kind == SendStructureKind.SET,
- isInvoke: kind == SendStructureKind.INVOKE,
- isCompound: kind == SendStructureKind.COMPOUND ||
- kind == SendStructureKind.COMPOUND_INDEX_SET ||
- kind == SendStructureKind.PREFIX ||
- kind == SendStructureKind.POSTFIX ||
- kind == SendStructureKind.INDEX_PREFIX ||
- kind == SendStructureKind.INDEX_POSTFIX);
- if (semantics == null) {
- return internalError(node, 'No semantics for $node');
- }
- Selector selector = elements.getSelector(node);
- switch (kind) {
- case SendStructureKind.GET:
- return new GetStructure(semantics, selector);
- case SendStructureKind.SET:
- return new SetStructure(semantics, selector);
- case SendStructureKind.INVOKE:
- switch (semantics.kind) {
- case AccessKind.STATIC_METHOD:
- case AccessKind.SUPER_METHOD:
- case AccessKind.TOPLEVEL_METHOD:
- // TODO(johnniwinther): Should local function also be handled here?
- FunctionElement function = semantics.element;
- FunctionSignature signature = function.functionSignature;
- if (!selector.callStructure.signatureApplies(signature)) {
- return new IncompatibleInvokeStructure(semantics, selector);
- }
- break;
- default:
- break;
- }
- return new InvokeStructure(semantics, selector);
- case SendStructureKind.UNARY:
- return internalError(node, "Unexpected unary.");
- case SendStructureKind.NOT:
- return internalError(node, "Unexpected not.");
- case SendStructureKind.BINARY:
- return internalError(node, "Unexpected binary.");
- case SendStructureKind.INDEX:
- return internalError(node, "Unexpected index.");
- case SendStructureKind.EQ:
- return internalError(node, "Unexpected equals.");
- case SendStructureKind.NOT_EQ:
- return internalError(node, "Unexpected not equals.");
- case SendStructureKind.COMPOUND:
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- return new CompoundStructure(
- semantics,
- assignmentOperator,
- getterSelector,
- selector);
- case SendStructureKind.INDEX_SET:
- return new IndexSetStructure(semantics, selector);
- case SendStructureKind.COMPOUND_INDEX_SET:
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- return new CompoundIndexSetStructure(
- semantics,
- assignmentOperator,
- getterSelector,
- selector);
- case SendStructureKind.INDEX_PREFIX:
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- return new IndexPrefixStructure(
- semantics,
- incDecOperator,
- getterSelector,
- selector);
- case SendStructureKind.INDEX_POSTFIX:
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- return new IndexPostfixStructure(
- semantics,
- incDecOperator,
- getterSelector,
- selector);
- case SendStructureKind.PREFIX:
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- return new PrefixStructure(
- semantics,
- incDecOperator,
- getterSelector,
- selector);
- case SendStructureKind.POSTFIX:
- Selector getterSelector =
- elements.getGetterSelectorInComplexSendSet(node);
- return new PostfixStructure(
- semantics,
- incDecOperator,
- getterSelector,
- selector);
- }
- }
-
- AccessSemantics computeAccessSemantics(Send node,
- {bool isSet: false,
- bool isInvoke: false,
- bool isCompound: false}) {
- Element element = elements[node];
- Element getter = isCompound ? elements[node.selector] : null;
- if (elements.isTypeLiteral(node)) {
- DartType dartType = elements.getTypeLiteralType(node);
- // TODO(johnniwinther): Handle deferred constants. There are runtime
- // but not compile-time constants and should have their own
- // [DeferredConstantExpression] class.
- ConstantExpression constant = elements.getConstant(
- isInvoke || isSet || isCompound ? node.selector : node);
- switch (dartType.kind) {
- case TypeKind.INTERFACE:
- return new ConstantAccess.classTypeLiteral(constant);
- case TypeKind.TYPEDEF:
- return new ConstantAccess.typedefTypeLiteral(constant);
- case TypeKind.TYPE_VARIABLE:
- return new StaticAccess.typeParameterTypeLiteral(dartType.element);
- case TypeKind.DYNAMIC:
- return new ConstantAccess.dynamicTypeLiteral(constant);
- default:
- return internalError(node, "Unexpected type literal type: $dartType");
- }
- } else if (node.isSuperCall) {
- if (Elements.isUnresolved(element)) {
- if (isCompound) {
- if (Elements.isUnresolved(getter)) {
- // TODO(johnniwinther): Ensure that [getter] is not null. This
- // happens in the case of missing super getter.
- return new StaticAccess.unresolvedSuper(element);
- } else if (getter.isField) {
- assert(invariant(node, getter.isFinal,
- message: "Super field expected to be final."));
- return new StaticAccess.superFinalField(getter);
- } else if (getter.isFunction) {
- if (node.isIndex) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element);
- } else {
- return new StaticAccess.superMethod(getter);
- }
- } else {
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element);
- }
- } else {
- return new StaticAccess.unresolvedSuper(element);
- }
- } else if (isCompound && Elements.isUnresolved(getter)) {
- // TODO(johnniwinther): Ensure that [getter] is not null. This happens
- // in the case of missing super getter.
- return new CompoundAccessSemantics(
- CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, element);
- } else if (element.isField) {
- if (getter != null && getter != element) {
- CompoundAccessKind accessKind;
- if (getter.isField) {
- accessKind = CompoundAccessKind.SUPER_FIELD_FIELD;
- } else if (getter.isGetter) {
- accessKind = CompoundAccessKind.SUPER_GETTER_FIELD;
- } else {
- return internalError(node,
- "Unsupported super call: $node : $element/$getter.");
- }
- return new CompoundAccessSemantics(accessKind, getter, element);
- } else if (element.isFinal) {
- return new StaticAccess.superFinalField(element);
- }
- return new StaticAccess.superField(element);
- } else if (element.isGetter) {
- return new StaticAccess.superGetter(element);
- } else if (element.isSetter) {
- if (getter != null) {
- CompoundAccessKind accessKind;
- if (getter.isField) {
- accessKind = CompoundAccessKind.SUPER_FIELD_SETTER;
- } else if (getter.isGetter) {
- accessKind = CompoundAccessKind.SUPER_GETTER_SETTER;
- } else {
- accessKind = CompoundAccessKind.SUPER_METHOD_SETTER;
- }
- return new CompoundAccessSemantics(accessKind, getter, element);
- }
- return new StaticAccess.superSetter(element);
- } else if (isCompound) {
- return new CompoundAccessSemantics(
- CompoundAccessKind.SUPER_GETTER_SETTER, getter, element);
- } else {
- return new StaticAccess.superMethod(element);
- }
- } else if (node.isConditional) {
- // Conditional sends (e?.x) are treated as dynamic property reads because
- // they are equivalent to do ((a) => a == null ? null : a.x)(e). If `e` is
- // a type `A`, this is equivalent to write `(A).x`.
- return const DynamicAccess.ifNotNullProperty();
- } else if (node.isOperator) {
- return const DynamicAccess.dynamicProperty();
- } else if (Elements.isClosureSend(node, element)) {
- if (element == null) {
- if (node.selector.isThis()) {
- return new DynamicAccess.thisAccess();
- } else {
- return new DynamicAccess.expression();
- }
- } else if (Elements.isErroneous(element)) {
- return new StaticAccess.unresolved(element);
- } else {
- return handleStaticallyResolvedAccess(
- node, element, getter, isCompound: isCompound);
- }
- } else {
- bool isDynamicAccess(Element e) => e == null || e.isInstanceMember;
-
- if (isDynamicAccess(element) &&
- (!isCompound || isDynamicAccess(getter))) {
- if (node.receiver == null || node.receiver.isThis()) {
- return const DynamicAccess.thisProperty();
- } else {
- return const DynamicAccess.dynamicProperty();
- }
- } else if (element != null && element.impliesType) {
- // TODO(johnniwinther): Provide an [ErroneousElement].
- // This happens for code like `C.this`.
- return new StaticAccess.unresolved(null);
- } else {
- return handleStaticallyResolvedAccess(
- node, element, getter, isCompound: isCompound);
- }
- }
- }
-
ConstructorAccessSemantics computeConstructorAccessSemantics(
ConstructorElement constructor,
CallStructure callStructure,
« no previous file with comments | « pkg/compiler/lib/src/resolution/semantic_visitor.dart ('k') | tests/compiler/dart2js/semantic_visitor_test_send_data.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698