@Override
  public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
    context.getProgressIndicator().setText(myValidator.getProgressIndicatorText());

    final List<ProcessingItem> processedItems = new ArrayList<ProcessingItem>();
    final List<LocalInspectionTool> inspections = new ArrayList<LocalInspectionTool>();
    for (final Class aClass : myValidator.getInspectionToolClasses(context)) {
      try {
        inspections.add((LocalInspectionTool) aClass.newInstance());
      } catch (RuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw new Error(e);
      }
    }
    for (int i = 0; i < items.length; i++) {
      final MyValidatorProcessingItem item = (MyValidatorProcessingItem) items[i];
      context.getProgressIndicator().checkCanceled();
      context.getProgressIndicator().setFraction((double) i / items.length);

      try {
        ourCompilationThreads.set(Boolean.TRUE);

        if (checkFile(inspections, item, context)) {
          processedItems.add(item);
        }
      } finally {
        ourCompilationThreads.set(Boolean.FALSE);
      }
    }

    return processedItems.toArray(new ProcessingItem[processedItems.size()]);
  }
  private boolean checkUnderReadAction(
      final MyValidatorProcessingItem item,
      final CompileContext context,
      final Computable<Map<ProblemDescriptor, HighlightDisplayLevel>> runnable) {
    return DumbService.getInstance(context.getProject())
        .runReadActionInSmartMode(
            new Computable<Boolean>() {
              @Override
              public Boolean compute() {
                final PsiFile file = item.getPsiFile();
                if (file == null) return false;

                final Document document = myPsiDocumentManager.getCachedDocument(file);
                if (document != null && myPsiDocumentManager.isUncommited(document)) {
                  final String url = file.getViewProvider().getVirtualFile().getUrl();
                  context.addMessage(
                      CompilerMessageCategory.WARNING,
                      CompilerBundle.message("warning.text.file.has.been.changed"),
                      url,
                      -1,
                      -1);
                  return false;
                }

                if (reportProblems(context, runnable.compute())) return false;
                return true;
              }
            });
  }
 @Override
 public boolean isCompilableFile(VirtualFile file, CompileContext context) {
   if (!(file.getFileType() instanceof JetFileType)) {
     return false;
   }
   Module module = context.getModuleByFile(file);
   if (module == null) {
     return false;
   }
   return ProjectStructureUtil.isJsKotlinModule(module);
 }
 private static void addMessages(
     @NotNull final CompileContext context,
     @NotNull final Map<CompilerMessageCategory, List<String>> messages,
     @NotNull final String url) {
   for (final CompilerMessageCategory category : messages.keySet()) {
     final List<String> messageList = messages.get(category);
     for (final String message : messageList) {
       context.addMessage(category, message, url, -1, -1);
     }
   }
 }
 public final CompileContext compile() throws RecognitionException {
   CompileContext _localctx = new CompileContext(_ctx, getState());
   enterRule(_localctx, 0, RULE_compile);
   try {
     enterOuterAlt(_localctx, 1);
     {
       setState(4);
       expression(0);
       setState(5);
       match(EOF);
     }
   } catch (RecognitionException re) {
     _localctx.exception = re;
     _errHandler.reportError(this, re);
     _errHandler.recover(this, re);
   } finally {
     exitRule();
   }
   return _localctx;
 }
  @Override
  @NotNull
  public ProcessingItem[] getProcessingItems(final CompileContext context) {
    final Project project = context.getProject();
    if (project.isDefault() || !ValidationConfiguration.shouldValidate(this, context)) {
      return ProcessingItem.EMPTY_ARRAY;
    }
    final ExcludesConfiguration excludesConfiguration =
        ValidationConfiguration.getExcludedEntriesConfiguration(project);
    final List<ProcessingItem> items =
        DumbService.getInstance(project)
            .runReadActionInSmartMode(
                new Computable<List<ProcessingItem>>() {
                  @Override
                  public List<ProcessingItem> compute() {
                    final CompileScope compileScope = context.getCompileScope();
                    if (!myValidator.isAvailableOnScope(compileScope)) return null;

                    final ArrayList<ProcessingItem> items = new ArrayList<ProcessingItem>();

                    final Processor<VirtualFile> processor =
                        new Processor<VirtualFile>() {
                          @Override
                          public boolean process(VirtualFile file) {
                            if (!file.isValid()) {
                              return true;
                            }

                            if (myCompilerManager.isExcludedFromCompilation(file)
                                || excludesConfiguration.isExcluded(file)) {
                              return true;
                            }

                            final Module module = context.getModuleByFile(file);
                            if (module != null) {
                              final PsiFile psiFile = myPsiManager.findFile(file);
                              if (psiFile != null) {
                                items.add(new MyValidatorProcessingItem(psiFile));
                              }
                            }
                            return true;
                          }
                        };
                    ContainerUtil.process(
                        myValidator.getFilesToProcess(myPsiManager.getProject(), context),
                        processor);
                    return items;
                  }
                });
    if (items == null) return ProcessingItem.EMPTY_ARRAY;

    return items.toArray(new ProcessingItem[items.size()]);
  }
 @Nullable
 private static Module getModule(
     @NotNull CompileContext context, @NotNull Chunk<Module> moduleChunk) {
   if (moduleChunk.getNodes().size() != 1) {
     context.addMessage(
         CompilerMessageCategory.ERROR,
         "K2JSCompiler does not support multiple modules.",
         null,
         -1,
         -1);
     return null;
   }
   return moduleChunk.getNodes().iterator().next();
 }
Exemple #8
0
  @Override
  protected Expr opt(final CompileContext cc) throws QueryException {
    if (allAreValues() && exprs[0].size() < UNROLL_LIMIT) {
      // unroll the loop
      cc.info(QueryText.OPTUNROLL_X, this);
      final Value seq = (Value) exprs[0];
      final int len = (int) seq.size();

      // fn:for-each(...)
      final Expr[] results = new Expr[len];
      for (int i = 0; i < len; i++) {
        results[i] = new DynFuncCall(info, sc, exprs[1], seq.itemAt(i)).optimize(cc);
      }
      return new List(info, results).optimize(cc);
    }
    return this;
  }
  @Override
  public GenerationItem[] generate(
      final CompileContext context,
      final GenerationItem[] items,
      final VirtualFile outputRootDirectory) {
    if (items == null || items.length <= 0) {
      return EMPTY_GENERATION_ITEM_ARRAY;
    }

    context.getProgressIndicator().setText("Compiling RenderScript files...");
    final GenerationItem[] generationItems = doGenerate(context, items, outputRootDirectory);
    final Set<VirtualFile> generatedVFiles = new HashSet<VirtualFile>();
    final HashSet<VirtualFile> visited = new HashSet<VirtualFile>();

    outputRootDirectory.refresh(false, true);
    AndroidUtils.collectFiles(outputRootDirectory, visited, generatedVFiles);

    if (context instanceof CompileContextEx) {
      ((CompileContextEx) context).markGenerated(generatedVFiles);
    }
    return generationItems;
  }
 @Override
 public void finished(
     boolean aborted, int errors, int warnings, final CompileContext compileContext) {
   try {
     for (CompilerMessageCategory category : CompilerMessageCategory.values()) {
       for (CompilerMessage message : compileContext.getMessages(category)) {
         final String msg = message.getMessage();
         if (category != CompilerMessageCategory.INFORMATION
             || !msg.startsWith("Compilation completed successfully")) {
           myMessages.add(category + ": " + msg);
         }
       }
     }
     if (errors > 0) {
       fail("Compiler errors occurred! " + StringUtil.join(myMessages, "\n"));
     }
     assertFalse("Code did not compile!", aborted);
   } catch (Throwable t) {
     myError = t;
   } finally {
     mySemaphore.up();
   }
 }
  private boolean reportProblems(
      CompileContext context, Map<ProblemDescriptor, HighlightDisplayLevel> problemsMap) {
    if (problemsMap.isEmpty()) {
      return false;
    }

    boolean errorsReported = false;
    for (Map.Entry<ProblemDescriptor, HighlightDisplayLevel> entry : problemsMap.entrySet()) {
      ProblemDescriptor problemDescriptor = entry.getKey();
      final PsiElement element = problemDescriptor.getPsiElement();
      final PsiFile psiFile = element.getContainingFile();
      if (psiFile == null) continue;

      final VirtualFile virtualFile = psiFile.getVirtualFile();
      if (virtualFile == null) continue;

      final CompilerMessageCategory category =
          myValidator.getCategoryByHighlightDisplayLevel(entry.getValue(), virtualFile, context);
      final Document document = myPsiDocumentManager.getDocument(psiFile);

      final int offset = problemDescriptor.getStartElement().getTextOffset();
      assert document != null;
      final int line = document.getLineNumber(offset);
      final int column = offset - document.getLineStartOffset(line);
      context.addMessage(
          category,
          problemDescriptor.getDescriptionTemplate(),
          virtualFile.getUrl(),
          line + 1,
          column + 1);
      if (CompilerMessageCategory.ERROR == category) {
        errorsReported = true;
      }
    }
    return errorsReported;
  }
 public static boolean isModuleAffected(CompileContext context, Module module) {
   return ArrayUtil.find(context.getCompileScope().getAffectedModules(), module) >= 0;
 }
  /**
   * A private helper routine to make the compiler code more sane.
   *
   * <p>This processes a single definition in a dependency tree. It works as a single step in a
   * breadth first traversal of the tree, accumulating children in the 'deps' set, and updating the
   * compile context with the current definition.
   *
   * <p>Note that once the definition has been retrieved, this code uses the 'canonical' descriptor
   * from the definition, discarding the incoming descriptor.
   *
   * @param descriptor the descriptor that we are currently handling, must not be in the compiling
   *     defs.
   * @param cc the compile context to allow us to accumulate information.
   * @param deps the set of dependencies that we are accumulating.
   * @throws QuickFixException if the definition is not found, or validateDefinition() throws one.
   */
  private <D extends Definition> D getHelper(
      DefDescriptor<D> descriptor, CompileContext cc, Set<DefDescriptor<?>> deps)
      throws QuickFixException {
    CompilingDef<D> cd = cc.getCompiling(descriptor);

    if (cd.def != null) {
      return cd.def;
    }
    try {
      if (!fillCompilingDef(cd, cc.context)) {
        //
        // At this point, we have failed to get the def, so we should throw an
        // error. The first stanza is to provide a more useful error description
        // including the set of components using the missing component.
        //
        if (!cd.parents.isEmpty()) {
          StringBuilder sb = new StringBuilder();
          Location handy = null;
          for (Definition parent : cd.parents) {
            handy = parent.getLocation();
            if (sb.length() != 0) {
              sb.append(", ");
            }
            sb.append(parent.getDescriptor().toString());
          }
          throw new DefinitionNotFoundException(descriptor, handy, sb.toString());
        }
        throw new DefinitionNotFoundException(descriptor);
      }
      //
      // Ok. We have a def. let's figure out what to do with it.
      //
      Set<DefDescriptor<?>> newDeps = Sets.newHashSet();
      cd.def.appendDependencies(newDeps);
      //
      // FIXME: this code will go away with preloads.
      // This pulls in the context preloads. not pretty, but it works.
      //
      if (!cc.addedPreloads && cd.descriptor.getDefType().equals(DefType.APPLICATION)) {
        cc.addedPreloads = true;
        Set<String> preloads = cc.context.getPreloads();
        for (String preload : preloads) {
          if (!preload.contains("_")) {
            DependencyDefImpl.Builder ddb = new DependencyDefImpl.Builder();
            ddb.setResource(preload);
            ddb.setType("APPLICATION,COMPONENT,STYLE,EVENT");
            ddb.build().appendDependencies(newDeps);
          }
        }
      }
      for (DefDescriptor<?> dep : newDeps) {
        if (!defs.containsKey(dep)) {
          CompilingDef<?> depcd = cc.getCompiling(dep);
          depcd.parents.add(cd.def);
        }
      }
      deps.addAll(newDeps);
      cc.dependencies.put(cd.descriptor, cd.def);
      return cd.def;
    } catch (DefinitionNotFoundException dnfe) {
      //
      // In the case that we have a DefinitionNotFoundException for our current descriptor,
      // cache the fact that we didn't find one.
      //
      if (dnfe.getDescriptor().equals(descriptor)) {
        cd.def = null;
        defs.put(descriptor, cd.def);
        if (cd.cacheable) {
          defsCache.put(descriptor, Optional.fromNullable(cd.def));
        }
      }
      throw dnfe;
    }
  }
  @Nullable
  public static String findResourcesCacheDirectory(
      @NotNull Module module, boolean createIfNotFound, @Nullable CompileContext context) {
    final Project project = module.getProject();

    final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(project);
    if (extension == null) {
      if (context != null) {
        context.addMessage(
            CompilerMessageCategory.ERROR,
            "Cannot get compiler settings for project " + project.getName(),
            null,
            -1,
            -1);
      }
      return null;
    }

    final String projectOutputDirUrl = extension.getCompilerOutputUrl();
    if (projectOutputDirUrl == null) {
      if (context != null) {
        context.addMessage(
            CompilerMessageCategory.ERROR,
            "Cannot find output directory for project " + project.getName(),
            null,
            -1,
            -1);
      }
      return null;
    }

    final String pngCacheDirPath =
        VfsUtil.urlToPath(projectOutputDirUrl)
            + '/'
            + RESOURCES_CACHE_DIR_NAME
            + '/'
            + module.getName();
    final String pngCacheDirOsPath = FileUtil.toSystemDependentName(pngCacheDirPath);

    final File pngCacheDir = new File(pngCacheDirOsPath);
    if (pngCacheDir.exists()) {
      if (pngCacheDir.isDirectory()) {
        return pngCacheDirOsPath;
      } else {
        if (context != null) {
          context.addMessage(
              CompilerMessageCategory.ERROR,
              "Cannot create directory " + pngCacheDirOsPath + " because file already exists",
              null,
              -1,
              -1);
        }
        return null;
      }
    }

    if (!createIfNotFound) {
      return null;
    }

    if (!pngCacheDir.mkdirs()) {
      if (context != null) {
        context.addMessage(
            CompilerMessageCategory.ERROR,
            "Cannot create directory " + pngCacheDirOsPath,
            null,
            -1,
            -1);
      }
      return null;
    }

    return pngCacheDirOsPath;
  }
 public static boolean isReleaseBuild(@NotNull CompileContext context) {
   final Boolean value = context.getCompileScope().getUserData(RELEASE_BUILD_KEY);
   return value != null && value.booleanValue();
 }
  private static GenerationItem[] doGenerate(
      @NotNull final CompileContext context,
      @NotNull final GenerationItem[] items,
      VirtualFile outputRootDirectory) {
    if (context.getProject().isDisposed()) {
      return EMPTY_GENERATION_ITEM_ARRAY;
    }

    // we have one item per module there, so clear output directory
    final String genRootPath = FileUtil.toSystemDependentName(outputRootDirectory.getPath());
    final File genRootDir = new File(genRootPath);
    if (genRootDir.exists()) {
      if (!FileUtil.delete(genRootDir)) {
        context.addMessage(
            CompilerMessageCategory.ERROR, "Cannot delete directory " + genRootPath, null, -1, -1);
        return EMPTY_GENERATION_ITEM_ARRAY;
      }
      if (!genRootDir.mkdir()) {
        context.addMessage(
            CompilerMessageCategory.ERROR, "Cannot create directory " + genRootPath, null, -1, -1);
        return EMPTY_GENERATION_ITEM_ARRAY;
      }
    }

    final List<GenerationItem> results = new ArrayList<GenerationItem>(items.length);
    for (final GenerationItem item : items) {
      if (item instanceof MyGenerationItem) {
        final MyGenerationItem genItem = (MyGenerationItem) item;

        if (!AndroidCompileUtil.isModuleAffected(context, genItem.myModule)) {
          continue;
        }

        boolean success = true;

        for (final VirtualFile sourceFile : genItem.myFiles) {
          final String depFolderOsPath =
              getDependencyFolder(context.getProject(), sourceFile, outputRootDirectory);

          try {
            final Map<CompilerMessageCategory, List<String>> messages =
                AndroidCompileUtil.toCompilerMessageCategoryKeys(
                    AndroidRenderscript.execute(
                        genItem.mySdkLocation,
                        genItem.myAndroidTarget,
                        sourceFile.getPath(),
                        genRootPath,
                        depFolderOsPath,
                        genItem.myRawDirPath));

            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      public void run() {
                        if (context.getProject().isDisposed()) {
                          return;
                        }
                        addMessages(context, messages, sourceFile.getUrl());
                      }
                    });

            if (messages.get(CompilerMessageCategory.ERROR).size() > 0) {
              success = false;
            }
          } catch (final IOException e) {
            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      public void run() {
                        if (context.getProject().isDisposed()) return;
                        context.addMessage(
                            CompilerMessageCategory.ERROR,
                            e.getMessage(),
                            sourceFile.getUrl(),
                            -1,
                            -1);
                      }
                    });
            success = false;
          }
        }

        if (success) {
          results.add(genItem);
        }
      }
    }
    outputRootDirectory.refresh(false, true);
    return results.toArray(new GenerationItem[results.size()]);
  }
  public static void generate(GeneratingCompiler compiler, final CompileContext context) {
    if (context == null) {
      return;
    }

    final Set<Module> affectedModules = new HashSet<Module>();
    Collections.addAll(affectedModules, context.getCompileScope().getAffectedModules());

    ApplicationManager.getApplication()
        .invokeAndWait(
            new Runnable() {
              @Override
              public void run() {
                for (Module module : affectedModules) {
                  if (module.isDisposed() || module.getProject().isDisposed()) {
                    continue;
                  }

                  final AndroidFacet facet = AndroidFacet.getInstance(module);
                  if (facet != null) {
                    AndroidCompileUtil.createGenModulesAndSourceRoots(facet);
                  }
                }
              }
            },
            ModalityState.defaultModalityState());

    List<GeneratingCompiler.GenerationItem> itemsToGenerate =
        new ArrayList<GeneratingCompiler.GenerationItem>();
    for (GeneratingCompiler.GenerationItem item : compiler.getGenerationItems(context)) {
      if (affectedModules.contains(item.getModule())) {
        itemsToGenerate.add(item);
      }
    }

    GeneratingCompiler.GenerationItem[] items =
        itemsToGenerate.toArray(new GeneratingCompiler.GenerationItem[itemsToGenerate.size()]);

    final boolean[] run = {true};
    final VirtualFile[] files = getFilesToCheckReadonlyStatus(items);
    if (files.length > 0) {
      ApplicationManager.getApplication()
          .invokeAndWait(
              new Runnable() {
                @Override
                public void run() {
                  ApplicationManager.getApplication()
                      .runReadAction(
                          new Runnable() {
                            @Override
                            public void run() {
                              final Project project = context.getProject();
                              run[0] =
                                  !project.isDisposed()
                                      && ReadonlyStatusHandler.ensureFilesWritable(project, files);
                            }
                          });
                }
              },
              ModalityState.defaultModalityState());
    }

    if (run[0]) {
      compiler.generate(context, items, null);
    }
  }
Exemple #18
0
  private static byte[] compileBytes(
      Rule rule,
      Class helperClass,
      String helperName,
      String compiledHelperName,
      boolean compileToBytecode)
      throws Exception {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;
    MethodVisitor mv;
    AnnotationVisitor av0;
    // create the class as a subclass of the rule helper class, appending Compiled to the front
    // of the class name and a unique number to the end of the class helperName
    // also ensure it implements the HelperAdapter interface
    //
    // public class foo.bar.Compiled_<helper>_<NNN> extends foo.bar.<helper> implements
    // HelperAdapter

    cw.visit(
        V1_5,
        ACC_PUBLIC + ACC_SUPER,
        compiledHelperName,
        null,
        helperName,
        new String[] {"org/jboss/byteman/rule/helper/HelperAdapter"});
    // we need to install the source file name
    {
      String fullFileName = rule.getFile();
      int idx = fullFileName.lastIndexOf(java.io.File.separatorChar);
      String basicFileName = (idx < 0 ? fullFileName : fullFileName.substring(idx + 1));
      String debug = "// compiled from: " + fullFileName + "\n// generated by Byteman\n";
      cw.visitSource(basicFileName, debug);
    }
    {
      // we need a Hashmap field to hold the bindings
      //
      // private HashMap<String, Object> bindingMap;

      fv =
          cw.visitField(
              ACC_PRIVATE,
              "bindingMap",
              "Ljava/util/HashMap;",
              "Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Object;>;",
              null);
      fv.visitEnd();
    }
    {
      // and a rule field to hold the rule
      //
      // private Rule rule;

      fv =
          cw.visitField(
              ACC_PRIVATE,
              "rule",
              "Lorg/jboss/byteman/rule/Rule;",
              "Lorg/jboss/byteman/rule/Rule;",
              null);
      fv.visitEnd();
    }
    {
      // we need a constructor which takes a Rule as argument
      // if the helper implements a constructor which takes a Rule as argument then we invoke it
      // otherwise we invoke the empty helper constructor

      Constructor superConstructor = null;
      try {
        superConstructor = helperClass.getDeclaredConstructor(Rule.class);
      } catch (NoSuchMethodException e) {
        // hmm, ok see if there is an empty constructor
      } catch (SecurityException e) {
        throw new CompileException(
            "Compiler.compileBytes : unable to access constructor for helper class "
                + helperClass.getCanonicalName());
      }
      boolean superWantsRule = (superConstructor != null);
      if (!superWantsRule) {
        try {
          superConstructor = helperClass.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
          throw new CompileException(
              "Compiler.compileBytes : no valid constructor found for helper class "
                  + helperClass.getCanonicalName());
        } catch (SecurityException e) {
          throw new CompileException(
              "Compiler.compileBytes : unable to access constructor for helper class "
                  + helperClass.getCanonicalName());
        }
      }
      //
      //  public Compiled<helper>_<NNN>()Rule rule)
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V", null, null);
      mv.visitCode();
      // super();
      //
      // or
      //
      // super(Rule);
      if (superWantsRule) {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V");
      } else {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "()V");
      }
      // bindingMap = new HashMap<String, Object);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitTypeInsn(NEW, "java/util/HashMap");
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V");
      mv.visitFieldInsn(PUTFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
      // this.rule = rule
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(PUTFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      // return;
      mv.visitInsn(RETURN);
      mv.visitMaxs(3, 2);
      mv.visitEnd();
    }
    {
      // create the execute method
      //
      // public void execute(Bindings bindings, Object recipient, Object[] args) throws
      // ExecuteException
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "execute",
              "(Ljava/lang/Object;[Ljava/lang/Object;)V",
              null,
              new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
      mv.visitCode();
      // if (Transformer.isVerbose())
      mv.visitMethodInsn(INVOKESTATIC, "org/jboss/byteman/agent/Transformer", "isVerbose", "()Z");
      Label l0 = new Label();
      mv.visitJumpInsn(IFEQ, l0);
      // then
      // System.out.println(rule.getName() + " execute");
      mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
      mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
      mv.visitLdcInsn(" execute()");
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/lang/StringBuilder",
          "append",
          "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
      mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
      // end if
      mv.visitLabel(l0);

      Bindings bindings = rule.getBindings();
      Iterator<Binding> iterator = bindings.iterator();

      while (iterator.hasNext()) {
        Binding binding = iterator.next();
        String name = binding.getName();
        if (binding.isAlias()) {
          // lookups and updates will use the aliased name
          continue;
        }
        if (binding.isHelper()) {
          // bindingMap.put(name, this);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
          mv.visitLdcInsn(name);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/util/HashMap",
              "put",
              "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
          mv.visitInsn(POP);
        } else if (binding.isRecipient()) {
          // bindingMap.put(name, recipient);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
          mv.visitLdcInsn(name);
          mv.visitVarInsn(ALOAD, 1);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/util/HashMap",
              "put",
              "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
          mv.visitInsn(POP);
          // } else if (binding.isParam() || binding.isLocalVar() || binding.isReturn() ||
          //             binding.isThrowable() || binding.isParamCount() || binding.isParamArray())
          // {
        } else if (!binding.isBindVar()) {
          // bindingMap.put(name, args[binding.getCallArrayIndex()]);
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
          mv.visitLdcInsn(name);
          mv.visitVarInsn(ALOAD, 2);
          mv.visitLdcInsn(binding.getCallArrayIndex());
          mv.visitInsn(AALOAD);
          mv.visitMethodInsn(
              INVOKEVIRTUAL,
              "java/util/HashMap",
              "put",
              "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
          mv.visitInsn(POP);
        }
      }

      // execute0()
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKEVIRTUAL, compiledHelperName, "execute0", "()V");

      // now restore update bindings

      iterator = bindings.iterator();

      while (iterator.hasNext()) {
        Binding binding = iterator.next();
        if (binding.isAlias()) {
          continue;
        }
        String name = binding.getName();

        if (binding.isUpdated()) {
          // if (binding.isParam() || binding.isLocalVar() || binding.isReturn()) {
          if (!binding.isBindVar()) {
            int idx = binding.getCallArrayIndex();
            // Object value = bindingMap.get(name);
            // args[idx] = value;
            mv.visitVarInsn(ALOAD, 2); // args
            mv.visitLdcInsn(idx);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
            mv.visitLdcInsn(name);
            mv.visitMethodInsn(
                INVOKEVIRTUAL,
                "java/util/HashMap",
                "get",
                "(Ljava/lang/Object;)Ljava/lang/Object;");
            mv.visitInsn(AASTORE);
          }
        }
      }

      // return
      mv.visitInsn(RETURN);
      mv.visitMaxs(4, 3);
      mv.visitEnd();
    }
    {
      // create the setBinding method
      //
      // public void setBinding(String name, Object value)
      mv =
          cw.visitMethod(
              ACC_PUBLIC, "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
      mv.visitCode();
      //  bindingMap.put(name, value);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "java/util/HashMap",
          "put",
          "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
      mv.visitInsn(POP);
      // return
      mv.visitInsn(RETURN);
      mv.visitMaxs(3, 3);
      mv.visitEnd();
    }
    {
      // create the getBinding method
      //
      // public Object getBinding(String name)
      mv =
          cw.visitMethod(
              ACC_PUBLIC, "getBinding", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
      mv.visitCode();
      // {TOS} <== bindingMap.get(name);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(2, 2);
      mv.visitEnd();
    }
    {
      // create the getName method
      //
      // public String getName()
      mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null);
      mv.visitCode();
      // {TOS} <== rule.getName()
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(1, 1);
      mv.visitEnd();
    }
    // create the getAccessibleField method
    //
    // public Object getAccessibleField(Object owner, int fieldIndex)
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "getAccessibleField",
              "(Ljava/lang/Object;I)Ljava/lang/Object;",
              null,
              null);
      mv.visitCode();
      // {TOS} <== rule.getAccessibleField(owner, fieldIndex);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ILOAD, 2);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "org/jboss/byteman/rule/Rule",
          "getAccessibleField",
          "(Ljava/lang/Object;I)Ljava/lang/Object;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(3, 3);
      mv.visitEnd();
    }

    // create the setAccessibleField method
    //
    // public void setAccessibleField(Object owner, Object value, int fieldIndex)
    // rule.setAccessibleField(owner, value, fieldIndex);
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "setAccessibleField",
              "(Ljava/lang/Object;Ljava/lang/Object;I)V",
              null,
              null);
      mv.visitCode();
      // rule.setAccessibleField(owner, value, fieldIndex);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitVarInsn(ILOAD, 3);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "org/jboss/byteman/rule/Rule",
          "setAccessibleField",
          "(Ljava/lang/Object;Ljava/lang/Object;I)V");
      // return
      mv.visitInsn(RETURN);
      mv.visitMaxs(4, 4);
      mv.visitEnd();
    }

    // create the invokeAccessibleMethod method
    //
    // public Object invokeAccessibleMethod(Object target, Object[] args, int methodIndex)
    // {TOS} <==  rule.invokeAccessibleMethod(target, args, methodIndex);
    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "invokeAccessibleMethod",
              "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;",
              null,
              null);
      mv.visitCode();
      // rule.invokeAccessibleMethod(target, args, fieldIndex);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitVarInsn(ILOAD, 3);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          "org/jboss/byteman/rule/Rule",
          "invokeAccessibleMethod",
          "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;");
      // return {TOS}
      mv.visitInsn(ARETURN);
      mv.visitMaxs(4, 4);
      mv.visitEnd();
    }
    if (compileToBytecode) {
      // we generate a single execute0 method if we want to run compiled and get
      // the event, condiiton and action to insert the relevant bytecode to implement
      // bind(), test() and fire()

      {
        // create the execute0() method
        //
        // private void execute0()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "execute0",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        CompileContext compileContext = new CompileContext(mv);
        // make sure we set the first line number before generating any code
        compileContext.notifySourceLine(rule.getLine());
        compileContext.addLocalCount(3); // for this and 2 object args
        // bind();
        rule.getEvent().compile(mv, compileContext);
        // if (test())
        rule.getCondition().compile(mv, compileContext);
        Label l0 = new Label();
        mv.visitJumpInsn(IFEQ, l0);
        compileContext.addStackCount(-1);
        // then
        rule.getAction().compile(mv, compileContext);
        // fire();
        // end if
        mv.visitLabel(l0);
        // this will match the ENDRULE line
        compileContext.notifySourceEnd();
        // return
        mv.visitInsn(RETURN);
        // need to specify correct Maxs values
        mv.visitMaxs(compileContext.getStackMax(), compileContext.getLocalMax());
        mv.visitEnd();
      }
    } else {
      // we generate the following methods if we want to run interpreted
      {
        // create the execute0() method
        //
        // private void execute0()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "execute0",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // bind();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "bind", "()V");
        // if (test())
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "test", "()Z");
        Label l0 = new Label();
        mv.visitJumpInsn(IFEQ, l0);
        // then
        // fire();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "fire", "()V");
        // end if
        mv.visitLabel(l0);
        // return
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
      }
      {
        // create the bind method
        //
        // private void bind()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "bind",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // rule.getEvent().interpret(this);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Rule",
            "getEvent",
            "()Lorg/jboss/byteman/rule/Event;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Event",
            "interpret",
            "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;");
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
      {
        // create the test method
        //
        // private boolean test()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "test",
                "()Z",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // {TOS} <== rule.getCondition().interpret(this);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Rule",
            "getCondition",
            "()Lorg/jboss/byteman/rule/Condition;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Condition",
            "interpret",
            "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;");
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");
        // unbox the returned Boolean
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
        // return {TOS}
        mv.visitInsn(IRETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
      {
        // create the fire method
        //
        // private void fire()
        mv =
            cw.visitMethod(
                ACC_PRIVATE,
                "fire",
                "()V",
                null,
                new String[] {"org/jboss/byteman/rule/exception/ExecuteException"});
        mv.visitCode();
        // rule.getAction().interpret(this);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;");
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Rule",
            "getAction",
            "()Lorg/jboss/byteman/rule/Action;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            "org/jboss/byteman/rule/Action",
            "interpret",
            "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;");
        // return
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
    }

    cw.visitEnd();

    return cw.toByteArray();
  }