Skip to content

Commit

Permalink
Argument is read-only with in default argument expressions.
Browse files Browse the repository at this point in the history
jsx#327
(cherry picked from commit bbaabac)

Failed to compile when `bin/jsx --minify t/run/400.constant-param-
within-default-argument-expressions.jsx`.
The minifier count reference to the original `ArgumentDeclaration`, and
not clone but
I think need replace `LocalVariable` within `LocalExpression` like
`MemberFunctionDefinition#clone`.
  • Loading branch information
uchida_t committed May 21, 2014
1 parent 0173307 commit a75ffd9
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 6 deletions.
28 changes: 24 additions & 4 deletions src/analysis.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,7 @@ class LocalVariable implements Stashable {

function touchVariable (context : AnalysisContext, token : Token, isAssignment : boolean) : boolean {
if (isAssignment) {
if (this._isConstant && context.getTopBlock().localVariableStatuses.getStatus(this) != LocalVariableStatuses.UNSET) {
context.errors.push(new CompileError(token, "assignment of read-only variable"));
if (!this.canAssignment(context, token)) {
return false;
}
context.getTopBlock().localVariableStatuses.setStatus(this);
Expand Down Expand Up @@ -259,6 +258,15 @@ class LocalVariable implements Stashable {
return true;
}

function canAssignment (context : AnalysisContext, token : Token) : boolean {
if (this._isConstant && context.getTopBlock().localVariableStatuses.getStatus(this) != LocalVariableStatuses.UNSET) {
context.errors.push(new CompileError(token, "assignment of read-only variable"));
return false;
}
return true;
}


override function toString () : string {
return this._name.getValue() + " : " + this._type.toString();
}
Expand Down Expand Up @@ -324,8 +332,13 @@ class ArgumentDeclaration extends LocalVariable {
this._defaultValue = defaultValue;
}

function constructor (name : Token, type : Type, isConst : boolean, defaultValue : Expression) {
super(name, type, isConst);
this._defaultValue = defaultValue;
}

function clone () : ArgumentDeclaration {
return new ArgumentDeclaration(this._name, this._type, Util.cloneNullable(this._defaultValue));
return new ArgumentDeclaration(this._name, this._type, this._isConstant, Util.cloneNullable(this._defaultValue));
}

function getDefaultValue() : Expression {
Expand All @@ -334,13 +347,20 @@ class ArgumentDeclaration extends LocalVariable {

override function _instantiate (instantiationContext : InstantiationContext) : ArgumentDeclaration {
var type = this._type != null ? this._type.instantiate(instantiationContext, false) : null;
return new ArgumentDeclaration(this._name, type, this._defaultValue);
return new ArgumentDeclaration(this._name, type, this._isConstant, this._defaultValue);
}

override function instantiateAndPush (instantiationContext : InstantiationContext) : ArgumentDeclaration {
return super.instantiateAndPush(instantiationContext) as ArgumentDeclaration;
}

override function canAssignment (context : AnalysisContext, token : Token) : boolean {
if (this._isConstant) {
context.errors.push(new CompileError(token, "The preceding argument is read-only within the default argument expression"));
return false;
}
return true;
}
}

class LocalVariableStatuses {
Expand Down
2 changes: 1 addition & 1 deletion src/classdef.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ class MemberFunctionDefinition extends MemberDefinition implements Block {
for (; origArgIndex != this.getArguments().length; ++origArgIndex) {
// build list of formal args (of the generated function)
var formalArgs = this.getArguments().slice(0, origArgIndex).map.<ArgumentDeclaration>((arg) -> {
return new ArgumentDeclaration(arg.getName(), arg.getType());
return new ArgumentDeclaration(arg.getName(), arg.getType(), true, null);
});
// build function body
var argExprs = formalArgs.map.<Expression>((arg) -> {
Expand Down
2 changes: 1 addition & 1 deletion src/parser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3447,7 +3447,7 @@ class Parser {
var assignToken = this._expectOpt("=");
if (assignToken != null) {
var state = this._preserveState();
this._pushScope(null, args);
this._pushScope(null, args.map(arg => new ArgumentDeclaration(arg.getName(), arg.getType(), true, arg.getDefaultValue())));
try {
if ((defaultValue = this._assignExpr(true)) == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class C {

function fn(a : number, b : number = ++a) : void {
}

}
16 changes: 16 additions & 0 deletions t/run/400.constant-param-within-default-argument-expressions.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*EXPECTED
1
1
*/
class _Main {

static function fn(a : number, b : () => number = () => a) : void {
log b();
a = 10;
log b();
}

static function main(args : string[]) : void {
_Main.fn(1);
}
}

0 comments on commit a75ffd9

Please sign in to comment.