allow symbol replacement on multiple occurrences (#2472)
- all-or-nothing replacement - avoid unmangleable names fixes #2436
This commit is contained in:
@@ -796,8 +796,8 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function drop_decl(def) {
|
function drop_decl(def) {
|
||||||
def._eliminiated = (def._eliminiated || 0) + 1;
|
def.eliminated++;
|
||||||
if (def.orig.length == def._eliminiated) {
|
if (def.orig.length == def.eliminated) {
|
||||||
def.scope.functions.del(def.name);
|
def.scope.functions.del(def.name);
|
||||||
def.scope.variables.del(def.name);
|
def.scope.variables.del(def.name);
|
||||||
}
|
}
|
||||||
@@ -854,10 +854,14 @@ merge(Compressor.prototype, {
|
|||||||
// Locate symbols which may execute code outside of scanning range
|
// Locate symbols which may execute code outside of scanning range
|
||||||
var lvalues = get_lvalues(candidate);
|
var lvalues = get_lvalues(candidate);
|
||||||
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
||||||
var one_off = lhs instanceof AST_Symbol && lhs.definition().references.length == 1;
|
var replace_all = candidate.multiple;
|
||||||
|
if (!replace_all && lhs instanceof AST_SymbolRef) {
|
||||||
|
var def = lhs.definition();
|
||||||
|
replace_all = def.references.length - def.replaced == 1;
|
||||||
|
}
|
||||||
var side_effects = value_has_side_effects(candidate);
|
var side_effects = value_has_side_effects(candidate);
|
||||||
var hit = candidate.name instanceof AST_SymbolFunarg;
|
var hit = candidate.name instanceof AST_SymbolFunarg;
|
||||||
var abort = false, replaced = false, can_replace = !args || !hit;
|
var abort = false, replaced = 0, can_replace = !args || !hit;
|
||||||
var tt = new TreeTransformer(function(node, descend) {
|
var tt = new TreeTransformer(function(node, descend) {
|
||||||
if (abort) return node;
|
if (abort) return node;
|
||||||
// Skip nodes before `candidate` as quickly as possible
|
// Skip nodes before `candidate` as quickly as possible
|
||||||
@@ -886,7 +890,8 @@ merge(Compressor.prototype, {
|
|||||||
&& !(node instanceof AST_SymbolDeclaration)
|
&& !(node instanceof AST_SymbolDeclaration)
|
||||||
&& !is_lhs(node, parent)
|
&& !is_lhs(node, parent)
|
||||||
&& lhs.equivalent_to(node)) {
|
&& lhs.equivalent_to(node)) {
|
||||||
CHANGED = replaced = abort = true;
|
CHANGED = abort = true;
|
||||||
|
replaced++;
|
||||||
compressor.info("Collapsing {name} [{file}:{line},{col}]", {
|
compressor.info("Collapsing {name} [{file}:{line},{col}]", {
|
||||||
name: node.print_to_string(),
|
name: node.print_to_string(),
|
||||||
file: node.start.file,
|
file: node.start.file,
|
||||||
@@ -897,8 +902,13 @@ merge(Compressor.prototype, {
|
|||||||
return make_node(AST_UnaryPrefix, candidate, candidate);
|
return make_node(AST_UnaryPrefix, candidate, candidate);
|
||||||
}
|
}
|
||||||
if (candidate instanceof AST_VarDef) {
|
if (candidate instanceof AST_VarDef) {
|
||||||
|
if (candidate.multiple) {
|
||||||
|
abort = false;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
var def = candidate.name.definition();
|
var def = candidate.name.definition();
|
||||||
if (def.references.length == 1 && !compressor.exposed(def)) {
|
if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
|
||||||
|
def.replaced++;
|
||||||
return maintain_this_binding(parent, node, candidate.value);
|
return maintain_this_binding(parent, node, candidate.value);
|
||||||
}
|
}
|
||||||
return make_node(AST_Assign, candidate, {
|
return make_node(AST_Assign, candidate, {
|
||||||
@@ -922,7 +932,7 @@ merge(Compressor.prototype, {
|
|||||||
|| side_effects && !references_in_scope(node.definition()))
|
|| side_effects && !references_in_scope(node.definition()))
|
||||||
|| (sym = lhs_or_def(node))
|
|| (sym = lhs_or_def(node))
|
||||||
&& (sym instanceof AST_PropAccess || sym.name in lvalues)
|
&& (sym instanceof AST_PropAccess || sym.name in lvalues)
|
||||||
|| (side_effects || !one_off)
|
|| (side_effects || !replace_all)
|
||||||
&& (parent instanceof AST_Binary && lazy_op(parent.operator)
|
&& (parent instanceof AST_Binary && lazy_op(parent.operator)
|
||||||
|| parent instanceof AST_Case
|
|| parent instanceof AST_Case
|
||||||
|| parent instanceof AST_Conditional
|
|| parent instanceof AST_Conditional
|
||||||
@@ -935,7 +945,7 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_Default || node instanceof AST_Scope) return node;
|
if (node instanceof AST_Default || node instanceof AST_Scope) return node;
|
||||||
});
|
});
|
||||||
if (!can_replace) {
|
if (!can_replace) {
|
||||||
for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; j < args.length; j++) {
|
for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
|
||||||
args[j].transform(tt);
|
args[j].transform(tt);
|
||||||
}
|
}
|
||||||
can_replace = true;
|
can_replace = true;
|
||||||
@@ -943,6 +953,33 @@ merge(Compressor.prototype, {
|
|||||||
for (var i = stat_index; !abort && i < statements.length; i++) {
|
for (var i = stat_index; !abort && i < statements.length; i++) {
|
||||||
statements[i].transform(tt);
|
statements[i].transform(tt);
|
||||||
}
|
}
|
||||||
|
if (candidate.multiple) {
|
||||||
|
var def = candidate.name.definition();
|
||||||
|
if (abort && def.references.length > replaced) replaced = false;
|
||||||
|
else {
|
||||||
|
abort = false;
|
||||||
|
hit = candidate.name instanceof AST_SymbolFunarg;
|
||||||
|
var value_def = candidate.value.definition();
|
||||||
|
for (var i = stat_index; !abort && i < statements.length; i++) {
|
||||||
|
statements[i].transform(new TreeTransformer(function(node) {
|
||||||
|
if (abort) return node;
|
||||||
|
if (!hit) {
|
||||||
|
if (node === candidate) {
|
||||||
|
hit = true;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolRef && node.name == def.name) {
|
||||||
|
def.replaced++;
|
||||||
|
value_def.replaced--;
|
||||||
|
if (!--replaced) abort = true;
|
||||||
|
return candidate.value;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
|
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -956,7 +993,7 @@ merge(Compressor.prototype, {
|
|||||||
&& (iife = compressor.parent()) instanceof AST_Call
|
&& (iife = compressor.parent()) instanceof AST_Call
|
||||||
&& iife.expression === fn) {
|
&& iife.expression === fn) {
|
||||||
var fn_strict = compressor.has_directive("use strict");
|
var fn_strict = compressor.has_directive("use strict");
|
||||||
if (fn_strict && fn.body.indexOf(fn_strict) < 0) fn_strict = false;
|
if (fn_strict && !member(fn_strict, fn.body)) fn_strict = false;
|
||||||
var len = fn.argnames.length;
|
var len = fn.argnames.length;
|
||||||
args = iife.args.slice(len);
|
args = iife.args.slice(len);
|
||||||
var names = Object.create(null);
|
var names = Object.create(null);
|
||||||
@@ -1012,12 +1049,22 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mangleable_var(expr) {
|
||||||
|
var value = expr.value;
|
||||||
|
if (!(value instanceof AST_SymbolRef)) return false;
|
||||||
|
if (value.name == "arguments") return false;
|
||||||
|
if (value.definition().undeclared) return false;
|
||||||
|
expr.multiple = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function get_lhs(expr) {
|
function get_lhs(expr) {
|
||||||
if (expr instanceof AST_VarDef) {
|
if (expr instanceof AST_VarDef) {
|
||||||
var def = expr.name.definition();
|
var def = expr.name.definition();
|
||||||
if (def.orig.length - (def._eliminiated || 0) > 1
|
var declared = def.orig.length - def.eliminated;
|
||||||
&& !(expr.name instanceof AST_SymbolFunarg)
|
var referenced = def.references.length - def.replaced;
|
||||||
|| def.references.length == 1 && !compressor.exposed(def)) {
|
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
|
||||||
|
|| (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
|
||||||
return make_node(AST_SymbolRef, expr.name, expr.name);
|
return make_node(AST_SymbolRef, expr.name, expr.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -46,8 +46,10 @@
|
|||||||
function SymbolDef(scope, index, orig) {
|
function SymbolDef(scope, index, orig) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
|
this.eliminated = 0;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
|
this.replaced = 0;
|
||||||
this.global = false;
|
this.global = false;
|
||||||
this.mangled_name = null;
|
this.mangled_name = null;
|
||||||
this.undeclared = false;
|
this.undeclared = false;
|
||||||
|
|||||||
@@ -3098,3 +3098,423 @@ issue_2437: {
|
|||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2436_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log({
|
||||||
|
x: o.a,
|
||||||
|
y: o.b,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o.a = 3;
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o.a = 3;
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o = {
|
||||||
|
a: 3,
|
||||||
|
b: 4,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
o = {
|
||||||
|
a: 3,
|
||||||
|
b: 4,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
var o;
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(o) {
|
||||||
|
return {
|
||||||
|
x: o.a,
|
||||||
|
y: o.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(o) {
|
||||||
|
return {
|
||||||
|
x: o.a,
|
||||||
|
y: o.b,
|
||||||
|
};
|
||||||
|
}({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
x: 1,
|
||||||
|
y: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_7: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
x: 1,
|
||||||
|
y: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_8: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_9: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = console;
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = console;
|
||||||
|
console.log(function(c) {
|
||||||
|
return {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b,
|
||||||
|
};
|
||||||
|
}(o));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_10: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
function f(n) {
|
||||||
|
o = { b: 3 };
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
console.log(function(c) {
|
||||||
|
return [
|
||||||
|
c.a,
|
||||||
|
f(c.b),
|
||||||
|
c.b,
|
||||||
|
];
|
||||||
|
}(o).join(" "));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
function f(n) {
|
||||||
|
o = { b: 3 };
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
console.log(function(c) {
|
||||||
|
return [
|
||||||
|
c.a,
|
||||||
|
f(c.b),
|
||||||
|
c.b,
|
||||||
|
];
|
||||||
|
}(o).join(" "));
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_11: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function matrix() {}
|
||||||
|
function isCollection() {}
|
||||||
|
function _randomDataForMatrix() {}
|
||||||
|
function _randomInt() {}
|
||||||
|
function f(arg1, arg2) {
|
||||||
|
if (isCollection(arg1)) {
|
||||||
|
var size = arg1;
|
||||||
|
var max = arg2;
|
||||||
|
var min = 0;
|
||||||
|
var res = _randomDataForMatrix(size.valueOf(), min, max, _randomInt);
|
||||||
|
return size && true === size.isMatrix ? matrix(res) : res;
|
||||||
|
} else {
|
||||||
|
var min = arg1;
|
||||||
|
var max = arg2;
|
||||||
|
return _randomInt(min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function matrix() {}
|
||||||
|
function isCollection() {}
|
||||||
|
function _randomDataForMatrix() {}
|
||||||
|
function _randomInt() {}
|
||||||
|
function f(arg1, arg2) {
|
||||||
|
if (isCollection(arg1)) {
|
||||||
|
var size = arg1, max = arg2, min = 0, res = _randomDataForMatrix(size.valueOf(), min, max, _randomInt);
|
||||||
|
return size && true === size.isMatrix ? matrix(res) : res;
|
||||||
|
} else {
|
||||||
|
return _randomInt(min = arg1, max = arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2436_12: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function isUndefined() {}
|
||||||
|
function f() {
|
||||||
|
var viewValue = this.$$lastCommittedViewValue;
|
||||||
|
var modelValue = viewValue;
|
||||||
|
return isUndefined(modelValue) ? modelValue : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function isUndefined() {}
|
||||||
|
function f() {
|
||||||
|
var modelValue = this.$$lastCommittedViewValue;
|
||||||
|
return isUndefined(modelValue) ? modelValue : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user