Index: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
index 9afaa960ff8c18be543a9365a0a9c18fe30f097c..51b1e1b0b8d1735938f11aaaac35e5510125ecc9 100644 |
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java |
@@ -1622,6 +1622,7 @@ public class TypeAnalyzer implements DartCompilationPhase { |
case FIELD: |
FieldElement fieldElement = (FieldElement) element; |
+ Modifiers fieldModifiers = fieldElement.getModifiers(); |
MethodElement getter = fieldElement.getGetter(); |
MethodElement setter = fieldElement.getSetter(); |
boolean inSetterContext = Elements.inSetterContext(node); |
@@ -1630,8 +1631,14 @@ public class TypeAnalyzer implements DartCompilationPhase { |
if (fieldElement.getEnclosingElement() instanceof ClassElement) { |
enclosingClass = (ClassElement) fieldElement.getEnclosingElement(); |
} |
+ |
+ // Implicit field declared as "final". |
+ if (!fieldModifiers.isAbstractField() && fieldModifiers.isFinal() && inSetterContext) { |
+ return typeError(node.getName(), TypeErrorCode.FIELD_IS_FINAL, node.getName()); |
+ } |
+ |
// Check for cases when property has no setter or getter. |
- if (fieldElement.getModifiers().isAbstractField() && enclosingClass != null) { |
+ if (fieldModifiers.isAbstractField() && enclosingClass != null) { |
// Check for using field without getter in other operation that assignment. |
if (inGetterContext) { |
if (getter == null) { |
@@ -1655,7 +1662,7 @@ public class TypeAnalyzer implements DartCompilationPhase { |
} |
Type result = member.getType(); |
- if (fieldElement.getModifiers().isAbstractField()) { |
+ if (fieldModifiers.isAbstractField()) { |
if (inSetterContext) { |
result = member.getSetterType(); |
if (result == null) { |