1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview Variables mutator. 7 */ 8 9'use strict'; 10 11const babelTypes = require('@babel/types'); 12 13const common = require('./common.js'); 14const random = require('../random.js'); 15const mutator = require('./mutator.js'); 16 17function _isInFunctionParam(path) { 18 const child = path.find(p => p.parent && babelTypes.isFunction(p.parent)); 19 return child && child.parentKey === 'params'; 20} 21 22class VariableMutator extends mutator.Mutator { 23 constructor(settings) { 24 super(); 25 this.settings = settings; 26 } 27 28 get visitor() { 29 const thisMutator = this; 30 31 return { 32 Identifier(path) { 33 if (!random.choose(thisMutator.settings.MUTATE_VARIABLES)) { 34 return; 35 } 36 37 if (!common.isVariableIdentifier(path.node.name)) { 38 return; 39 } 40 41 // Don't mutate variables that are being declared. 42 if (babelTypes.isVariableDeclarator(path.parent)) { 43 return; 44 } 45 46 // Don't mutate function params. 47 if (_isInFunctionParam(path)) { 48 return; 49 } 50 51 if (common.isInForLoopCondition(path) || 52 common.isInWhileLoop(path)) { 53 return; 54 } 55 56 const randVar = common.randomVariable(path); 57 if (!randVar) { 58 return; 59 } 60 61 const newName = randVar.name; 62 thisMutator.annotate( 63 path.node, 64 `Replaced ${path.node.name} with ${newName}`); 65 path.node.name = newName; 66 } 67 }; 68 } 69} 70 71module.exports = { 72 VariableMutator: VariableMutator, 73}; 74