});
AST_Symbol.DEFMETHOD("has_const_pragma", function() {
- var token = this.scope.body[0] && this.scope.body[0].start;
- var comments = token && token.comments_before;
- if (comments && comments.length > 0) {
- var last = comments[comments.length - 1];
- return /@const/.test(last.value);
- }
- return false;
+ var symbol = this;
+ var symbol_has_pragma = false;
+ var pragma_found = false;
+ var found_symbol = false;
+ // Walk the current scope, looking for a comment with the @const pragma.
+ // If it exists, mark a bool that will remain true only for the next iteration.
+ // If the next iteration is this symbol, then we return true.
+ // Otherwise we stop descending and get out of here.
+ var tw = new TreeWalker(function(node, descend){
+ // This is our symbol. Was the pragma before this?
+ if (node.name === symbol) {
+ found_symbol = true;
+ symbol_has_pragma = pragma_found;
+ }
+
+ // Look for the /** @const */ pragma
+ var comments_before = node.start && node.start.comments_before;
+ var lastComment = comments_before && comments_before[comments_before.length - 1];
+ pragma_found = lastComment && /@const/.test(lastComment.value);
+
+ // no need to descend after finding our node
+ return found_symbol;
+ });
+ this.scope.walk(tw);
+ return symbol_has_pragma;
})
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
evaluate : true\r
};\r
input: {\r
+ var unused;\r
const CONST_FOO = false;\r
if (CONST_FOO) {\r
console.log("unreachable");\r
}\r
}\r
expect: {\r
+ var unused;\r
const CONST_FOO = !1;\r
var moo;\r
function bar() {}\r
evaluate : true\r
};\r
input: {\r
- /** @const*/ var CONST_FOO_ANN = false;\r
+ var unused;\r
+ /** @const */ var CONST_FOO_ANN = false;\r
if (CONST_FOO_ANN) {\r
console.log("unreachable");\r
var moo;\r
}\r
}\r
expect: {\r
+ var unused;\r
var CONST_FOO_ANN = !1;\r
var moo;\r
function bar() {}\r
}\r
}\r
+\r
+dead_code_const_annotation_complex_scope: {\r
+ options = {\r
+ dead_code : true,\r
+ loops : true,\r
+ booleans : true,\r
+ conditionals : true,\r
+ evaluate : true\r
+ };\r
+ input: {\r
+ var unused_var;\r
+ /** @const */ var test = 'test';\r
+ /** @const */ var CONST_FOO_ANN = false;\r
+ var unused_var_2;\r
+ if (CONST_FOO_ANN) {\r
+ console.log("unreachable");\r
+ var moo;\r
+ function bar() {}\r
+ }\r
+ if (test === 'test') {\r
+ var beef = 'good';\r
+ /** @const */ var meat = 'beef';\r
+ var pork = 'bad';\r
+ if (meat === 'pork') {\r
+ console.log('also unreachable');\r
+ } else if (pork === 'good') {\r
+ console.log('reached, not const');\r
+ }\r
+ }\r
+ }\r
+ expect: {\r
+ var unused_var;\r
+ var test = 'test';\r
+ var CONST_FOO_ANN = !1;\r
+ var unused_var_2;\r
+ var moo;\r
+ function bar() {}\r
+ var beef = 'good';\r
+ var meat = 'beef';\r
+ var pork = 'bad';\r
+ 'good' === pork && console.log('reached, not const');\r
+ }\r
+}\r