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

Unified Diff: lib/src/compiler/code_generator.dart

Issue 2039173005: Refactoring assignment (Closed) Base URL: https://github.com/dart-lang/dev_compiler@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/compiler/code_generator.dart
diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
index 4c8001751fb93d265197105016866d1a2c5c5d3b..27127cdc060821928d40fb02891d541e51dd9f1b 100644
--- a/lib/src/compiler/code_generator.dart
+++ b/lib/src/compiler/code_generator.dart
@@ -2715,21 +2715,35 @@ class CodeGenerator extends GeneralizingAstVisitor
return _emitSend(target, '[]=', [lhs.index, rhs]);
}
+ if (lhs is SimpleIdentifier) {
+ return _emitSetSimpleIdentifier(lhs, rhs);
+ }
+
Expression target = null;
SimpleIdentifier id;
if (lhs is PropertyAccess) {
if (lhs.operator.lexeme == '?.') {
return _emitNullSafeSet(lhs, rhs);
}
-
target = _getTarget(lhs);
id = lhs.propertyName;
} else if (lhs is PrefixedIdentifier) {
+ if (isLibraryPrefix(lhs.prefix)) {
+ return _emitSet(lhs.identifier, rhs);
+ }
target = lhs.prefix;
id = lhs.identifier;
+ } else {
+ assert(false);
+ }
+
+ assert(target != null);
+
+ if (target is SuperExpression) {
+ return _emitSetSuper(lhs, target, id, rhs);
}
- if (target != null && DynamicInvoke.get(target)) {
+ if (DynamicInvoke.get(target)) {
if (_inWhitelistCode(lhs)) {
var vars = <JS.MetaLetVariable, JS.Expression>{};
var l = _visit(_bindValue(vars, 'l', target));
@@ -2743,6 +2757,134 @@ class CodeGenerator extends GeneralizingAstVisitor
[_visit(target), _emitMemberName(id.name), _visit(rhs)]);
}
+ var accessor = id.staticElement;
+ var element =
+ accessor is PropertyAccessorElement ? accessor.variable : accessor;
+
+ if (element is ClassMemberElement && element is! ConstructorElement) {
+ bool isStatic = element.isStatic;
+ if (isStatic) {
+ if (element is FieldElement) {
+ return _emitSetStaticProperty(lhs, element, rhs);
+ }
+ return _badAssignment('Unknown static: $element', lhs, rhs);
+ }
+ if (element is FieldElement) {
+ return _emitWriteInstanceProperty(
+ lhs, _visit(target), element, _visit(rhs));
+ }
+ }
+
+ return _badAssignment('Unhandled assignment', lhs, rhs);
+ }
+
+ JS.Expression _badAssignment(String problem, Expression lhs, Expression rhs) {
Jennifer Messerly 2016/06/07 23:04:20 do we know what can hit this? Is it a compiler bug
sra1 2016/06/07 23:56:07 It should be a compiler bug (e.g. List = null;). I
+ return js.call('dart.throw((#, #, #))',
+ [js.string('$lhs ='), _visit(rhs), js.string(problem)]);
+ }
+
+ /// Emits assignment to a simple identifier. Handles all legal simple
+ /// identifier assignment targets (local, top level library member, implicit
+ /// `this` or class, etc.).
+ JS.Expression _emitSetSimpleIdentifier(
+ SimpleIdentifier node, Expression rhs) {
+ JS.Expression unimplemented() {
+ return _badAssignment("Unimplemented: unknown name '$node'", node, rhs);
+ }
+
+ var accessor = node.staticElement;
+ if (accessor == null) return unimplemented();
+
+ // Get the original declaring element. If we had a property accessor, this
+ // indirects back to a (possibly synthetic) field.
+ var element = accessor;
+ if (accessor is PropertyAccessorElement) element = accessor.variable;
+
+ _declareBeforeUse(element);
+
+ if (element is LocalVariableElement || element is ParameterElement) {
+ return _emitSetLocal(node, element, rhs);
+ }
+
+ if (element.enclosingElement is CompilationUnitElement) {
+ // Top level library member.
+ return _emitSetTopLevel(node, element, rhs);
+ }
+
+ // Unqualified class member. This could mean implicit `this`, or implicit
+ // static from the same class.
+ if (element is ClassMemberElement) {
+ bool isStatic = element.isStatic;
+ if (isStatic) {
+ if (element is FieldElement) {
+ return _emitSetStaticProperty(node, element, rhs);
+ }
+ return unimplemented();
+ }
+
+ // For instance members, we add implicit-this.
+ if (element is FieldElement) {
+ return _emitWriteInstanceProperty(
+ node, new JS.This(), element, _visit(rhs));
+ }
+ return unimplemented();
+ }
+
+ // We should not get here.
+ return unimplemented();
+ }
+
+ /// Emits assignment to a simple local variable or parameter.
+ JS.Expression _emitSetLocal(
+ SimpleIdentifier node, Element element, Expression rhs) {
+ JS.Expression target;
+ if (element is TemporaryVariableElement) {
+ // If this is one of our compiler's temporary variables, use its JS form.
+ target = element.jsVariable;
+ } else if (element is ParameterElement) {
+ target = _emitParameter(element);
+ } else {
+ target = new JS.Identifier(element.name);
+ }
+
+ return _visit(rhs).toAssignExpression(annotate(target, node));
+ }
+
+ /// Emits assignment to library scope element [element].
+ JS.Expression _emitSetTopLevel(
+ Expression lhs, Element element, Expression rhs) {
+ return _visit(rhs)
+ .toAssignExpression(annotate(_emitTopLevelName(element), lhs));
+ }
+
+ /// Emits assignment to a static field element or property.
+ JS.Expression _emitSetStaticProperty(
+ Expression lhs, Element element, Expression rhs) {
+ // For static methods, we add the raw type name, without generics or
+ // library prefix. We don't need those because static calls can't use
+ // the generic type.
+ ClassElement classElement = element.enclosingElement;
+ var type = classElement.type;
+ var dynType = _emitType(fillDynamicTypeArgs(type));
+ var member = _emitMemberName(element.name, isStatic: true, type: type);
+ return _visit(rhs).toAssignExpression(
+ annotate(new JS.PropertyAccess(dynType, member), lhs));
+ }
+
+ /// Emits an assignment to the [element] property of instance referenced by
+ /// [jsTarget].
+ JS.Expression _emitWriteInstanceProperty(Expression lhs,
+ JS.Expression jsTarget, Element element, JS.Expression value) {
+ String memberName = element.name;
+ var type = (element.enclosingElement as ClassElement).type;
+ var name = _emitMemberName(memberName, type: type);
+ return value.toAssignExpression(
+ annotate(new JS.PropertyAccess(jsTarget, name), lhs));
+ }
+
+ JS.Expression _emitSetSuper(Expression lhs, SuperExpression target,
+ SimpleIdentifier id, Expression rhs) {
+ // TODO(sra): Fix.
Jennifer Messerly 2016/06/07 23:04:20 Fix what? :)
sra1 2016/06/07 23:56:07 Done.
return _visit(rhs).toAssignExpression(_visit(lhs));
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698