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

Unified Diff: frog/frogsh

Issue 8586020: Treat assignment to final as an error (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: update status Created 9 years, 1 month 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 | frog/gen.dart » ('j') | frog/gen.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/frogsh
diff --git a/frog/frogsh b/frog/frogsh
index 565bdd919643c789f67b6890a7d7676a1960a22c..df9cdeb6af82d8ec5291aec0e8255e45c8760488 100755
--- a/frog/frogsh
+++ b/frog/frogsh
@@ -11027,7 +11027,7 @@ BlockScope.prototype._isDefinedInParent = function(name) {
if (type.get$library().lookup(name, null) != null) return true;
return false;
}
-BlockScope.prototype.create = function(name, type, span, isParameter) {
+BlockScope.prototype.create = function(name, type, span, isFinal, isParameter) {
var jsName = world.toJsIdentifier(name);
if (this._vars.containsKey(name)) {
world.error(('duplicate name "' + name + '"'), span);
@@ -11039,15 +11039,16 @@ BlockScope.prototype.create = function(name, type, span, isParameter) {
}
}
var ret = new Value(type, jsName, span, false);
+ ret.isFinal = isFinal;
this._vars.$setindex(name, ret);
return (ret && ret.is$Value());
}
BlockScope.prototype.declareParameter = function(p) {
- return this.create(p.name, p.type, p.definition.span, true);
+ return this.create(p.name, p.type, p.definition.span, false, true);
}
BlockScope.prototype.declare = function(id) {
var type = this.enclosingMethod.method.resolveType(id.type, false);
- return this.create(id.name.name, (type && type.is$lang_Type()), id.span, false);
+ return this.create(id.name.name, (type && type.is$lang_Type()), id.span, false, false);
}
BlockScope.prototype.getRethrow = function() {
var scope = this;
@@ -11076,7 +11077,7 @@ function MethodGenerator(method, enclosingMethod) {
}
if (this.enclosingMethod != null && this.method.name != '') {
var m = (($0 = this.method) && $0.is$MethodMember());
- this._scope.create(m.name, m.get$functionType(), m.definition.span, false);
+ this._scope.create(m.name, m.get$functionType(), m.definition.span, true, false);
}
this._usedTemps = new HashSetImplementation();
this._freeTemps = [];
@@ -11200,7 +11201,7 @@ MethodGenerator.prototype.writeDefinition = function(defWriter, lambda) {
defWriter.writeln('var \$this = this; // closure support');
}
if (this._usedTemps.get$length() > 0 || this._freeTemps.length > 0) {
- $assert(this._usedTemps.get$length() == 0, "_usedTemps.length == 0", "gen.dart", 705, 14);
+ $assert(this._usedTemps.get$length() == 0, "_usedTemps.length == 0", "gen.dart", 706, 14);
this._freeTemps.addAll(this._usedTemps);
this._freeTemps.sort((function (x, y) {
return x.compareTo$1(y);
@@ -11383,7 +11384,7 @@ MethodGenerator.prototype.writeBody = function() {
for (var $i = this.method.declaringType.get$members().getKeys().iterator$0(); $i.hasNext$0(); ) {
var name = $i.next$0();
var member = this.method.declaringType.get$members().$index(name);
- if ((member instanceof FieldMember) && $notnull_bool(member.isFinal) && !$notnull_bool(member.get$isStatic()) && !$notnull_bool(initializedFields.contains$1(name))) {
+ if ((member instanceof FieldMember) && $notnull_bool(member.get$isFinal()) && !$notnull_bool(member.get$isStatic()) && !$notnull_bool(initializedFields.contains$1(name))) {
world.error(('Field "' + name + '" is final and was not initialized'), this.method.get$definition().get$span());
}
}
@@ -11520,7 +11521,7 @@ MethodGenerator.prototype.visitVariableDefinition = function(node) {
if ($notnull_bool(thisType.get$isVar())) thisType = value.type;
}
}
- var val = this._scope.create($assert_String(name), (thisType && thisType.is$lang_Type()), node.names.$index(i).get$span(), false);
+ var val = this._scope.create($assert_String(name), (thisType && thisType.is$lang_Type()), node.names.$index(i).get$span(), $assert_bool(isFinal), false);
if ($notnull_bool(value == null)) {
if ($notnull_bool(this._scope.reentrant)) {
this.writer.write(('' + val.code + ' = null'));
@@ -11541,7 +11542,7 @@ MethodGenerator.prototype.visitFunctionDefinition = function(node) {
var $0;
var name = world.toJsIdentifier(node.name.name);
var meth = this._makeLambdaMethod($assert_String(name), node);
- var funcValue = this._scope.create($assert_String(name), (($0 = meth.get$functionType()) && $0.is$lang_Type()), this.method.get$definition().get$span(), false);
+ var funcValue = this._scope.create($assert_String(name), (($0 = meth.get$functionType()) && $0.is$lang_Type()), this.method.get$definition().get$span(), true, false);
meth.generator.writeDefinition$2(this.writer);
return false;
}
@@ -11666,20 +11667,27 @@ MethodGenerator.prototype.visitForStatement = function(node) {
this._popBlock();
return false;
}
+MethodGenerator.prototype._isFinal = function(typeRef) {
+ if ((typeRef instanceof GenericTypeReference)) {
+ typeRef = typeRef.baseType;
+ }
+ return $notnull_bool($ne(typeRef, null)) && $notnull_bool(typeRef.get$isFinal());
+}
MethodGenerator.prototype.visitForInStatement = function(node) {
var $0;
var itemType = this.method.resolveType(node.item.type, false);
var itemName = node.item.name.name;
var list = node.list.visit(this);
this._pushBlock(true);
- var item = this._scope.create($assert_String(itemName), (itemType && itemType.is$lang_Type()), node.item.name.span, false);
+ var isFinal = this._isFinal(node.item.type);
+ var item = this._scope.create($assert_String(itemName), (itemType && itemType.is$lang_Type()), node.item.name.span, isFinal, false);
var listVar = (list && list.is$Value());
if ($notnull_bool(list.needsTemp)) {
- listVar = this._scope.create('\$list', (($0 = list.type) && $0.is$lang_Type()), null, false);
+ listVar = this._scope.create('\$list', (($0 = list.type) && $0.is$lang_Type()), null, false, false);
this.writer.writeln(('var ' + listVar.code + ' = ' + list.code + ';'));
}
if ($notnull_bool(list.type.get$isList())) {
- var tmpi = this._scope.create('\$i', world.numType, null, false);
+ var tmpi = this._scope.create('\$i', world.numType, null, false, false);
this.writer.enterBlock(('for (var ' + tmpi.code + ' = 0;') + ('' + tmpi.code + ' < ' + listVar.code + '.length; ' + tmpi.code + '++) {'));
var value = listVar.invoke(this, '\$index', node.list, new Arguments(null, [tmpi]), false);
this.writer.writeln(('var ' + item.code + ' = ' + value.code + ';'));
@@ -11687,7 +11695,7 @@ MethodGenerator.prototype.visitForInStatement = function(node) {
else {
this._pushBlock(false);
var iterator = list.invoke$4(this, 'iterator', node.list, Arguments.get$EMPTY());
- var tmpi = this._scope.create('\$i', (($0 = iterator.type) && $0.is$lang_Type()), null, false);
+ var tmpi = this._scope.create('\$i', (($0 = iterator.type) && $0.is$lang_Type()), null, false, false);
var hasNext = tmpi.invoke$4(this, 'hasNext', node.list, Arguments.get$EMPTY());
var next = tmpi.invoke$4(this, 'next', node.list, Arguments.get$EMPTY());
this.writer.enterBlock(('for (var ' + tmpi.code + ' = ' + iterator.code + '; ' + hasNext.code + '; ) {'));
@@ -11738,7 +11746,7 @@ MethodGenerator.prototype.visitTryStatement = function(node) {
}
else if (node.catches.length > 0) {
this._pushBlock(false);
- var ex = this._scope.create('\$ex', world.varType, null, false);
+ var ex = this._scope.create('\$ex', world.varType, null, false, false);
this._scope.rethrow = (ex && ex.is$Value());
this.writer.nextBlock(('} catch (' + ex.code + ') {'));
var trace = null;
@@ -11746,7 +11754,7 @@ MethodGenerator.prototype.visitTryStatement = function(node) {
return c.trace != null;
})
)) {
- trace = this._scope.create('\$trace', world.varType, null, false);
+ trace = this._scope.create('\$trace', world.varType, null, false, false);
this.writer.writeln(('var ' + trace.code + ' = \$stackTraceOf(' + ex.code + ');'));
world.gen.corejs.useStackTraceOf = true;
}
@@ -12066,6 +12074,9 @@ MethodGenerator.prototype._visitVarAssign = function(kind, xn, yn, position, cap
}
}
}
+ if ($notnull_bool(x.get$isFinal())) {
+ world.error(('final variable "' + x.code + '" is not assignable'), position.span);
+ }
y = y.convertTo$3(this, x.type, yn);
if (kind == 0) {
x = captureOriginal((x && x.is$Value()));
@@ -12206,7 +12217,7 @@ MethodGenerator.prototype.visitNewExpression = function(node) {
var names = ListFactory.ListFactory$from$factory((($0 = typeRef.names) && $0.is$Iterable()));
constructorName = names.removeLast$0().get$name();
if (names.length == 0) names = null;
- typeRef = new NameTypeReference(typeRef.isFinal, typeRef.get$name(), names, typeRef.get$span());
+ typeRef = new NameTypeReference(typeRef.get$isFinal(), typeRef.get$name(), names, typeRef.get$span());
}
var type = this.method.resolveType((typeRef && typeRef.is$TypeReference()), true);
if ($notnull_bool(type.get$isTop())) {
@@ -12358,7 +12369,7 @@ MethodGenerator.prototype.visitNullExpression = function(node) {
MethodGenerator.prototype.visitLiteralExpression = function(node) {
var $0;
var type = node.type.type;
- $assert($ne(type, null), "type != null", "gen.dart", 2106, 12);
+ $assert($ne(type, null), "type != null", "gen.dart", 2119, 12);
if (!!(($0 = node.value) && $0.is$List)) {
var items = [];
var $list = node.value;
@@ -13213,6 +13224,8 @@ FieldMember.prototype.get$type = function() { return this.type; };
FieldMember.prototype.set$type = function(value) { return this.type = value; };
FieldMember.prototype.get$isStatic = function() { return this.isStatic; };
FieldMember.prototype.set$isStatic = function(value) { return this.isStatic = value; };
+FieldMember.prototype.get$isFinal = function() { return this.isFinal; };
+FieldMember.prototype.set$isFinal = function(value) { return this.isFinal = value; };
FieldMember.prototype.get$isNative = function() { return this.isNative; };
FieldMember.prototype.set$isNative = function(value) { return this.isNative = value; };
FieldMember.prototype.override = function(other) {
@@ -18041,6 +18054,9 @@ TypeReference.prototype.set$type = function(value) { return this.type = value; }
TypeReference.prototype.visit = function(visitor) {
return visitor.visitTypeReference(this);
}
+TypeReference.prototype.get$isFinal = function() {
+ return false;
+}
TypeReference.prototype.visit$1 = function($0) {
return this.visit(($0 && $0.is$TreeVisitor()));
};
@@ -18698,6 +18714,8 @@ function NameTypeReference(isFinal, name, names, span) {
}
$inherits(NameTypeReference, TypeReference);
NameTypeReference.prototype.is$NameTypeReference = function(){return this;};
+NameTypeReference.prototype.get$isFinal = function() { return this.isFinal; };
+NameTypeReference.prototype.set$isFinal = function(value) { return this.isFinal = value; };
NameTypeReference.prototype.get$name = function() { return this.name; };
NameTypeReference.prototype.set$name = function(value) { return this.name = value; };
NameTypeReference.prototype.visit = function(visitor) {
@@ -18731,6 +18749,8 @@ function FunctionTypeReference(isFinal, func, span) {
}
$inherits(FunctionTypeReference, TypeReference);
FunctionTypeReference.prototype.is$FunctionTypeReference = function(){return this;};
+FunctionTypeReference.prototype.get$isFinal = function() { return this.isFinal; };
+FunctionTypeReference.prototype.set$isFinal = function(value) { return this.isFinal = value; };
FunctionTypeReference.prototype.visit = function(visitor) {
return visitor.visitFunctionTypeReference(this);
}
@@ -20209,6 +20229,7 @@ FixedIterator$E.prototype.is$Iterator$T = function(){return this;};
function Value(type, code, span, needsTemp) {
this.isSuper = false
this.isType = false
+ this.isFinal = false
this.type = type;
this.code = code;
this.span = span;
@@ -20221,6 +20242,8 @@ Value.prototype.get$type = function() { return this.type; };
Value.prototype.set$type = function(value) { return this.type = value; };
Value.prototype.get$span = function() { return this.span; };
Value.prototype.set$span = function(value) { return this.span = value; };
+Value.prototype.get$isFinal = function() { return this.isFinal; };
+Value.prototype.set$isFinal = function(value) { return this.isFinal = value; };
Value.prototype.get$_typeIsVarOrParameterType = function() {
return $notnull_bool(this.type.get$isVar()) || (this.type instanceof ParameterType);
}
@@ -20502,8 +20525,8 @@ Value.prototype.invokeNoSuchMethod = function(context, name, node, args) {
return this._resolveMember(context, 'noSuchMethod', node, false).invoke$4(context, node, this, new Arguments(null, noSuchArgs));
}
Value.prototype.invokeSpecial = function(name, args, returnType) {
- $assert(name.startsWith('\$'), "name.startsWith('\\$')", "value.dart", 480, 12);
- $assert(!$notnull_bool(args.get$hasNames()), "!args.hasNames", "value.dart", 481, 12);
+ $assert(name.startsWith('\$'), "name.startsWith('\\$')", "value.dart", 483, 12);
+ $assert(!$notnull_bool(args.get$hasNames()), "!args.hasNames", "value.dart", 484, 12);
var argsString = args.getCode();
if (name == '\$index' || name == '\$setindex') {
return new Value(returnType, ('' + this.code + '.' + name + '(' + argsString + ')'), this.span, true);
@@ -20638,7 +20661,7 @@ GlobalValue.prototype.is$Comparable = function(){return this;};
GlobalValue.GlobalValue$fromStatic$factory = function(field, exp, dependencies) {
var code = ($notnull_bool(exp.get$isConst()) ? exp.get$canonicalCode() : exp.code);
var codeWithComment = ('' + code + '/*' + field.declaringType.name + '.' + field.get$name() + '*/');
- return new GlobalValue(exp.type, $assert_String(codeWithComment), field.isFinal, field, null, exp, code, exp.span, dependencies.filter$1((function (d) {
+ return new GlobalValue(exp.type, $assert_String(codeWithComment), field.get$isFinal(), field, null, exp, code, exp.span, dependencies.filter$1((function (d) {
return (d instanceof GlobalValue);
})
));
@@ -20702,10 +20725,10 @@ function BareValue(home, outermost, span) {
}
$inherits(BareValue, Value);
BareValue.prototype._tryResolveMember = function(context, name) {
- $assert($eq(context, this.home), "context == home", "value.dart", 685, 12);
+ $assert($eq(context, this.home), "context == home", "value.dart", 688, 12);
var member = this.type.resolveMember(name);
if ($notnull_bool($ne(member, null))) {
- $assert(this.code == null, "code == null", "value.dart", 690, 14);
+ $assert(this.code == null, "code == null", "value.dart", 693, 14);
if ($notnull_bool(this.isType)) {
this.code = this.type.get$jsname();
}
« no previous file with comments | « no previous file | frog/gen.dart » ('j') | frog/gen.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698