All files / src index.js

100% Statements 93/93
96.67% Branches 29/30
100% Functions 17/17
100% Lines 88/88

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143  1x   1x   1x   1x 1x   1x 6123x 841x         841x     1x   1x 37x 37x 37x 37x 37x   37x       1x 64x 64x 64x   64x       1x 64x 64x 64x 64x 2x 8x 8x   5x     64x       1x 64x 64x 64x 64x 2x 8x 8x   7x     64x       1x 7x       7x   841x 2x 1x 1x 1x 1x 1x 1x 1x 1x       1x 1x 1x 1x 1x 1x 1x 1x       37x 1x 1x   1x       64x 1x 1x 1x 1x   1x   64x 1x 1x 1x 1x   1x   64x 1x 1x 1x 1x 1x 1x 1x       7x    
// js代码转AST
const parser = require("@babel/parser");
//从AST中找到相应的节点
const traverse = require("@babel/traverse").default;
//提供了很多和 AST 的 Node 节点相关的辅助函数
const t = require("@babel/types");
//将 AST 树重新转为对应的代码字符串
const generate = require("babel-generator").default;
const template = require("@babel/template").default;
 
const isIwant_replaceElement = (path) => {
  const createMenuEntryParent = path.findParent(path => path.isMemberExpression());
  const isIwant = t.isIdentifier(path.node, {name: "_createMenuEntry"})
    && createMenuEntryParent.node
    && createMenuEntryParent.node.object
    && createMenuEntryParent.node.object.object
    && createMenuEntryParent.node.object.object.name === "ReplaceMenuProvider";
  return isIwant;
};
 
const isIwant_commandStack = (path) => path.node && path.node.id && path.node.id.name === "CommandInitializer";
 
const isIwant_initBpmn = (path)=>{
  let isIwantLeftPropertiesName = false;
  let isIwantLeftInstanceName = false;
  try{
    isIwantLeftPropertiesName = path.get("left.property").isIdentifier({name:"_init"});
    isIwantLeftInstanceName = path.get("left.object.object").isIdentifier({name:"PropertiesPanel"});
  }finally {
    return isIwantLeftPropertiesName && isIwantLeftInstanceName;
  }
};
 
const isIwant_elementDocuEntry = (path)=>{
  let  isIwantVariableDeclarations = false;
  try{
    isIwantVariableDeclarations = path.get("declarations.0").node.id.name === "processRef";
  }finally {
    return isIwantVariableDeclarations;
  }
};
 
const isIwant_conditionalEntry = (path)=>{
  let  isIwantConditionalEntry = false;
  try{
    const node = path.get("declarations.0").node;
    if(node.id.name === "bo" && node.init.callee.name === "getBusinessObject"){
      const moduleExportsParams=path.parentPath.parent.params.reduce((result,item)=>{
        result.push(item.name);
        return result;
      },[]);
      isIwantConditionalEntry = ["group","element","bpmnFactory","translate"].every(item=>moduleExportsParams.includes(item));
    }
  }finally {
    return isIwantConditionalEntry ;
  }
};
 
const isIwant_Element_BusinessObject =(path) =>{
  let isIwantElementAndBusinessObject = false;
  try{
    const node = path.get("declarations.0").node;
    if(node.id.name === "bo" && node.init.callee.name === "getBusinessObject"){
      const moduleExportsParams=path.parentPath.parent.params.reduce((result,item)=>{
        result.push(item.name);
        return result;
      },[]);
      isIwantElementAndBusinessObject = ["element","bpmnFactory","options","translate"].every(item=>moduleExportsParams.includes(item));
    }
  }finally {
    return isIwantElementAndBusinessObject;
  }
};
 
module.exports = function (source) {
  let ast = parser.parse(source, {
    sourceType: "module",
    plugins: ["dynamicImport"]
  });
  traverse(ast, {
    Identifier(path) {
      if (isIwant_replaceElement(path)) {
        const parent = path.findParent(path => path.isAssignmentExpression());
        const rightFunctionExpression = parent.get("right");
        const functionBody = rightFunctionExpression.get("body").get("body");
        const astVmReplaceElement_1 = template.ast(`var vm=window.vm.$children[0];`);
        const astVmReplaceElement_2 = template.ast(`vm.$set(vm.bpmnPanel,'replaceElement',replaceElement);`);
        const astVmReplaceElement_3 = template.ast(`window.bpmnPanel.replaceElement = replaceElement;`);
        functionBody[2].insertBefore(astVmReplaceElement_1);
        functionBody[2].insertBefore(astVmReplaceElement_2);
        functionBody[2].insertBefore(astVmReplaceElement_3);
      }
    },
    FunctionDeclaration(path) {
      Eif(isIwant_commandStack(path)){
        const functionBody = path.get("body").get("body");
        const astCommandStackVm = template.ast(`var vm=window.vm.$children[0];`);
        const astCommandStackVmSet = template.ast(`vm.$set(vm.bpmnPanel,'bpmnPanelCommandStack',commandStack);`);
        const astCommandStack = template.ast(`window.bpmnPanel.bpmnPanelCommandStack=commandStack;`);
        functionBody[0].insertBefore(astCommandStackVm);
        functionBody[0].insertBefore(astCommandStackVmSet);
        functionBody[0].insertBefore(astCommandStack);
      }
    },
    AssignmentExpression(path) {
      if(isIwant_initBpmn(path)){
        const functionBody = path.get("right.body.body");
        const astBpmnPanel = template.ast(`window.bpmnPanel={};`);
        //[NodePath...] NodePath可以使用insertBefore方法
        functionBody[0].insertBefore(astBpmnPanel);
      }
    },
    VariableDeclaration(path){
      if(isIwant_elementDocuEntry(path)){
        const astBpmnPanelElementDocuEntryVm = template.ast(`var vm=window.vm.$children[0];`);
        const astBpmnPanelElementDocuEntryVmSet = template.ast(`vm.$set(vm.bpmnPanel,'bpmnPanelElementDocuEntry',group.entries[0]);`);
        const astBpmnPanelElementDocuEntry = template.ast(`window.bpmnPanel.bpmnPanelElementDocuEntry=group.entries[0];`);
        const functionBody = path.container;
        //[Node...] Node类型不能使用insertBefore方法
        functionBody.splice(path.key,0,astBpmnPanelElementDocuEntryVm,astBpmnPanelElementDocuEntryVmSet,astBpmnPanelElementDocuEntry);
      }
      if(isIwant_conditionalEntry(path)){
        const astBpmnPanelConditionalEntryVm = template.ast(`var vm=window.vm.$children[0];`);
        const astBpmnPanelConditionalEntryVmSet = template.ast(`vm.$set(vm.bpmnPanel,'bpmnPanelConditionalEntry',group.entries[0]);`);
        const astBpmnPanelConditionalEntry = template.ast(`window.bpmnPanel.bpmnPanelConditionalEntry=group.entries[0];`);
        const functionBody = path.container;
        //[Node...] Node类型不能使用insertBefore方法
        functionBody.push(...[astBpmnPanelConditionalEntryVm,astBpmnPanelConditionalEntryVmSet,astBpmnPanelConditionalEntry]);
      }
      if(isIwant_Element_BusinessObject(path)){
        const astVm = template.ast(`var vm=window.vm.$children[0];`);
        const astElementVmSet = template.ast(`vm.$set(vm.bpmnPanel,'bpmnPanelElement',element);`);
        const astBusinessObjectVmSet = template.ast(`vm.$set(vm.bpmnPanel,'bpmnPanelBusinessObject',bo);`);
        const astElement = template.ast(`window.bpmnPanel.bpmnPanelElement=element;`);
        const astBusinessObject = template.ast(`window.bpmnPanel.bpmnPanelBusinessObject=bo;`);
        const functionBody = path.container;
        functionBody.splice(path.key+1,0,astVm,astElementVmSet,astBusinessObjectVmSet,astElement,astBusinessObject);
      }
    }
  });
  return generate(ast).code;
};