import type Transformer from "./transformer";
import traverse from "babel-traverse";
import type File from "./file";

/**
 * This class is responsible for traversing over the provided `File`s
 * AST and running it's parent transformers handlers over it.
 */

export default class PluginPass {
  constructor(file: File, plugin: Transformer) {
    this.plugin = plugin;
    this.file   = file;
    this.key    = plugin.key;

    if (this.canTransform() && plugin.metadata.experimental && !file.opts.experimental) {
      file.log.warn(`THE TRANSFORMER ${this.key} HAS BEEN MARKED AS EXPERIMENTAL AND IS WIP. USE AT YOUR OWN RISK. ` +
                    "THIS WILL HIGHLY LIKELY BREAK YOUR CODE SO USE WITH **EXTREME** CAUTION. ENABLE THE " +
                    "`experimental` OPTION TO IGNORE THIS WARNING.");
    }
  }

  canTransform(): boolean {
    if (this.plugin.metadata.mode !== this.file.opts.mode) {
      return false;
    } else {
      return this.canRun();
    }
  }

  canRun() {
    return this.file.transformerDependencies[this.key] ||
           this.file.pipeline.canRun(this.plugin, this.file.opts);
  }

  transform() {
    var file = this.file;
    file.log.debug(`Start transformer ${this.key}`);
    traverse(file.ast, this.plugin.visitor, file.scope, file);
    file.log.debug(`Finish transformer ${this.key}`);
  }
}

@@ -85,21 +85,16 @@
 %0Aimport 
-type 
 File fro
@@ -110,1009 +110,188 @@
 %22;%0A%0A
-/**%0A * This class is responsible for traversing over the provided %60File%60s%0A * AST and running it's parent transformers handlers over it.%0A */%0A%0Aexport default class PluginPass %7B%0A  constructor(file: File, plugin: Transformer) %7B%0A    this.plugin = plugin;%0A    this.file   = file;%0A    this.key    = plugin.key;%0A%0A    if (this.canTransform() && plugin.metadata.experimental && !file.opts.experimental) %7B%0A      file.log.warn(%60THE TRANSFORMER $%7Bthis.key%7D HAS BEEN MARKED AS EXPERIMENTAL AND IS WIP. USE AT YOUR OWN RISK. %60 +%0A                    %22THIS WILL HIGHLY LIKELY BREAK YOUR CODE SO USE WITH **EXTREME** CAUTION. ENABLE THE %22 +%0A                    %22%60experimental%60 OPTION TO IGNORE THIS WARNING.%22);%0A    %7D%0A  %7D%0A%0A  canTransform(): boolean %7B%0A    if (this.plugin.metadata.mode !== this.file.opts.mode) %7B%0A      return fals
+export default class PluginPass %7B%0A  constructor(file: File, plugin: Transformer, options: Object = %7B%7D) %7B%0A    this.plugin = plugin;%0A    this.file   = fil
 e;%0A   
- 
-%7D else %7B%0A      return this.canRun();%0A    %7D%0A  %7D%0A%0A  canRun() %7B%0A    return this.file.transformerDependencies%5Bthis.key%5D %7C%7C%0A           this.file.pipeline.canRun(this.plugin, this.file.opts)
+ this.opts   = options
 ;%0A  
@@ -508,11 +508,80 @@
 %7D%60);%0A  %7D
+%0A%0A  addHelper(...args) %7B%0A    return this.file.addHelper(...args);%0A  %7D
 %0A%7D%0A

make PluginPass the state each plugin visitor gets