public List<RefactorException> replace(final Script script, Function f) {
    final List<ExprStmt> calls = new LinkedList<ExprStmt>();
    System.out.println("Script Name: " + script.getName());
    NodeFinder.apply(
        ExprStmt.class,
        context.cu,
        new AbstractNodeFunction<ExprStmt>() {

          @Override
          public void apply(ExprStmt node) {
            if (node.getExpr() instanceof NameExpr
                && ((NameExpr) node.getExpr()).getName().getID().equals(script.getName()))
              calls.add(node);
          }
        });
    f.setStmtList(script.getStmtList().copy());
    FunctionList fl = new FunctionList();
    fl.addFunction(f);
    fl.setFile(script.getFile());
    f.setParent(fl.getFunctionList());
    LivenessAnalysis live = new LivenessAnalysis(script);
    VFFlowInsensitiveAnalysis scriptKind = new VFFlowInsensitiveAnalysis(script);
    ReachingDefs scriptReaching = new ReachingDefs(script);
    live.analyze();
    scriptKind.analyze();
    scriptReaching.analyze();

    Set<String> scriptLiveVars = live.getOutFlowSets().get(script).getSet();
    Set<String> assignedVars = new HashSet<String>();
    for (Map.Entry<String, Set<Def>> entry :
        scriptReaching.getOutFlowSets().get(script).toMap().entrySet()) {
      if (entry.getValue().contains(ReachingDefs.UNDEF) || entry.getValue().isEmpty()) continue;
      assignedVars.add(entry.getKey());
    }
    //		Set<String> shouldNotBeAssigned = new HashSet<String>();
    List<RefactorException> errors = new LinkedList<RefactorException>();
    TreeSet<String> inputArgs = null;
    TreeSet<String> outputArgs = null;
    boolean inlined = false;

    System.out.println(
        script.getPrettyPrinted()
            + "\nAssigned:"
            + assignedVars
            + "\nLive:"
            + scriptLiveVars
            + " Calls: "
            + calls);

    for (ExprStmt call : calls) {
      Name name = ((NameExpr) call.getExpr()).getName();
      Function callFunc = NodeFinder.findParent(Function.class, call);
      if (callFunc == null) { // called inside script
        errors.add(new Exceptions.ScriptCalledFromScript(name));
        return errors;
      }
      // int offset = NodeFinder.find(callFunc, ExprStmt.class).indexOf(call);
      //            callFunc = callFunc.fullCopy();
      //		call = NodeFinder.find(callFunc, ExprStmt.class).get(offset);

      // MScriptInliner scriptInliner = new MScriptInliner(context.cu);
      // for (ExprStmt toInline : NodeFinder.find(callFunc, ExprStmt.class)){
      //		if (toInline != call){
      //       if (toInline.getChild(0) instanceof NameExpr)

      // scriptInliner.inlineStmt(callFunc, toInline, new LinkedList<Exception>());
      //         inlined = true;
      //                }
      // }
      if (inlined) {
        System.out.println(name + "\n" + callFunc.getPrettyPrinted());
      }
      TreeSet<String> inputArgsCurrent = new TreeSet<String>();
      TreeSet<String> outputArgsCurrent = new TreeSet<String>();
      ReachingDefs mayReach = new ReachingDefs(callFunc);
      LivenessAnalysis callLive = new LivenessAnalysis(callFunc);
      mayReach.analyze();
      callLive.analyze();
      Set<String> callLiveVars = callLive.getOutFlowSets().get(call).getSet();
      Map<String, Set<Def>> reaching = mayReach.getInFlowSets().get(call).toMap();
      System.out.println("\ncallReaching:" + reaching + "\ncLive:" + callLiveVars);
      if (inlined) {
        System.out.println();
      }

      for (Map.Entry<String, Set<Def>> entry : reaching.entrySet()) {
        if (entry.getValue() != null) {
          Set<Def> reached = entry.getValue();
          if ((reached.size() > 1 || (!reached.contains(ReachingDefs.UNDEF)))
              && scriptLiveVars.contains(entry.getKey())) inputArgsCurrent.add(entry.getKey());
        }
        if (callLiveVars.contains(entry.getKey()) && assignedVars.contains(entry.getKey())) {
          outputArgsCurrent.add(entry.getKey());
        }
      }
      if (inputArgs == null) {
        inputArgs = inputArgsCurrent;
      } else if (!inputArgs.equals(inputArgsCurrent)) {
        inputArgs.removeAll(inputArgsCurrent);
        errors.add(new Exceptions.ScriptInputsNotMatching(new Name(inputArgs.toString())));
      }

      if (outputArgs == null) {
        outputArgs = outputArgsCurrent;
      } else if (!outputArgs.equals(outputArgsCurrent)) {
        outputArgs.addAll(outputArgsCurrent);
        errors.add(new Exceptions.ScriptOutputsNotMatching(new Name(outputArgs.toString())));
      }
    }
    System.out.println("" + inputArgs + " " + outputArgs);
    if (inputArgs != null)
      for (String inputArg : inputArgs) {
        f.addInputParam(new Name(inputArg));
      }

    if (outputArgs != null)
      for (String outputArg : outputArgs) {
        f.addOutputParam(new Name(outputArg));
      }

    if (inputArgs == null) {
      errors.add(new Exceptions.NoCallsToScript(new Name(script.getName())));
    }
    VFFlowInsensitiveAnalysis funcKind = new VFFlowInsensitiveAnalysis(f);
    if (inlined) {
      System.out.println(f.getPrettyPrinted());
      //            System.exit(0);
    }
    funcKind.analyze();
    VFFlowset funcRes = funcKind.getFlowSets().get(f);
    for (Map.Entry<String, VFDatum> entry : scriptKind.getFlowSets().get(script)) {
      if (entry.getValue() != null
          && entry.getValue().isID()
          && funcRes.getKind(entry.getKey()).isID())
        errors.add(new IDConflictException(new Name(entry.getKey())));
      if (entry.getValue() != null
          && entry.getValue().isID()
          && funcRes.getKind(entry.getKey()).isFunction())
        errors.add(new Exceptions.WarnIDToFunException(new Name(entry.getKey())));
      if (funcRes.getKind(entry.getKey()) == VFDatum.TOP)
        errors.add(new Exceptions.KindConflict(new Name(entry.getKey())));
    }
    return errors;
  }
Example #2
0
 public void caseScript(Script node) {
   currentScope = "script";
   instrumentStmtList(node.getStmts());
 }